bbpro
Version:
BrowserBox - remote browser isolation tool
478 lines (463 loc) • 19.5 kB
JavaScript
function $parcel$export(e, n, v, s) {
Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
}
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;
parcelRegister("iT6R0", function(module, exports) {
$parcel$export(module.exports, "SERVICE_COUNT", () => $dc02ae1d9a800d1d$export$ee9fc76acd4d3ae8);
$parcel$export(module.exports, "FRAME_CONTROL", () => $dc02ae1d9a800d1d$export$9dcc2e02386b68c3);
$parcel$export(module.exports, "VERSION", () => $dc02ae1d9a800d1d$export$a4ad2735b021c132);
$parcel$export(module.exports, "iden", () => $dc02ae1d9a800d1d$export$55e2939a8f16392c);
$parcel$export(module.exports, "isSafari", () => $dc02ae1d9a800d1d$export$95df08bae54cb4df);
$parcel$export(module.exports, "BLANK", () => $dc02ae1d9a800d1d$export$8b3da334abb66be4);
$parcel$export(module.exports, "USE_DDG", () => $dc02ae1d9a800d1d$export$57008c6a656bd989);
$parcel$export(module.exports, "OPTIONS", () => $dc02ae1d9a800d1d$export$8eb3892b442747bd);
$parcel$export(module.exports, "DEBUG", () => $dc02ae1d9a800d1d$export$3f32c2013f0dcc1e);
$parcel$export(module.exports, "deviceIsMobile", () => $dc02ae1d9a800d1d$export$ca775e5d37b5320);
$parcel$export(module.exports, "CONFIG", () => $dc02ae1d9a800d1d$export$1630b5343357e8b5);
$parcel$export(module.exports, "CHAR", () => $dc02ae1d9a800d1d$export$9e88d7b6f62f62d8);
$parcel$export(module.exports, "COMMON", () => $dc02ae1d9a800d1d$export$86f1dfd3ce213c93);
$parcel$export(module.exports, "sleep", () => $dc02ae1d9a800d1d$export$e772c8ff12451969);
$parcel$export(module.exports, "debounce", () => $dc02ae1d9a800d1d$export$61fc7d43ac8f84b0);
$parcel$export(module.exports, "throttle", () => $dc02ae1d9a800d1d$export$de363e709c412c8a);
$parcel$export(module.exports, "littleEndian", () => $dc02ae1d9a800d1d$export$bbf3db47f3cb1881);
$parcel$export(module.exports, "be2le", () => $dc02ae1d9a800d1d$export$899749ffa4b84453);
$parcel$export(module.exports, "logitKeyInputEvent", () => $dc02ae1d9a800d1d$export$e7d2b79d200ea62);
$parcel$export(module.exports, "elogit", () => $dc02ae1d9a800d1d$export$c28506313afd25db);
$parcel$export(module.exports, "logit", () => $dc02ae1d9a800d1d$export$cdb624a6994a61c0);
$parcel$export(module.exports, "untilTrue", () => $dc02ae1d9a800d1d$export$e26007e3056af1f2);
$parcel$export(module.exports, "untilHuman", () => $dc02ae1d9a800d1d$export$d9b57ae9ef5f7013);
$parcel$export(module.exports, "untilTrueOrTimeout", () => $dc02ae1d9a800d1d$export$279fa041b1cf551d);
$parcel$export(module.exports, "randomInterval", () => $dc02ae1d9a800d1d$export$e58ec57d99ec296);
const $dc02ae1d9a800d1d$export$ee9fc76acd4d3ae8 = 4; // pptr(menu), chat, audio, devtools
const $dc02ae1d9a800d1d$export$9dcc2e02386b68c3 = false;
const $dc02ae1d9a800d1d$export$a4ad2735b021c132 = "3.14159265358979323846264338327950";
const $dc02ae1d9a800d1d$export$d6d004a6c8c04703 = /^((?!chrome|android).)*safari/i;
const $dc02ae1d9a800d1d$var$MobilePlatform = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
const $dc02ae1d9a800d1d$var$FirefoxPlatform = /firefox/i;
const $dc02ae1d9a800d1d$export$55e2939a8f16392c = (e)=>e;
const $dc02ae1d9a800d1d$export$95df08bae54cb4df = ()=>$dc02ae1d9a800d1d$export$d6d004a6c8c04703.test(navigator.userAgent);
const $dc02ae1d9a800d1d$export$8b3da334abb66be4 = "about:blank";
const $dc02ae1d9a800d1d$export$57008c6a656bd989 = true;
const $dc02ae1d9a800d1d$var$MIN_WAIT = 50;
const $dc02ae1d9a800d1d$var$MAX_WAITS = 200;
const $dc02ae1d9a800d1d$export$8eb3892b442747bd = {
showBWStatus: true,
showTorStatus: true,
showAudioStatus: true,
showWebRTCStatus: true,
useSystemColorScheme: true,
useDarkMode: false
};
const $dc02ae1d9a800d1d$export$3f32c2013f0dcc1e = Object.freeze({
// note on: increaseResolutionOfSmallerCanvas
// this seems to look clearer on smaller devices when we are using a scaled up co viewport,
// from multiple clients
// but it throws off the bitmap calculation for pointer events
// so switching off for now
increaseResolutionOfSmallerCanvas: false,
debugIMEDetection: true,
debugShrink: false,
debugResize: false,
debugImageRemainderClears: false,
debugDownload: false,
debugNetCheck: false,
debugActivate: false,
debugDownloadProgress: false,
logBandwidthIssueChanges: false,
debugSafariWebRTC: false,
debugSetup: false,
/* debug connections */ cnx: false,
debugIntentPrompts: false,
allowContextMenuOnContextMenu: true,
debugTabs: false,
debugContextMenu: false,
debugQdEs: false,
/* QdEs == QueuedEvents */ debugConnect: false,
debugBetterModals: false,
debugHistory: false,
debugFavicon: false,
debugElementInfo: false,
coords: false,
debugBitmapCoordConversion: false,
debugEventChains: false,
debugEventQueue: false,
HFUNCTION: false,
debugCopyPaste: false,
trackLoading: true,
debugAudioAck: false,
debugFastest: false,
get useStraightAudioStream () {
return location.host.endsWith(".onion") || false;
},
get includeAudioElementAnyway () {
return $dc02ae1d9a800d1d$export$95df08bae54cb4df() || $dc02ae1d9a800d1d$export$ca775e5d37b5320() || this.useStraightAudioStream;
},
scaleImage: true,
centerImage: false,
dontEnforceOnlineCheck: true,
newUI: true,
get useWindowOpenForSecureView () {
return !$dc02ae1d9a800d1d$export$ca775e5d37b5320();
},
showCollect: false,
debugFocus: false,
debugAuth: false,
debugAudio: false,
debugModal: false,
get debugMeta () {
return this.debugFavicon > 1 || 0;
},
get untabledServerMessageId () {
return this.debugMeta > 1;
},
debugCast: false,
debugBox: false,
debugDraw: false,
debugDevTools: false,
debugFrameDrops: false,
logFrameIds: false,
dropFramesWhenDrawing: false,
ensureScroll: false,
useDataURL: false,
noCollect: false,
/* do not do buffered frame collection */ mobileUIDefault: true,
/* mobile UI defaults to true (visible) or false (not visible) */ toggleUI: true,
/* switches toggle UI option on */ get logMeta () {
return !!this.debugMeta;
},
ackEvery: 1,
asyncLoop: false,
immediateAck: true,
showKeyboardToggleInContextMenu: false,
logRaces: false,
logAcks: false,
regularFrameCheck: false,
showUnreadBadge: true,
framesPushed: true,
clientsCanResetViewport: true,
adaptiveImageQuality: false,
loggableEvents: new Set([
/*typing events*/ "keydown",
"keypress",
"keyup",
"compositionstart",
"compositionupdate",
"compositionend",
"input",
"beforeinput",
/*pointing events*/ "pointerdown",
"pointerup",
"pointermove",
"touchmove",
"touchstart",
"touchcancel",
"mousedown",
"mouseup",
"mousemove",
"click",
"contextmenu",
"dblclick"
]),
activateDebug: false,
activateNewTab: true,
frameControl: $dc02ae1d9a800d1d$export$9dcc2e02386b68c3,
sidebarMenu: false,
pluginsMenu: false,
serviceWorker: false,
neonMode: false,
resetCache: false,
exposeState: true,
fullScope: false,
get err () {
return this.fullScope || false;
},
get promiserejection () {
return this.fullScope || false;
},
get dev () {
return this.fullScope || false;
},
get val () {
return this.fullScope ? 1 : 0;
},
low: 1,
med: 3,
high: 5
});
const $dc02ae1d9a800d1d$export$1630b5343357e8b5 = Object.freeze({
get useServiceWorkerToCache () {
return location.hostname !== "localhost" && true;
},
downloadMeterVanishTimeout: $dc02ae1d9a800d1d$export$3f32c2013f0dcc1e.debugDownload ? 500000 : 5000,
ACK_BLAST_LENGTH: 1000,
netCheckTimeout: 6007,
netCheckMinGap: 2000,
netCheckMaxGap: 7001,
doAckBlast: true,
/* making this true means we don't check audio start on every tap or click BUT
it does seem to interfere with audio restarting in the case it stops
*/ centerContextMenuOnMobile: true,
get darkMode () {
if ($dc02ae1d9a800d1d$export$8eb3892b442747bd.useSystemColorScheme) {
const isDark = globalThis.window.top.matchMedia("screen and (prefers-color-scheme: dark)");
return isDark;
}
return $dc02ae1d9a800d1d$export$8eb3892b442747bd.useDarkMode;
},
showModalOnFileDownload: false,
settingsButton: false,
useBlankWindowForProtocolLaunch: false,
removeAudioStartHandlersAfterFirstStart: false,
uiDefaultOff: false,
magicBar: false,
audioServiceFileName: "audio.srv",
devtoolsServiceFileName: "devtools.srv",
sessionTokenFileName: "session.tkn",
get isOnion () {
return location.host.endsWith(".onion");
},
get privateConnectivity () {
return this.isOnion || true; // on by default now
}
});
const $dc02ae1d9a800d1d$export$9e88d7b6f62f62d8 = Object.freeze({
loadReload: "↻",
/*"⟳",*/ /*"♻", */ /*"↻",*/ forward: "›",
backward: "‹",
approxequals: "≈",
newtab: "+",
/*'⋕',*/ /*"⛌",*/ /*"✖",*/ /*"➕",*/ /*"+",*/ /*"⋰", */ /*"⋕",*/ tabcloser: "+",
/*"⛌",*/ /*"╳",*/ /*"␡",*/ /*"⌧",*/ /*"≠",*/ /*"⋱",*/ menuopener: "⋯",
menucloser: "⋮",
/*"∘"*/ /*
viewportresize: ["ߧ", "಄", "ౚ",
...Range(3104, 3111).map(n => `&#${n};`),
...Range(3120, 3125).map(n => `&#${n};`)
][2],
*/ viewportresize: "■",
/*"ౚ", */ complexmenu: "֍"
});
const $dc02ae1d9a800d1d$export$86f1dfd3ce213c93 = Object.seal(Object.preventExtensions({
blockAnotherReset: false,
delayUnload: false
}));
async function $dc02ae1d9a800d1d$export$e772c8ff12451969(ms) {
return new Promise((res)=>setTimeout(res, ms));
}
function $dc02ae1d9a800d1d$export$61fc7d43ac8f84b0(func, wait) {
let timeout;
return function(...args) {
const later = ()=>{
timeout = null;
func.apply(this, args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
function $dc02ae1d9a800d1d$export$de363e709c412c8a(func, wait) {
let timeout;
const throttled = (...args)=>{
if (!timeout) {
timeout = setTimeout(()=>timeout = false, wait);
return func(...args);
}
};
return throttled;
}
function $dc02ae1d9a800d1d$export$bbf3db47f3cb1881() {
const uInt32 = new Uint32Array([
0x11223344
]);
const uInt8 = new Uint8Array(uInt32.buffer);
if (uInt8[0] === 0x44) return true;
else if (uInt8[0] === 0x11) return false;
else return true;
}
function $dc02ae1d9a800d1d$export$899749ffa4b84453(u32) {
const u32a = new Uint32Array([
u32
]);
const data = new Uint8Array(u32a.buffer);
return data[3] << 0 | data[2] << 8 | data[1] << 16 | data[0] << 24;
}
function $dc02ae1d9a800d1d$export$b7d78993b74f766d() {
return $dc02ae1d9a800d1d$var$FirefoxPlatform.test(navigator.userAgent);
}
function $dc02ae1d9a800d1d$export$ca775e5d37b5320() {
return $dc02ae1d9a800d1d$var$MobilePlatform.test(navigator.userAgent);
}
function $dc02ae1d9a800d1d$export$e7d2b79d200ea62(e) {
if ($dc02ae1d9a800d1d$export$3f32c2013f0dcc1e.val < $dc02ae1d9a800d1d$export$3f32c2013f0dcc1e.high && $dc02ae1d9a800d1d$export$3f32c2013f0dcc1e.debugBox) return;
if ($dc02ae1d9a800d1d$export$3f32c2013f0dcc1e.loggableEvents && !$dc02ae1d9a800d1d$export$3f32c2013f0dcc1e.loggableEvents.has(e.type)) return;
const { type: type, key: key, code: code, data: data, isComposing: isComposing, inputType: inputType, composed: composed, target: { value: value } } = e;
const typingData = {
key: key,
code: code,
type: type,
data: data,
isComposing: isComposing,
inputType: inputType,
composed: composed,
value: value
};
const debugBox = document.querySelector("#debugBox");
if (debugBox) debugBox.insertAdjacentHTML("afterbegin", `<p style="max-width:90vw;"><code><pre>${JSON.stringify(typingData, null, 2)}</code></pre></p>`);
else {
if ($dc02ae1d9a800d1d$export$ca775e5d37b5320()) alert("No debugBox found");
else throw new Error("No element with ID 'debugBox' found.");
}
}
function $dc02ae1d9a800d1d$export$c28506313afd25db(e) {
if ($dc02ae1d9a800d1d$export$3f32c2013f0dcc1e.val < $dc02ae1d9a800d1d$export$3f32c2013f0dcc1e.high && !$dc02ae1d9a800d1d$export$3f32c2013f0dcc1e.debugBox) return;
if ($dc02ae1d9a800d1d$export$3f32c2013f0dcc1e.loggableEvents && !$dc02ae1d9a800d1d$export$3f32c2013f0dcc1e.loggableEvents.has(e.type)) return;
const { type: type, defaultPrevented: defaultPrevented, clientX: clientX, clientY: clientY, touches: touches, deltaX: deltaX, deltaY: deltaY, ctrlKey: ctrlKey, metaKey: metaKey, shiftKey: shiftKey, pointerType: pointerType, isPrimary: isPrimary, button: button, buttons: buttons } = e;
const data = {
type: type,
defaultPrevented: defaultPrevented,
clientX: clientX,
clientY: clientY,
touches: touches,
deltaX: deltaX,
deltaY: deltaY,
ctrlKey: ctrlKey,
metaKey: metaKey,
shiftKey: shiftKey,
pointerType: pointerType,
isPrimary: isPrimary,
button: button,
buttons: buttons
};
const debugBox = document.querySelector("#debugBox");
if (debugBox) debugBox.insertAdjacentHTML("afterbegin", `<p style="max-width:90vw;"><code><pre>${JSON.stringify(data, null, 2)}</code></pre></p>`);
else {
if ($dc02ae1d9a800d1d$export$ca775e5d37b5320()) alert("No debugBox found");
else throw new Error("No element with ID 'debugBox' found.");
}
}
function $dc02ae1d9a800d1d$export$9a58ef0d7ad3278c(...args) {
return [
...$dc02ae1d9a800d1d$export$54e4d5a87c224695(...args)
];
}
function* $dc02ae1d9a800d1d$export$54e4d5a87c224695(a, b, inc = 1) {
let i = a;
for(let i = a; i <= b; i += inc)yield i;
}
function $dc02ae1d9a800d1d$export$cdb624a6994a61c0(info) {
if (!$dc02ae1d9a800d1d$export$3f32c2013f0dcc1e.val) return;
const debugBox = document.querySelector("#debugBox");
if (debugBox) debugBox.insertAdjacentHTML("afterbegin", `<p style="max-width:90vw;"><code><pre>${JSON.stringify(info, null, 2)}</code></pre></p>`);
else throw new Error("No element with ID 'debugBox' found.");
}
async function $dc02ae1d9a800d1d$export$e26007e3056af1f2(pred, waitOverride = $dc02ae1d9a800d1d$var$MIN_WAIT, maxWaits = $dc02ae1d9a800d1d$var$MAX_WAITS, failCallback) {
let waitCount = 0;
let resolve;
let reject;
const pr = new Promise((res, rej)=>(resolve = res, reject = rej));
setTimeout(checkPred, 0);
return pr;
function checkPred() {
$dc02ae1d9a800d1d$export$3f32c2013f0dcc1e.debugUntilTrue && console.log("Checking", pred);
if (pred()) return resolve(true);
else {
waitCount++;
if (waitCount < maxWaits) setTimeout(checkPred, waitOverride);
else if (typeof failCallback == "function") failCallback(reject);
}
}
}
async function $dc02ae1d9a800d1d$export$d9b57ae9ef5f7013(pred) {
return $dc02ae1d9a800d1d$export$e26007e3056af1f2(pred, 618, 432000); // wait for 3 days
}
async function $dc02ae1d9a800d1d$export$279fa041b1cf551d(pred, seconds) {
return $dc02ae1d9a800d1d$export$e26007e3056af1f2(pred, 1000, seconds, (reject)=>reject(`Checking predicate (${pred}) timed out after ${seconds} seconds.`));
}
function $dc02ae1d9a800d1d$export$e58ec57d99ec296(func, minGap, maxGap) {
if (minGap > maxGap) throw new TypeError(`minGap needs to be less than maxGap for function randomInterval`);
const controller = new AbortController();
const { signal: signal } = controller;
let timeoutIdClosure;
signal.addEventListener("abort", ()=>clearTimeout(timeoutIdClosure));
repeater();
return {
abort () {
controller.abort();
}
};
async function repeater() {
const nextWait = Math.ceil(minGap + Math.random() * (maxGap - minGap));
if (signal.aborted) return;
try {
await func();
} catch (e) {
console.warn(`Error when calling function at randomInterval. Error: ${e}\nFunction: ${func}`);
}
if (signal.aborted) return;
timeoutIdClosure = setTimeout(repeater, nextWait);
}
}
function $dc02ae1d9a800d1d$export$e7af819b5a294856(interval) {
if (typeof interval.abort == "function") interval.abort();
}
});
var $iT6R0 = parcelRequire("iT6R0");
// some services (audio and devtools) require the client to know their URL in order to connect.
// in the case of tor we can't calculate from ports as there are independent random addresses
// this function saves these to local storage for later so we don't always have to provide them
// in the url. It's expected that for a given main app onion address (hidden service) the
// audio and devtools addresses will remain as they are. In other words, all services in an
// instance will update their addresses in sync, whent he service as a whole is restarted.
// but for the duration of a single run, the addresses are consistent, and so local storage
// is a good way for the main service to store these other addresses against its own
$c7dd4e3d209193c8$var$saveTorParams();
function $c7dd4e3d209193c8$var$saveTorParams() {
const uri = new URL(location);
const zVal = uri.searchParams.get("z");
const token = uri.hash.slice(1);
if (!zVal && !token) // no tor params
return;
if (zVal) {
const z = JSON.parse(atob(decodeURIComponent(zVal)));
localStorage.setItem((0, $iT6R0.CONFIG).audioServiceFileName, z.x);
localStorage.setItem((0, $iT6R0.CONFIG).devtoolsServiceFileName, z.y);
if (!z.x || !z.y) console.warn(`Missing tor addresses for services`, z);
else {
// pre fetch to warm up cache in case they open it
const OPTS = {
method: "GET",
mode: "no-cors"
};
fetch(`${location.protocol}//${z.x}`, OPTS);
fetch(`${location.protocol}//${z.y}`, OPTS);
}
}
if (token) localStorage.setItem((0, $iT6R0.CONFIG).sessionTokenFileName, token);
}
//# sourceMappingURL=image.d6f6fc22.js.map