<script>
		(function (f) { if (typeof exports === "object" && typeof module !== "undefined") { module.exports = f() } else if (typeof define === "function" && define.amd) { define([], f) } else { var g; if (typeof window !== "undefined") { g = window } else if (typeof global !== "undefined") { g = global } else if (typeof self !== "undefined") { g = self } else { g = this } g.protocolCheck = f() } })(function () {
			var define, module, exports; return (function e(t, n, r) { function s(o, u) { if (!n[o]) { if (!t[o]) { var a = typeof require == "function" && require; if (!u && a) return a(o, !0); if (i) return i(o, !0); var f = new Error("Cannot find module '" + o + "'"); throw f.code = "MODULE_NOT_FOUND", f } var l = n[o] = { exports: {} }; t[o][0].call(l.exports, function (e) { var n = t[o][1][e]; return s(n ? n : e) }, l, l.exports, e, t, n, r) } return n[o].exports } var i = typeof require == "function" && require; for (var o = 0; o < r.length; o++)s(r[o]); return s })({
				1: [function (require, module, exports) {
					function _registerEvent(target, eventType, cb) {
						if (target.addEventListener) {
							target.addEventListener(eventType, cb);
							return {
								remove: function () {
									target.removeEventListener(eventType, cb);
								}
							};
						} else {
							target.attachEvent(eventType, cb);
							return {
								remove: function () {
									target.detachEvent(eventType, cb);
								}
							};
						}
					}

					function _createHiddenIframe(target, uri) {
						var iframe = document.createElement("iframe");
						iframe.src = uri;
						iframe.id = "hiddenIframe";
						iframe.style.display = "none";
						target.appendChild(iframe);

						return iframe;
					}

					function _createDetachedHiddenIframe() {
						var iframe = document.createElement("iframe");
						iframe.id = "hiddenDetachedIframe";
						iframe.style.display = "none";
						return iframe;
					}

					function openUriWithHiddenFrame(uri, failCb, successCb) {

						var timeout = setTimeout(function () {
							failCb();
							handler.remove();
						}, 1000);

						var iframe = document.querySelector("#hiddenIframe");
						if (!iframe) {
							iframe = _createHiddenIframe(document.body, "about:blank");
						}

						var handler = _registerEvent(window, "blur", onBlur);

						function onBlur() {
							clearTimeout(timeout);
							handler.remove();
							successCb();
						}

						iframe.contentWindow.location.href = uri;
					}

					function openUriWithTimeoutHack(uri, failCb, successCb) {

						var timeout = setTimeout(function () {
							failCb();
							handler.remove();
						}, 1000);

						//handle page running in an iframe (blur must be registered with top level window)
						var target = window;
						while (target != target.parent) {
							target = target.parent;
						}

						var handler = _registerEvent(target, "blur", onBlur);

						function onBlur() {
							clearTimeout(timeout);
							handler.remove();
							successCb();
						}

						window.location = uri;
					}

					function openUriUsingFirefox(uri, failCb, successCb) {						
						openUriWithTimeoutHack(uri, failCb, successCb);
						//openUriUsingIE10InWindows7(uri, failCb, successCb);
						//openUriUsingWickedInsaneHackery(uri, failCb, successCb);
						/*
						return;
						var iframe = document.querySelector("#hiddenIframe");

						if (!iframe) {
							iframe = _createHiddenIframe(document.body, "about:blank");
						}

						try {
							iframe.contentWindow.location.href = uri;
							successCb();
						} catch (e) {
							if (e.name == "NS_ERROR_UNKNOWN_PROTOCOL") {
								failCb();
							}
						}
						*/
					}
					

					function openUriUsingIEInOlderWindows(uri, failCb, successCb) {
						if (getInternetExplorerVersion() === 10) {
							openUriUsingIE10InWindows7(uri, failCb, successCb);
						} else if (getInternetExplorerVersion() === 9 || getInternetExplorerVersion() === 11) {
							openUriWithHiddenFrame(uri, failCb, successCb);
						} else {
							openUriInNewWindowHack(uri, failCb, successCb);
						}
					}

					function openUriUsingWickedInsaneHackery(uri, failCb, successCb) {
						var succeded = false;
 						var timeout;						

						var handler = function () {
								console.log('blurred -- success')
								window.removeEventListener("blur", handler);
								if (timeout) {
									clearTimeout(timeout);
								}
								succeded = true
								successCb();								
						};
						 
						var inner = function() {							
							if (timeout) {
								clearTimeout(timeout);
							}
							timeout = setTimeout(function() {
									window.removeEventListener("blur", handler);
									failCb();
							}, 5000);
							
							window.removeEventListener("blur", handler);
							window.addEventListener("blur", handler);
							
							var iframe = document.querySelector("#hiddenIframe");							
							
							if (!iframe) {
								iframe = _createHiddenIframe(document.body, "about:blank");								
							}							
							try {																
								iframe.contentWindow.location.href = uri;																
							} catch (e) {								
								window.removeEventListener("blur", handler);								
								failCb();
								clearTimeout(timeout);								
							}		
						}	
						var i = 0;
						var foo = function() {
							if (!succeded) {
								inner();
							}
							if (succeded) {
								clearInterval(poop);
								return;
							}
							i++;
							console.log(i);
						}
						var poop = setInterval(foo, 250);						 			
					}

					function openUriUsingIE10InWindows7(uri, failCb, successCb) {
						var timeout = setTimeout(function() {
							window.removeEventListener("blur", handler);
							failCb();
						}, 2000);
						
						var handler = function () {
							window.removeEventListener("blur", handler);
							clearTimeout(timeout);
							successCb();
						};
						window.addEventListener("blur", handler);

						var iframe = document.querySelector("#hiddenIframe");
						if (!iframe) {
							iframe = _createHiddenIframe(document.body, "about:blank");
						}
						try {
							iframe.contentWindow.location.href = uri;
						} catch (e) {
							window.removeEventListener("blur", handler);
							failCb();
							clearTimeout(timeout);
						}						 			
					}

					function openUriInNewWindowHack(uri, failCb, successCb) {
						var myWindow = window.open('', '', 'width=0,height=0');

						myWindow.document.write("<iframe src='" + uri + "'></iframe>");

						setTimeout(function () {
							try {
								myWindow.location.href;
								myWindow.setTimeout("window.close()", 1000);
								successCb();
							} catch (e) {
								myWindow.close();
								failCb();
							}
						}, 1000);
					}

					function openUriWithMsLaunchUri(uri, failCb, successCb) {
						navigator.msLaunchUri(uri,
							successCb,
							failCb
						);
					}

					function checkBrowser() {
						var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
						var ua = navigator.userAgent.toLowerCase();
						return {
							isOpera: isOpera,
							isFirefox: typeof InstallTrigger !== 'undefined',
							isSafari: (~ua.indexOf('safari') && !~ua.indexOf('chrome')) || Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0,
							isIOS: /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream,
							isChrome: !!window.chrome && !isOpera,
							isIE: /*@cc_on!@*/false || !!document.documentMode // At least IE6
						}
					}

					function getInternetExplorerVersion() {
						var rv = -1;
						if (navigator.appName === "Microsoft Internet Explorer") {
							var ua = navigator.userAgent;
							var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
							if (re.exec(ua) != null)
								rv = parseFloat(RegExp.$1);
						}
						else if (navigator.appName === "Netscape") {
							var ua = navigator.userAgent;
							var re = new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})");
							if (re.exec(ua) != null) {
								rv = parseFloat(RegExp.$1);
							}
						}
						return rv;
					}

					module.exports = function (uri, failCb, successCb, unsupportedCb) {
						function failCallback() {
							failCb && failCb();
						}

						function successCallback() {
							successCb && successCb();
						}

						function unsupportedCallback() {
							unsupportedCb && unsupportedCb();
						}

						if (navigator.msLaunchUri) { //for IE and Edge in Win 8 and Win 10
							openUriWithMsLaunchUri(uri, failCb, successCb);
						} else {
							var browser = checkBrowser();

							if (browser.isFirefox) {
								openUriUsingFirefox(uri, failCallback, successCallback);
							} else if (browser.isChrome || browser.isIOS) {
								openUriWithTimeoutHack(uri, failCallback, successCallback);
							} else if (browser.isIE) {
								openUriUsingIEInOlderWindows(uri, failCallback, successCallback);
							} else if (browser.isSafari) {
								openUriWithHiddenFrame(uri, failCallback, successCallback);
							} else {
								unsupportedCallback();
								// this works for most common browsers, so we try it if detection fails
								openUriWithTimeoutHack(uri, failCallback, successCallback);
							}
						}
					}

				}, {}]
			}, {}, [1])(1)
		});
