UNPKG

bbpro

Version:

BrowserBox - remote browser isolation tool

1,095 lines (1,047 loc) 319 kB
import {s as $hN0lD$s, c as $hN0lD$c} from "../node_modules/bang.html/src/vv/vanillaview.js"; import {s as $hN0lD$s1, c as $hN0lD$c1} from "../../node_modules/bang.html/src/vv/vanillaview.js"; function $parcel$export(e, n, v, s) { Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true}); } function $parcel$exportWildcard(dest, source) { Object.keys(source).forEach(function(key) { if (key === 'default' || key === '__esModule' || Object.prototype.hasOwnProperty.call(dest, key)) { return; } Object.defineProperty(dest, key, { enumerable: true, get: function get() { return source[key]; } }); }); return dest; } var $parcel$global = globalThis; var $parcel$modules = {}; var $parcel$inits = {}; var parcelRequire = $parcel$global["parcelRequirec372"]; if (parcelRequire == null) { parcelRequire = function(id) { if (id in $parcel$modules) { return $parcel$modules[id].exports; } if (id in $parcel$inits) { var init = $parcel$inits[id]; delete $parcel$inits[id]; var module = {id: id, exports: {}}; $parcel$modules[id] = module; init.call(module.exports, module, module.exports); return module.exports; } var err = new Error("Cannot find module '" + id + "'"); err.code = 'MODULE_NOT_FOUND'; throw err; }; parcelRequire.register = function register(id, init) { $parcel$inits[id] = init; }; $parcel$global["parcelRequirec372"] = parcelRequire; } var parcelRegister = parcelRequire.register; // imports function $d94625c3a2476526$export$fb565972e52018f({ selectInput: { selectOpen: selectOpen, values: values, selected: selected }, executionContextId: executionContextId }, state) { state.waitingExecutionContext = executionContextId; if (state.ignoreSelectInputEvents) return; $d94625c3a2476526$var$toggleSelect({ selectOpen: selectOpen, values: values, selected: selected }); } function $d94625c3a2476526$var$toggleSelect({ selectOpen: selectOpen, values: values, selected: selected }) { try { const input = document.querySelector("bb-view").shadowRoot.querySelector("#selectinput"); if (selectOpen) { input.innerHTML = values; input.selectedIndex = selected; input.classList.add("open"); //input.focus(); } else { input.classList.remove("open"); input.innerHTML = ""; //input.blur(); } } catch (e) { console.warn`Select error ${e}`; } } //FIXME we could move this into constructor // and switch it to WS var $iT6R0 = parcelRequire("iT6R0"); const $3d0c8bfa5756f081$var$DEFAULT_FAVICON = `data:image/png;base64,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`; var $3d0c8bfa5756f081$export$2e2bcd8739ae039 = $3d0c8bfa5756f081$var$DEFAULT_FAVICON; const $f4e39816b3866cf5$var$STATE_SYMBOL = Symbol(`[[State]]`); const $f4e39816b3866cf5$var$MODAL_MESSAGE = `RBI is paused, probably because a modal dialog is open. It's alright, this happens sometimes. Before you leave a page, remember to close any modal dialogs. You can also try again to close the last one that was open.`; let $f4e39816b3866cf5$var$modaler; let $f4e39816b3866cf5$var$active; async function $f4e39816b3866cf5$export$bf2931cd7b20e6e2({ sessionToken: sessionToken }, getState) { (0, $iT6R0.DEBUG).debugTabs && console.log(`Fetch tabs called`); try { const url = new URL(location); url.pathname = "/api/v1/tabs"; const resp = await fetch(url); if (resp.ok) { const data = await resp.json(); if (data.error) { if (data.resetRequired) { const reload = confirm(`Some errors occurred and we can't seem to reach your cloud browser. You can try reloading the page and if the problem persists, try switching your cloud browser off then on again. Want to reload the page now?`); if (reload) location.reload(); } } if (data.vmPaused) { let { modal: modal } = data; (0, $iT6R0.DEBUG).debugModal && console.log("Remote Browser VM is paused. Probably because a modal dialog is open."); if (modal) { if (!$f4e39816b3866cf5$var$active) { clearTimeout($f4e39816b3866cf5$var$modaler); $f4e39816b3866cf5$var$modaler = setTimeout(async ()=>{ if ($f4e39816b3866cf5$var$active) return; $f4e39816b3866cf5$var$active = true; const state = getState(); (0, $iT6R0.DEBUG).debugModal && console.log({ modal: modal, 1: true }); await (0, $iT6R0.untilTrue)(()=>!!state?.viewState?.modalComponent, 100, 1000); (0, $iT6R0.DEBUG).debugModal && console.log({ modal: modal, 2: true }); state.viewState.modalComponent.openModal({ modal: modal }); (0, $iT6R0.DEBUG).debugModal && console.log({ modal: modal, 3: true }); await (0, $iT6R0.untilTrue)(()=>!state?.viewState?.currentModal, 100, 1000).then(()=>{ $f4e39816b3866cf5$var$active = false; (0, $iT6R0.DEBUG).debugModal && console.log("Active is now false."); }); (0, $iT6R0.DEBUG).debugModal && console.log({ modal: modal, 4: true }); }, 0); } } } (0, $iT6R0.DEBUG).debugBetterModals && console.log(data); if (data.tabs) { data.tabs = (data.tabs || []).filter(({ type: type })=>type == "page"); data.tabs = data.tabs.map((tab)=>new $f4e39816b3866cf5$var$Tab(tab, { getState: getState })); } (0, $iT6R0.DEBUG).debugTabs && console.log(data); return data; } else if (resp.status == 401) { console.warn(`Session has been cleared. Let's attempt relogin`, sessionToken); const x = new URL(location); x.pathname = "login"; x.search = `token=${sessionToken}&ran=${Math.random()}`; (0, $iT6R0.COMMON).blockAnotherReset = true; alert("Your browser cleared your session. We need to reload the page to refresh it."); (0, $iT6R0.COMMON).delayUnload = false; location.href = x; return; } } catch (e) { console.warn(e); alert(e); const reload = confirm(`Some errors occurred and we can't seem to reach your cloud browser. You can try reloading the page and if the problem persists, try switching your cloud browser off then on again. Want to reload the page now?`); if (reload) location.reload(); } } class $f4e39816b3866cf5$var$Tab { constructor({ ...tabDetails }, { getState: getState } = {}){ Object.assign(this, tabDetails); Object.defineProperty(this, $f4e39816b3866cf5$var$STATE_SYMBOL, { get: ()=>getState() }); } setDefaultFavicon() { this.faviconDataURI = (0, $3d0c8bfa5756f081$export$2e2bcd8739ae039); this.usingDefaultFavicon = true; } get faviconDataURI() { return this[$f4e39816b3866cf5$var$STATE_SYMBOL].favicons.get(this.targetId)?.dataURI; } set faviconDataURI(dataURI) { this[$f4e39816b3866cf5$var$STATE_SYMBOL].favicons.set(this.targetId, Object.assign(this[$f4e39816b3866cf5$var$STATE_SYMBOL].favicons.get(this.targetId) || {}, { dataURI: dataURI })); this.usingDefaultFavicon = false; } get favicon() { return this[$f4e39816b3866cf5$var$STATE_SYMBOL].favicons.get(this.targetId)?.favicon; } set favicon(favicon) { this[$f4e39816b3866cf5$var$STATE_SYMBOL].favicons.set(this.targetId, Object.assign(this[$f4e39816b3866cf5$var$STATE_SYMBOL].favicons.get(this.targetId) || {}, { favicon: favicon })); } } var $iT6R0 = parcelRequire("iT6R0"); const $82b4f7ce2c8e9dc5$var$imeLikelyUnicodeRanges = [ // Combining broad ranges for languages often using IME [ 0x2E80, 0x9FFF ], [ 0x0E00, 0x0E7F ], [ 0x0900, 0x097F ] ]; function $82b4f7ce2c8e9dc5$var$isInUnicodeRange(char, ranges) { const codePoint = char.codePointAt(0); return ranges.some(([start, end])=>codePoint >= start && codePoint <= end); } function $82b4f7ce2c8e9dc5$export$ff3c94dca8cdea21(inputField, state) { const ranges = $82b4f7ce2c8e9dc5$var$imeLikelyUnicodeRanges; if (inputField.imeDetection) return; inputField.imeDetection = 1; let usingIME = false; inputField.addEventListener("compositionstart", ()=>{ usingIME = true; state.usingIME = usingIME; (0, $iT6R0.DEBUG).debugIMEDetection && console.log("IME is being used.", { usingIME: usingIME }); }); inputField.addEventListener("compositionend", ()=>{ usingIME = false; state.usingIME = usingIME; (0, $iT6R0.DEBUG).debugIMEDetection && console.log("IME is NOT being used.", { usingIME: usingIME }); }); self.inputField = inputField; inputField.addEventListener("input", ()=>{ const lastChar = inputField.value.slice(-1); // Check if the last character falls within the typical IME Unicode ranges const imeLikely = $82b4f7ce2c8e9dc5$var$isInUnicodeRange(lastChar, ranges); usingIME ||= imeLikely; if (usingIME || imeLikely) (0, $iT6R0.DEBUG).debugIMEDetection && console.log("IME is likely being used.", { usingIME: usingIME, imeLikely: imeLikely }); else (0, $iT6R0.DEBUG).debugIMEDetection && console.log("Regular input or post-IME input.", { usingIME: usingIME, imeLikely: imeLikely }); state.usingIME = usingIME; (0, $iT6R0.DEBUG).debugIMEDetection && console.log("using ime", state.currentInputLanguageUsesIME, state); }, { capture: true }); inputField.imeDetection = 2; (0, $iT6R0.DEBUG).debugIMEDetection && console.log("installed ime detection"); } function $e9f0e9f2ca7fefe5$export$852351fd1d8fca1f({ multiplayer: multiplayer }, state) { const { onlineCount: onlineCount } = multiplayer; if (onlineCount && onlineCount !== state.onlineCount) { state.onlineCount = multiplayer.onlineCount; setState("bbpro", state); } } function $0d9a86a65e680a6e$export$bc32a5fcfc8a7ae({ keyInput: { keysCanInput: keysCanInput, isTextareaOrContenteditable: isTextareaOrContenteditable, type: type, inputmode: inputmode, value: value = "" }, executionContextId: executionContextId }, state) { if (state.ignoreKeysCanInputMessage) return; if (keysCanInput) { state.contextIdOfFocusedInput = executionContextId; if (!state.dontFocusControlInputs) { if (isTextareaOrContenteditable) state.viewState.focusTextarea(inputmode, value); else state.viewState.focusKeyinput(type, inputmode, value); } } else { state.contextIdOfFocusedInput = null; if (!state.dontFocusControlInputs) { const active = document.deepActiveElement; if (active == state.viewState.textarea) state.viewState.blurTextarea(); else if (active == state.viewState.keyinput) state.viewState.blurKeyinput(); } } } var $iT6R0 = parcelRequire("iT6R0"); function $c9d8cb61d8944574$export$f62089aa453e130c({ elementInfo: { attributes: attributes, innerText: innerText, noSuchElement: noSuchElement } }, state) { if (!state.elementInfoContinuation) { (0, $iT6R0.DEBUG).debugElementInfo && console.warn(`Got element info message, but no continuation to pass it to`); (0, $iT6R0.DEBUG).debugElementInfo && console.warn(JSON.stringify({ elementInfo: { attributes: attributes, innerText: innerText, noSuchElement: noSuchElement } })); return; } try { state.elementInfoContinuation({ attributes: attributes, innerText: innerText, noSuchElement: noSuchElement }); } catch (e) { console.warn(`Element info continuation failed`, state.elementInfoContinuation, e); console.warn(JSON.stringify({ elementInfo: { attributes: attributes, innerText: innerText, noSuchElement: noSuchElement } })); } } var $iT6R0 = parcelRequire("iT6R0"); const $0526ce16d0dc3940$export$1de010aa2873489 = (state)=>[ (el)=>{ // only have 1 context menu at a time const component = el.getRootNode().host; state.viewState.contextMenu = component; }, ()=>{ if (state.contextMenuGlobalClick) return; state.contextMenuGlobalClick = true; self.addEventListener("click", function remove(click) { // if we clicked outside the menu, // remove the menu and stop listening for such clicks (0, $iT6R0.DEBUG).val && console.log({ click: click }); (0, $iT6R0.DEBUG).debugContextMenu && console.log("Click target", click.target); if (state.ignoreNextClickEvent) { (0, $iT6R0.DEBUG).debugContextMenu && console.log("Not closing menu because ignoring this click event", click.target); click.preventDefault(); click.stopPropagation(); state.ignoreNextClickEvent = false; return; } if (!click.target.closest(".context-menu")) { (0, $iT6R0.DEBUG).debugContextMenu && console.log(`Removing context menu global click closer`); self.removeEventListener("click", remove, { capture: true }); state.contextMenuGlobalClick = false; if (state._top.viewState.contextMenu) { (0, $iT6R0.DEBUG).debugContextMenu && console.log(`Closing context menu because it is open`); state._top.viewState.contextMenu.close(state, false); } else (0, $iT6R0.DEBUG).debugContextMenu && console.log(`NOT closing context menu because it is NOT open`); } }, { capture: true }); }, async (el)=>{ (0, $iT6R0.DEBUG).debugContextMenu && console.log(`Check 2`, el); await (0, $iT6R0.untilTrue)(()=>!!state.contextMenuEvent); await (0, $iT6R0.untilTrue)(()=>!!state?.viewState?.contextMenu?.matches(".bang-styled")); (0, $iT6R0.DEBUG).debugContextMenu && console.log(`Check 3`); const contextMenu = state.contextMenuEvent; if (!contextMenu) { console.log(`context menu event, not arrived yet`); return; } else ((0, $iT6R0.DEBUG).debugContextMenu || (0, $iT6R0.DEBUG).val) && console.log("Context menu Event", contextMenu); let pageX, pageY; if (contextMenu?.detail?.pageX !== undefined) ({ pageX: pageX, pageY: pageY } = contextMenu.detail); else ({ pageX: pageX, pageY: pageY } = contextMenu); if ((0, $iT6R0.CONFIG).centerContextMenuOnMobile && (0, $iT6R0.deviceIsMobile)() || pageX === undefined || pageY === undefined) { pageX = (globalThis.window.innerWidth - el.scrollWidth) / 2; pageY = (globalThis.window.innerHeight - el.scrollHeight) / 2; } const x = pageX + "px"; const y = pageY + "px"; (0, $iT6R0.DEBUG).debugContextMenu && console.log(`Check 4`, { x: x, y: y }); const component = el.getRootNode().host; if (pageX + el.scrollWidth > globalThis.window.innerWidth - 8) component.style.right = "4px"; else component.style.left = x; if (pageY + el.scrollHeight > globalThis.window.innerHeight - 8) component.style.bottom = "4px"; else component.style.top = y; component.style.visibility = "visible"; } ]; const $0526ce16d0dc3940$export$11559b641d91f48b = (0, $iT6R0.DEBUG).debugContextMenu ? 375 : 375; function $44aadc44a225d442$export$8a9c9b6f9b0bef26({ executionContextId: executionContextId }, state) { state.viewState.latestScrollContext = executionContextId; } //import {LoadingIndicator} from '../subviews/loadingIndicator.js'; function $6a68183ee7023901$export$decd666f49a25970({ navigated: navigated }, state) { const { targetId: targetId } = navigated; state.loadings.delete(targetId); /* if ( state.activeTarget == targetId ) { LoadingIndicator(state); } */ } function $6a68183ee7023901$export$bca35ffa6fba3335({ resource: resource }, state) { const { targetId: targetId } = resource; state.loadings.set(targetId, resource); /* if ( state.activeTarget == targetId ) { LoadingIndicator(state); } */ } // MIGRATE var $iT6R0 = parcelRequire("iT6R0"); async function $0d9180dea3face4c$export$97f3c7149fcdc4e8({ targetId: targetId }, state) { await (0, $iT6R0.untilTrue)(()=>!!state?.tabMap); const tab = state.tabMap.get(targetId); (0, $iT6R0.DEBUG).debugFavicon && console.log(`reset favicon called for tab`, tab); if (tab) { tab.defaultFavicon = true; tab.faviconDataURI = (0, $3d0c8bfa5756f081$export$2e2bcd8739ae039); } tab?.favicon?.rerender(); } async function $0d9180dea3face4c$export$6091b9c288c9b04f({ favicon: { faviconDataUrl: faviconDataUrl, useDefaultFavicon: useDefaultFavicon, targetId: targetId } }, state) { await (0, $iT6R0.untilTrue)(()=>!!state?.tabMap); const tab = state.tabMap.get(targetId); (0, $iT6R0.DEBUG).debugFavicon && console.log("handle favicon message happening", { tab: tab, faviconDataUrl: faviconDataUrl, useDefaultFavicon: useDefaultFavicon, targetId: targetId }); if (useDefaultFavicon) return $0d9180dea3face4c$export$97f3c7149fcdc4e8({ targetId: targetId }, state); if (tab && targetId) { tab.faviconDataURI = faviconDataUrl; tab.defaultFavicon = false; } else if (targetId) { state.tabMap.set(targetId, { targetId: targetId, faviconDataURI: faviconDataUrl }); (0, $iT6R0.DEBUG).debugFavicon && console.warn(`No such tab for favicon with details:`, { faviconDataUrl: faviconDataUrl, targetId: targetId }); } else console.warn(`No such targetId for favicon with details:`, { faviconDataUrl: faviconDataUrl, targetId: targetId }); tab?.favicon?.rerender(); } var $iT6R0 = parcelRequire("iT6R0"); var $iT6R0 = parcelRequire("iT6R0"); const $bfc2920f02cf7874$var$StatusSymbol = Symbol(`[[ConnectivityStatus]]`); class $bfc2920f02cf7874$export$2e2bcd8739ae039 { constructor(timeout = (0, $iT6R0.CONFIG).privateConnectivity ? 6000 : 3700, debug = false){ this.biasToVerification = (0, $iT6R0.CONFIG).privateConnectivity ? 0.618 : 0.8; this.timeout = timeout; this.debug = debug; this.checkInProgress = false; this[$bfc2920f02cf7874$var$StatusSymbol] = "issue"; this.urls = (0, $iT6R0.CONFIG).privateConnectivity ? [ location.origin, location.origin ] : [ "https://1.1.1.1", "https://dns.google", "https://www.akamai.com", "https://www.lumen.com", "https://www.equinix.com", "https://www.f5.com", "https://www.cogentco.com", "https://www.he.net", "https://www.arista.com" ]; } async singleCheck(url) { const swatch = Math.random(); if (swatch < this.biasToVerification) { const timeoutPromise = new Promise((_, reject)=>{ setTimeout(()=>reject(new Error("Request timed out")), this.timeout); }); const fetchPromise = fetch(url, { method: "GET", mode: "no-cors" }); return Promise.race([ fetchPromise, timeoutPromise ]); } else if (navigator.onLine) return true; else throw new Error(`Offline`); } async checkInternet() { if (this.checkInProgress) { this.debug && console.log("Check already in progress, please wait."); return { status: "in-progress" }; } this.checkInProgress = true; let status = "issue"; let error; if ((0, $iT6R0.CONFIG).privateConnectivity) { try { await this.singleCheck(this.urls[0]); this.checkInProgress = false; status = "online"; } catch (e) { this.checkInProgress = false; this.status = "offline"; } this.status = status; return { status: status }; } else { // Shuffle and select two URLs const shuffledUrls = this.urls.sort(()=>0.5 - Math.random()); const selectedUrls = shuffledUrls.slice(0, 2); // Execute checks try { const results = await Promise.allSettled([ this.singleCheck(selectedUrls[0]), this.singleCheck(selectedUrls[1]) ]); const successfulChecks = results.filter((r)=>r.status === "fulfilled").length; if (successfulChecks === 2) { status = "online"; this.debug && console.log("You are online!"); } else if (successfulChecks === 0) { status = "offline"; this.debug && console.log("You are offline!"); } else { this.debug && console.log("Connection status is ambiguous. You might be experiencing network issues."); status = "issue"; } this.checkInProgress = false; } catch (err) { this.checkInProgress = false; this.debug && console.log("An error occurred while checking the connection.", err); error = err; this.status = "error"; return { status: "error", error: error }; } } this.status = status; return { status: status, error: error }; } get status() { return this[$bfc2920f02cf7874$var$StatusSymbol]; } set status(value) { switch(value){ case "online": case "offline": case "issue": case "error": this[$bfc2920f02cf7874$var$StatusSymbol] = value; break; default: throw new TypeError(`Invalid value ${value} for Connectivity status enum`); } } } // Converts an ArrayBuffer directly to base64, without any intermediate 'convert to string then // use window.btoa' step. According to my tests, this appears to be a faster approach: // http://jsperf.com/encoding-xhr-image-data/5 /* MIT LICENSE Copyright 2011 Jon Leighton Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ function $8432577b4e67a4da$export$2e2bcd8739ae039(arrayBuffer) { const encodings = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; const bytes = new Uint8Array(arrayBuffer); const byteLength = bytes.byteLength; const byteRemainder = byteLength % 3; const mainLength = byteLength - byteRemainder; let base64 = ""; let a, b, c, d; let chunk; // Main loop deals with bytes in chunks of 3 for(let i = 0; i < mainLength; i = i + 3){ // Combine the three bytes into a single integer chunk = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2]; // Use bitmasks to extract 6-bit segments from the triplet a = (chunk & 16515072) >> 18 // 16515072 = (2^6 - 1) << 18 ; b = (chunk & 258048) >> 12 // 258048 = (2^6 - 1) << 12 ; c = (chunk & 4032) >> 6 // 4032 = (2^6 - 1) << 6 ; d = chunk & 63 // 63 = 2^6 - 1 ; // Convert the raw binary segments to the appropriate ASCII encoding base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d]; } // Deal with the remaining bytes and padding if (byteRemainder == 1) { chunk = bytes[mainLength]; a = (chunk & 252) >> 2 // 252 = (2^6 - 1) << 2 ; // Set the 4 least significant bits to zero b = (chunk & 3) << 4 // 3 = 2^2 - 1 ; base64 += encodings[a] + encodings[b] + "=="; } else if (byteRemainder == 2) { chunk = bytes[mainLength] << 8 | bytes[mainLength + 1]; a = (chunk & 64512) >> 10 // 64512 = (2^6 - 1) << 10 ; b = (chunk & 1008) >> 4 // 1008 = (2^6 - 1) << 4 ; // Set the 2 least significant bits to zero c = (chunk & 15) << 2 // 15 = 2^4 - 1 ; base64 += encodings[a] + encodings[b] + encodings[c] + "="; } return base64; } const $48e9146c7332841e$var$$ = Symbol("[[EventQueuePrivates]]"); //const TIME_BETWEEN_ONLINE_CHECKS = 1001; const $48e9146c7332841e$var$FRAME_CHECK_INTERVAL = 100; const $48e9146c7332841e$var$ALERT_TIMEOUT = 300; const $48e9146c7332841e$var$SOCKET_RECONNECT_MS = 1618; const $48e9146c7332841e$var$PEER_RECONNECT_MS = 618; const $48e9146c7332841e$var$HEADER_BYTE_LEN = 28; const $48e9146c7332841e$var$KEYS = [ 1, 11, 13, 629, 1229, 2046, 17912, 37953, 92194, 151840 ]; const $48e9146c7332841e$var$MAX_E = 255; const $48e9146c7332841e$var$REGULAR_NO_FRAME_ACK_INTERVAL = 3001; const $48e9146c7332841e$var$BUFFERED_FRAME_EVENT = { type: "buffered-results-collection", command: { isBufferedResultsCollectionOnly: true, params: {} } }; const $48e9146c7332841e$var$BUFFERED_FRAME_COLLECT_DELAY = { MIN: 40, /* 250, 500 */ MAX: 4000 }; const $48e9146c7332841e$var$RACES = new Map(); const $48e9146c7332841e$var$Scores = []; const $48e9146c7332841e$var$AlreadySent = new Map(); const $48e9146c7332841e$var$SCORE_WINDOW = 11; const $48e9146c7332841e$var$MIN_DECISION_DATA = 5; const $48e9146c7332841e$var$ITYPE = "image/jpeg"; const $48e9146c7332841e$var$MAX_BW_MEASURES = 10; const $48e9146c7332841e$var$OldIncoming = new Map(); const $48e9146c7332841e$var$waiting = new Map(); const $48e9146c7332841e$var$isLE = (0, $iT6R0.littleEndian)(); const $48e9146c7332841e$var$Connectivity = { checker: new (0, $bfc2920f02cf7874$export$2e2bcd8739ae039)((0, $iT6R0.CONFIG).netCheckTimeout, (0, $iT6R0.DEBUG).netCheckDebug) }; let $48e9146c7332841e$var$loopCalls = 0; let $48e9146c7332841e$var$inFrameCount = 0; let $48e9146c7332841e$var$noFrameReceived = 1; let $48e9146c7332841e$var$WSScore = 0; let $48e9146c7332841e$var$WPScore = 0; let $48e9146c7332841e$var$connecting; let $48e9146c7332841e$var$latestReload; let $48e9146c7332841e$var$latestAlert; //let lastTestTime; //let lastOnlineCheck; let $48e9146c7332841e$var$messageId = Math.ceil(Math.random() * 10001) * 1000000; let $48e9146c7332841e$var$latestFrameId = -1; let $48e9146c7332841e$var$clearNextFrame = false; let $48e9146c7332841e$var$frameDrawing = false; let $48e9146c7332841e$var$bufferedFrameCollectDelay = $48e9146c7332841e$var$BUFFERED_FRAME_COLLECT_DELAY.MIN; class $48e9146c7332841e$var$Privates { constructor(publics, state1, sessionToken){ this.willCollectBufferedFrame = null; this.websockets = new Map(); this.publics = publics; this.subscribers = []; this.translators = new Map(); this.eventQueue = new Map(); this.images = new Map(); this.typeLists = new Map(); this.loopActive = false; this.Data = []; this.Meta = []; this.sessionToken = sessionToken; const WindowLength = 10; const messageWindow = []; const bwWindow = []; Object.defineProperty(this, "screenshotReceived", { get () { return state1.screenshotReceived; }, set (val) { state1.screenshotReceived = val; (0, $iT6R0.DEBUG).logAcks && val && console.log("set screenshot received", state1.screenshotReceived); } }); this.addBytes = (n, hasFrame)=>{ state1.totalBytes += n; if (hasFrame) { messageWindow.push(n); bwWindow.push(state1.totalBytesThisSecond); while(messageWindow.length > WindowLength)messageWindow.shift(); while(bwWindow.length > WindowLength)bwWindow.shift(); const averageSize = Math.round(messageWindow.reduce((total, size)=>total + size, 0) / messageWindow.length); const averageBw = Math.round(bwWindow.reduce((total, size)=>total + size, 0) / bwWindow.length); if ((0, $iT6R0.DEBUG).adpativeImageQuality) { if (averageSize > averageBw * 1.1) state1.H({ custom: true, type: "resample-imagery", down: true, averageBw: averageBw }); else if (averageSize < averageBw * 0.9) state1.H({ custom: true, type: "resample-imagery", up: true, averageBw: averageBw }); } } }; let lastBytes = 0; let lastCheck = Date.now(); if (!(0, $iT6R0.DEBUG).framesPushed || (0, $iT6R0.DEBUG).regularFrameCheck) { this.checkForFrames(); (0, $iT6R0.DEBUG).val && console.log("Starting check for frames"); } $48e9146c7332841e$var$ackIfNoFrame(state1); //clearNextFrame = true; } static get firstDelay() { return 37; /* 20, 40, 250, 500;*/ } triggerSendLoop() { if (this.loopActive) return; this.loopActive = true; this.currentDelay = this.constructor.firstDelay; clearTimeout(this.currentLoop); this.currentLoop = setTimeout(()=>this.nextLoop(), this.currentDelay); } sendImmediate(event) { (0, $iT6R0.DEBUG).debugTabs && console.log(`Sending immediately`, event); const url = this.subscribers[0]; return this.sendEvents({ events: [ event ], url: url }); } async nextLoop() { (0, $iT6R0.DEBUG).logLoop && console.log("Loop start"); $48e9146c7332841e$var$loopCalls++; //let data, meta, totalBandwidth; let q = Array.from(this.publics.queue); const url = this.subscribers[0]; if (!this.publics.state.demoMode && this.translators.has(url)) { const translator = this.translators.get(url); q = q.map((e)=>translator(e, {})).filter((e)=>e !== undefined); q = q.reduce((Q, e)=>(Array.isArray(e) ? Q.push(...e) : Q.push(e), Q), []); } const firstChainIndex = q.findIndex((e)=>!!e.chain); let chain, events; if (firstChainIndex == -1) { events = q.splice(0, $48e9146c7332841e$var$MAX_E); this.publics.queue.splice(0, $48e9146c7332841e$var$MAX_E); } else if (firstChainIndex == 0) { ({ chain: chain } = q.shift()); this.publics.queue.shift(); } else { const splice_index = Math.min($48e9146c7332841e$var$MAX_E, firstChainIndex); events = q.splice(0, splice_index); this.publics.queue.splice(0, splice_index); } if (chain) this.sendEventChain({ chain: chain, url: url }).then(({ data: data, meta: meta, totalBandwidth: totalBandwidth })=>{ if (!!data) { if (data.some(({ vmPaused: vmPaused })=>vmPaused)) (0, $iT6R0.DEBUG).debugVM && console.log("VM PAUSED"); } if (!!meta && meta.length) meta.forEach((metaItem)=>{ const executionContextId = metaItem.executionContextId; (0, $iT6R0.DEBUG).logMeta && console.log(`Meta in chain`, metaItem); for (const key of Object.keys(metaItem)){ (0, $iT6R0.DEBUG).logMeta && console.log("meta", key, metaItem); let typeList = this.typeLists.get(key); if (typeList) typeList.forEach((func)=>{ try { func({ [key]: metaItem[key], executionContextId: executionContextId }); } catch (e) { console.warn(`Error on ${key} handler`, func, e); } }); } }); if (totalBandwidth) this.publics.state.totalBandwidth = totalBandwidth; }); else this.sendEvents({ events: events, url: url }).then(()=>{}); if ((0, $iT6R0.DEBUG).asyncLoop) await (0, $iT6R0.sleep)(this.currentDelay / 2); ///* let measure, dist; if ((0, $iT6R0.DEBUG).logLoop) { measure = Date.now(); dist = measure - this.lastMeasure; } if (this.publics.queue.length) { (0, $iT6R0.DEBUG).logLoop && console.log(`Loop continue (frame:${$48e9146c7332841e$var$latestFrameId}) (loops:${$48e9146c7332841e$var$loopCalls})`, dist); if ((0, $iT6R0.DEBUG).asyncLoop) { clearTimeout(this.currentLoop); this.currentLoop = setTimeout(()=>this.nextLoop(), this.currentDelay / 2); } else { clearTimeout(this.currentLoop); this.currentLoop = setTimeout(()=>this.nextLoop(), this.currentDelay); } } else { (0, $iT6R0.DEBUG).logLoop && console.log(`Loop stop (frame:${$48e9146c7332841e$var$latestFrameId}) (loops:${$48e9146c7332841e$var$loopCalls})`, dist); this.loopActive = false; } if ((0, $iT6R0.DEBUG).logLoop) this.lastMeasure = measure; //*/ } queueEvents({ events: events, url: url }) { let q = this.eventQueue.get(url); if (!q) { q = []; this.eventQueue.set(url, q); } q.push(...events); (0, $iT6R0.DEBUG).debugQdEs && console.log(`Queued`, [ ...events ], this.eventQueue); (0, $iT6R0.DEBUG).debugQdEs && console.log(`Total queue length`, q.length); } hasQueuedEvents(url) { return this.eventQueue.get(url)?.length > 0; } unqueueEvents(url) { let q; if (this.hasQueuedEvents(url)) { q = this.eventQueue.get(url); this.eventQueue.set(url, []); } else q = []; (0, $iT6R0.DEBUG).debugQdEs && console.log(`Unqueued`, [ ...q ]); (0, $iT6R0.DEBUG).debugQdEs && console.log(`Total queue length`, 0); return q; } async sendEvents({ events: events, url: url }) { (0, $iT6R0.DEBUG).debugConnect && console.info(`Send events A`, events, url); if (this.hasQueuedEvents(url)) { events = [ ...this.unqueueEvents(url), ...events ]; (0, $iT6R0.DEBUG).debugQdEs && console.log(`1 Forming events to send from passed events and queued events:`, events, this.eventQueue); } if (!events) return { meta: [], data: [] }; events = events.filter((e)=>!!e && !!e.command); if (events.length == 0) return { meta: [], data: [] }; this.checkForBufferedFrames(events); let protocol; try { url = new URL(url); protocol = url.protocol; // OK WTF url.search = `session_token=${this.sessionToken}`; url = url + ""; } catch (e) { alert("WTF " + url); console.warn(e, url, this); } if (!this.publics.state.demoMode) { ((0, $iT6R0.DEBUG).debugQdEs || (0, $iT6R0.DEBUG).debugConnect) && console.info(`Send events B (${events.length} events)`, events, url); if (protocol == "ws:" || protocol == "wss:") try { if (!this.senders) this.senders = this.websockets.get(url); const { senders: senders } = this; $48e9146c7332841e$var$messageId++; let resolve; const promise = new Promise((res)=>resolve = res); const sendClosure = (senders)=>senders.so({ messageId: $48e9146c7332841e$var$messageId, zombie: { events: events }, screenshotAck: $48e9146c7332841e$var$noFrameReceived || this.screenshotReceived }, { url: url, resolve: resolve }); ((0, $iT6R0.DEBUG).debugQdEs || (0, $iT6R0.DEBUG).debugConnect) && console.info(`Send events C`, senders); if (senders) { if ((0, $iT6R0.DEBUG).logAcks && this.screenshotReceived) { const measure = Date.now(); const dist = measure - this.lastAckTime; this.lastAckTime = measure; console.log("ASYNC Ack sent. Time since last ack sent", dist, ". Time since this shot received", measure - this.publics.state.lastShotAt); } try { sendClosure(senders); } catch (e) { console.warn(`Issue with sendClosure`, sendClosure, e); } this.screenshotReceived = undefined; } else { (0, $iT6R0.DEBUG).debugConnect && console.log("Awaiting connect", url, this.websockets); this.queueEvents({ events: events, url: url }); const connected = await this.connectSocket(url); if (!connected) { (0, $iT6R0.DEBUG).debugConnect && console.info(`Socket did not connect...will retry`); await (0, $iT6R0.sleep)(666); //return this.sendEvents({events:[], url}); } ((0, $iT6R0.DEBUG).debugQdEs || (0, $iT6R0.DEBUG).debugConnect) && console.info(`Socket connected.`); } return promise; } catch (e) { console.warn(e); console.warn(JSON.stringify({ msg: `Error sending event to websocket ${url}`, events: events, url: url, error: e })); return { error: "failed to send", events: events }; } else { const request = { method: "POST", body: JSON.stringify({ events: events }), headers: { "content-type": "application/json" } }; return fetch(url, request).then((r)=>r.json()).then(async ({ data: data, frameBuffer: frameBuffer, meta: meta })=>{ if (!!frameBuffer && this.images.has(url)) { if ((0, $iT6R0.DEBUG).logAcks) { const measure = Date.now(); const dist = measure - this.publics.state.lastShotAt; this.publics.state.lastShotAt = measure; console.log("Got shot. Time since last", dist); } if ((0, $iT6R0.DEBUG).immediateAck) { $48e9146c7332841e$var$messageId++; $48e9146c7332841e$var$noFrameReceived = 0; this.publics.state.screenshotReceived = { frameId: this.publics.state.latestFrameReceived, castSessionId: this.publics.state.latestCastSession }; this.senders.so({ messageId: $48e9146c7332841e$var$messageId, zombie: { events: [ $48e9146c7332841e$var$BUFFERED_FRAME_EVENT ] }, screenshotAck: $48e9146c7332841e$var$noFrameReceived || this.screenshotReceived }); this.publics.state.screenshotReceived = false; if ((0, $iT6R0.DEBUG).logAcks) { const measure = Date.now(); const dist = measure - this.lastAckTime; this.lastAckTime = measure; console.log("Ack sent. Time since last ack sent", dist, ". Time since this shot received", measure - this.publics.state.lastShotAt); } } $48e9146c7332841e$var$drawFrames(this.publics.state, frameBuffer, this.images.get(url)); } const errors = data.filter((d)=>!!d.error); if (errors.length) { (0, $iT6R0.DEBUG).val >= (0, $iT6R0.DEBUG).low && console.warn(`${errors.length} errors occured.`); (0, $iT6R0.DEBUG).val >= (0, $iT6R0.DEBUG).low && console.log(JSON.stringify(errors)); } return { data: data, meta: meta }; }).catch((e)=>{ console.warn(JSON.stringify({ msg: `Error sending event to POST url ${url}`, events: events, url: url, error: e })); return { error: "failed to send", events: events }; }); } } else return await this.publics.state.demoEventConsumer({ events: events }); } async connectSocket(url, sendClosure) { // normalize URL forces us to have only 1 browser-backend connection per origin // we could change this but for now keep it const wsUrl = url; url = $48e9146c7332841e$var$normalizeUrl(url); const privates = this; let resolve; const promise = new Promise((res)=>resolve = res); if ($48e9146c7332841e$var$connecting) //await untilTrue(() => this.websockets.has(url)); try { sendClosure(this.websockets.get(url)); } catch (e) { resolve(false); } else if (!this.publics.state.demoMode && $48e9146c7332841e$var$onLine() && !$48e9146c7332841e$var$connecting) { $48e9146c7332841e$var$connecting = true; let peer; let socket; let Senders; let AssureOpenTask; try { socket = new WebSocket(wsUrl); (0, $iT6R0.DEBUG).cnx && console.info("Creating socket"); socket.binaryType = "blob"; $48e9146c7332841e$var$connecting = socket; socket.onopen = ()=>{ privates.socket = socket; (0, $iT6R0.DEBUG).cnx && console.log(`WebS