</script>

<script> 
 
var ides = {{{toJSON ides}}};
window.CODESTREAM = window.CODESTREAM || {};
window.CODESTREAM._state = {	
	MRU: String('{{isMru}}') === 'true',
	lastOrigin: '{{{toJSON lastOrigin}}}',
	lastOriginDetail: String('{{isLastOriginDetail}}') === 'true',
	isSpecificIde: String('{{isSpecificIde}}') === 'true'
};
window.CODESTREAM.openEditor = function(ide) {
		if (!ide) {
			console.warn('missing ide');
			return;
		}
		var page = window.CODESTREAM.page;
		if (!page) {
			console.error('missing page');
			return;
		}
		var type = page.type;
		var options = page.data || {};    
		if (type === 'codemark' && !options.id) {
			console.error('missing codemark id');
			return;				
		}	
		else if (type === 'review' && !options.id)	{
			console.error('missing review id');
			return;			
		}
		 
		var protocolStart = ide.protocol;
		var { ideName, moniker, downloadUrl } = ide;
		var repoId; 
		var protocol;
		var route;
		if (type ==='errorsinbox' || type === 'span' || type === 'logs' || type === 'pixie') {
			const urlSearchParams = new URLSearchParams(window.location.search);
			const entries = Object.fromEntries(urlSearchParams.entries());			 
			let results = Object.keys(entries).map((key) => { return { key: key, value: entries[key] }; } );
			const payload = results.find(_ => _.key === "payload");
			if (payload) {
				try { 
					const parsed = JSON.parse(atob(decodeURIComponent(payload.value)));
					Object.keys(parsed).forEach(_ => {
						results.push({
							key: _,
							value: parsed[_]
						})
					});
					results = results.filter(_ => _.key !== "payload");					
				}
				catch(ex) {
					console.warn(ex)
				}
			}
			if ('{{environment}}'.length > 0) {
				results.push({ key: 'env', value: '{{environment}}' });
			}
			route = { controller: 'newrelic', action: type, id: options.id, query: results }
		} else if (type === 'navigate') {
			if (options.action === 'search') {
				// special handler for search
				route = { controller: 'search', action: 'open', query: [ { key: 'q', value: options.q } ]}
			}
			else {
				route = { controller: 'navigate', action: options.action, query: [ { key: 'q', value: options.q } ]}
			}
		} else {
			console.error(`unknown type=${type}`);
			return;
		}

		if (moniker.indexOf('jb-') === 0) {
			// jetbrains requires to pass the controller/action/ids as queryString params
			if (route && route.query) {
				route.query.push({key: 'controller', value: route.controller});
				if (route.action) {
					route.query.push({key: 'action', value: route.action});
				}
				if (route.id) {
					route.query.push({key: 'id', value: route.id});
				}
				if (options.file) {
				// var fileName = '{{rawFileName}}';
				 	route.query.push({key:'file', value: encodeURIComponent(options.file)  });
				}
			}
		}
		if (route) {
			protocol = `${protocolStart}${route.controller}`;
			if (route.id) {
				protocol += `/${route.id}`
			}
			if (route.action) {
				protocol += `/${route.action}`
			}
			if (route.query && route.query.length) {				
				protocol += '?1=1&';
				var len = route.query.length;
				for (var i = 0; i < len; i++) {
					var query = route.query[i];
					protocol += `${query.key}=${query.value}`;
					if (i + 1 < len) {
						protocol += `&`;
					}
				}
			}
		}
		else {
			console.warn('no route');
			return;
		}	 
		console.log(protocol);

		var startTime = new Date();
		var ideSelection;
		if (window.CODESTREAM._state) {
			if (window.CODESTREAM._state.MRU === true) {
				ideSelection = "MRU";
			}
			else if (window.CODESTREAM._state.lastOriginDetail === true) {
				ideSelection = "lastOriginDetail";
			}
			else {
				ideSelection = "User Selected";
			}
		}
		if (!ideSelection) {
			ideSelection = "User Selected";
		}
		
		window.protocolCheck(protocol,
			function () {
				//fail				
				const source = "{{src}}" || "shared_link";
				window.CODESTREAM.track("codestream/ide_redirect failed", { 
					"event_type": "response",
					"platform": "codestream",
					"path": "N/A (codestream)",
					"section": "N/A (codestream)",
					"meta_data": `ide_detail: ${moniker}`, 
					"meta_data_2": `selection_method: ${ideSelection}`,
					"meta_data_3": `source: ${source}`
				}, options.nrUserId);
				console.log(`CodeStream: failed in ${(new Date() - startTime)/1000}s for Moniker=${moniker} Path=${protocol} IDESelection=${ideSelection}`);
			}, function () {
				//success	
				const source = "{{src}}" || "shared_link";
				window.CODESTREAM.track("codestream/ide selected", { 
					"event_type": "response",
					"platform": "codestream",
					"path": "N/A (codestream)",
					"section": "N/A (codestream)",
					"meta_data": `ide_detail: ${moniker}`, 
					"meta_data_2": `selection_method: ${ideSelection}`,
					"meta_data_3": `source: ${source}`
				}, options.nrUserId);
				console.log(`CodeStream: success in ${(new Date() - startTime)/1000}s for Moniker=${moniker} Path=${protocol} IDESelection=${ideSelection}`);
		});	
}
var _openEditorCounter = 0;
function _openEditor(ide) { 
	var onAnyComplete = function() {
		$('#notification-area-vs').toggle(false);
		$('#notification-area-jb').toggle(false);

		var lastOrigin;
		try {
			var rawLastOrigin = window.CODESTREAM && window.CODESTREAM._state && window.CODESTREAM._state.lastOrigin;
			lastOrigin = JSON.parse(rawLastOrigin);
 		}
		catch(e){ }
		// on first click, just show the help stuff
		if (ide.protocol.indexOf("jetbrains") > -1) {
			$('#notification-area-jb').toggle(true);
			$('[data-ide-name=""]').html(ide.ideName);
			if (lastOrigin && lastOrigin.moniker !== ide.moniker) {
				// if the last ide we know about isn't the one they're selecting and we're here (aka requies an additional message), reset the counter
				_openEditorCounter = 1;
				window.CODESTREAM._state.lastOrigin = JSON.stringify(ide);
			}
			else {
				_openEditorCounter++;
			}			
		}
		else if (ide.protocol.indexOf("codestream-vs") > -1) {
			$('#notification-area-vs').toggle(true);
			$('[data-ide-name=""]').html(ide.ideName); 
			if (lastOrigin && lastOrigin.moniker !== ide.moniker) {
				// if the last ide we know about isn't the one they're selecting and we're here (aka requies an additional message), reset the counter
				_openEditorCounter = 1;
				window.CODESTREAM._state.lastOrigin = JSON.stringify(ide);
			}
			else {
				_openEditorCounter++;
			} 
		} else {
		   _openEditorCounter = 2;	
		}		
		
		if ((window.CODESTREAM && window.CODESTREAM._state && window.CODESTREAM._state.MRU) || _openEditorCounter > 1) {
			$("#notification-title").html("Opening link in New Relic CodeStream...");	
			window.CODESTREAM.openEditor(ide);
			// nuke the initial state
			delete window.CODESTREAM._state.MRU;
			delete window.CODESTREAM._state.lastOriginDetail;
			delete window.CODESTREAM._state.isSpecificIde;
		}		
	};

	try {
		if (window.CODESTREAM._state && window.CODESTREAM._state.isSpecificIde) {
			// don't set the cookie if we're opening an ide with a 1-time queryString
			onAnyComplete();
		}
		else {
			var xhr = new XMLHttpRequest();
			xhr.open('POST', '/web/ide/mru', true);
			xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
			xhr.send(JSON.stringify({
				ide: ide.moniker, 
				repoId: "{{uniqueRepoId}}",
				_csrf: "{{csrf}}"}
			))
			xhr.onload = function() {
				onAnyComplete();
			};
			xhr.onerror = function() {
				onAnyComplete();
			};
		}
	}
	catch (x) {
		console.error(x);
		onAnyComplete();
	}
}

// clicked the already-selected-button
function onIdeClick(e) {
	e.preventDefault();	
	var moniker = $('#selected-ide').attr("data-ide-moniker");
	_openEditor(ides.find(_ => _.moniker === moniker))
}

// clicked from the "dropdown"
function onIdeSelected(e, moniker) {
	e.preventDefault();
	var ide = ides.find(_ => _.moniker === moniker);
	try {
		$('#selected-ide')
			.addClass("selected-ide btn-light btn-block form-control btn-open-in")
			.attr("data-ide-moniker", ide.moniker)
			.attr('title', `Open with ${ide.ideName}`);

		$('#selected-ide-name').html(`Open in ${ide.ideName}`);
		$('#selected-ide-icon').attr('src', `https://images.codestream.com/ides/128/${ide.moniker}.png`);
		
		_openEditor(ides.find(_ => _.moniker === ide.moniker));
	}
	catch (e) {
		console.error(e);
	}
} 
</script> 
 

<div class="container" style="margin-bottom:35px;">
	<div class="interstitial-detail-wrapper">
		<div class="interstitial-action-wrapper">
			<div class="btn-group btn-set-width" style="white-space:nowrap;">
				{{#lastOrigin}}
					<span style="margin-right: 10px; font-size: x-large">
						Open in
					</span>
					<a id="selected-ide" 
						class="selected-ide btn-light btn-block form-control btn-open-in" 
						title="Open with {{ideName}}"
						href="#" 
						onclick="(function(e){onIdeClick(e);})(event)"
						data-ide-moniker="{{moniker}}">
						<img src="https://images.codestream.com/ides/128/{{moniker}}.png" id="selected-ide-icon" class="icon-ide" />
						<span id="selected-ide-name">Open in {{ideName}}</span>
					</a>
				{{/lastOrigin}}							
				<a href="#" class="btn-light dropdown-toggle-split dropdown-toggle-custom form-control"
					data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
					<svg style="width:15px;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 8" focusable="false" role="img"><title>Chevron bottom icon</title><path d="M6.6 1.6L4 4.3 1.4 1.6l-.8.8L4 5.7l3.4-3.3z"></path></svg>				</a> 
				<div class="dropdown-menu dropdown-menu-light dropdown-menu-right ide-list-items" data-element-ide-list="" 
					style="position: absolute !important; transform: translate3d(0px, 58px, 0px) !important; top: 0px !important; left: 0px !important; will-change: transform !important; width: 225px !important;"
				>
					{{#ides}}
						{{#if ideName}}
							<a class="dropdown-item dropdown-item-light" onclick="(function(e){onIdeSelected(e,'{{moniker}}');})(event)" href="#">
								<img src="https://images.codestream.com/ides/128/{{moniker}}.png" class="icon-ide" />{{ideName}}</a>
						{{/if}}
						{{^ideName}}
							{{#unless @last}}
								<div class="dropdown-divider dropdown-divider-light"></div>
							{{/unless}}
						{{/ideName}}
					{{/ides}}
				</div>
			</div>
		</div>
		<div id="notification-area-jb" style="display:none;" class="notification-content-wrapper">
			<div class="notification-icons">
				<img src="https://images.codestream.com/icons/status/stop_sign.png" class="notification-icon" />
			</div>
			<div class="notification-content-light">				 
				<div class="notification-text">
					1. Install the 
					<a href="https://www.jetbrains.com/toolbox/app/" target="_blank">
						JetBrains Toolbox App
					</a>
				</div>
				<div class="notification-text">
					2. Install the 
					<a href="https://plugins.jetbrains.com/plugin/12206-codestream" target="_blank">
						New Relic CodeStream extension
					</a>
				</div>
				<div class="notification-text">
					3. Return here and click "Open in <span data-ide-name=""></span>" again.
				</div>
			</div>
		</div>
		<div id="notification-area-vs" style="display:none;" class="notification-content-wrapper">
			<div class="notification-content-light">
				<div class="notification-text">
					1. Install the 
					<a href="https://marketplace.visualstudio.com/items?itemName=CodeStream.codestream-vs" target="_blank">
						New Relic CodeStream extension
					</a>
				</div>
				<div class="notification-text">
					2. Return here and click "Open in <span data-ide-name=""></span>" again.
				</div>
			</div> 
        </div>
	</div>
	<div class="content-body-container">
		<h4 style="text-align: center" class="content-body-header">
			All the power of New Relic, right in your IDE
		</h4>
		<div>
			Install New Relic's CodeStream IDE extension to see how the services built from your code
			are performing, and access powerful tools for identifying and investigating performance issues.
		</div>

		<div class="content-body-tab-container">
			<div style="width: 17%" class="content-body-tab-header" onclick="openTab(event, 'content-body-tab1')">
				<svg class="content-body-tab-icon" style="margin-top: -5px; width: 16px; fill: rgb(220, 223, 228)" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" focusable="false"><path fill-rule="evenodd" d="M4.446 1h7.108c.377 0 .747.114 1.067.327a2.131 2.131 0 01.747.882l2.576 5.534A.61.61 0 0116 8v4.82c0 .578-.213 1.133-.594 1.541-.38.41-.895.639-1.433.639H2.027c-.538 0-1.053-.23-1.433-.639A2.267 2.267 0 010 12.82V8c0-.09.02-.177.056-.257L2.632 2.21c.168-.363.426-.669.747-.883.32-.213.69-.327 1.067-.327zm0 1.148a.91.91 0 00-.505.155 1.01 1.01 0 00-.354.418v.001l-2.19 4.704h3.616c.179 0 .345.096.444.256l1.335 2.154h2.416l1.335-2.154a.524.524 0 01.444-.256h3.616l-2.19-4.704v-.001a1.009 1.009 0 00-.354-.418.91.91 0 00-.505-.155m3.38 6.426h-3.662l-1.335 2.154a.524.524 0 01-.444.256H6.507a.524.524 0 01-.444-.256L4.728 8.574H1.067v4.246c0 .274.1.536.28.73.18.194.425.302.68.302h11.946a.928.928 0 00.68-.302c.18-.194.28-.456.28-.73V8.574z" clip-rule="evenodd"></path></svg>
				Errors
			</div>
			<div style="width: 17%" class="content-body-tab-header" onclick="openTab(event, 'content-body-tab2')">
				<svg class="content-body-tab-icon" style="margin-top: -5px; width: 16px; fill: rgb(220, 223, 228)" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" focusable="false"><path fill-rule="evenodd" d="M7.7 0H2v15h11V5.3L7.7 0zm3.6 5H8V1.7L11.3 5zM3 1v13h9V6H7V1H3zm2 7h5v1H5V8zm3 3H5v1h3v-1z" clip-rule="evenodd"></path></svg>
				Logs
			</div>
			<div style="width: 29%" class="content-body-tab-header" onclick="openTab(event, 'content-body-tab3')">
				<svg class="content-body-tab-icon" style="margin-top: -5px; width: 16px; fill: rgb(220, 223, 228)" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" focusable="false"><path fill-rule="evenodd" d="M13 1H2C.9 1 0 1.9 0 3v10c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm1 12c0 .6-.4 1-1 1H2c-.6 0-1-.4-1-1V5h13v8zM1 4h13V3c0-.6-.4-1-1-1H2c-.6 0-1 .4-1 1v1zm3.4 8.4l2.8-2.9-2.8-2.9-.8.8 2.2 2.1-2.2 2.1.8.8zM12 11H8v1h4v-1z" clip-rule="evenodd"></path></svg>
				NRQL Queries
			</div>
			<div style="width: 32%" class="content-body-tab-header" onclick="openTab(event, 'content-body-tab4')">
				<svg class="content-body-tab-icon" style="margin-top: -5px; width: 16px; fill: rgb(220, 223, 228)" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" focusable="false"><path fill-rule="evenodd" d="M9 12v3H1v-3h8zm-1 1H2v1h6v-1zm4-6v3H1V7h11zm-1 1H2v1h9V8zm4-6v3H1V2h14zm-1 1H2v1h12V3z" clip-rule="evenodd"></path></svg>
				Code Performance
			</div>
		</div>

		<div class="content-body-tab" id="content-body-tab1">
			<div class="content-body-copy">
				Use the frames of the stack trace to navigate the code.  Leverage the power of New Relic AI, and the help of
				your teammates, to collaborate on the investigation.
			</div>
			<div>
				<img class="observability-gif" src="https://raw.githubusercontent.com/TeamCodeStream/CodeStream/develop/images/animated/ErrorsAI-VSC.gif" alt="CodeStream Observability" /> 
			</div>
		</div>
		<div class="content-body-tab" id="content-body-tab2">
			<div class="content-body-copy">
				Search logs for your APM or OTel services, or even an Infra container.  Intiate a log search
				directly from specific log lines in your code.
			</div>
			<div>
				<img class="observability-gif" src="https://images.codestream.com/misc/redirect-logs.png" /> 
			</div>
		</div>
		<div class="content-body-tab" id="content-body-tab3">		
			<div class="content-body-copy">
				Run queries right from your IDE, with auto-complete, visualizations, and export.  Share commonly
				used queries in .nrql files added to your repo, and run queries right from the file.
			</div>
			<div>
				<img class="observability-gif" src="https://images.codestream.com/misc/redirect-queries.png" /> 
			</div>
		</div>
		<div class="content-body-tab" id="content-body-tab4">
			<div class="content-body-copy">
				Identify transactions that are exhibiting performance problems since your last release, and drill down
				into specific methods, database operations or external services that are at the root of the problem.
			</div>
			<div>
				<img class="observability-gif" src="https://images.codestream.com/misc/redirect-anomalies.png" /> 
			</div>
		</div>
	</div>
</div>
<script src="//fast.wistia.com/embed/medias/aei2dq75qi.jsonp" async></script>
<script src="//fast.wistia.com/assets/external/E-v1.js" async></script>
<script>
    function openTab(evt, tabName) {
      	let tabcontent, tablinks;

        tabcontent = document.getElementsByClassName("content-body-tab");
        for (let i = 0; i < tabcontent.length; i++) {
            tabcontent[i].style.display = "none";
        }

        tablinks = document.getElementsByClassName("content-body-tab-header");
        for (let i = 0; i < tablinks.length; i++) {
            tablinks[i].classList.remove("content-active-tab");
        }

        document.getElementById(tabName).style.display = "block";

        evt.currentTarget.classList.add("content-active-tab");
    }

	// Start on logs tab if coming from logs, otherwise default to errors tab
	if ("{{pageType}}" === "logs"){
		document.getElementById("content-body-tab2").style.display = "block";
		document.getElementsByClassName("content-body-tab-header")[1].classList.add("content-active-tab");
	} else {
		document.getElementById("content-body-tab1").style.display = "block";
		document.getElementsByClassName("content-body-tab-header")[0].classList.add("content-active-tab");
	}

</script>
<script>
	$(function() {	
		if (
			String("{{autoOpen}}") == "true"
		) {
			$('#selected-ide').click();
		}
	});
</script>