import { a as createVueComponent, _ as _export_sfc, c as createElementBlock, o as openBlock, s as createBlock, p as createCommentVNode, v as renderSlot, u as unref, q as normalizeClass, z as useDeviceStore, m as ref, r as reactive, b as onMounted, h as createVNode, f as createBaseVNode, w as withCtx, t as toDisplayString, i as createTextVNode, B as IconDevices, F as Fragment, g as renderList, d as axios, e as appUrl, n as onUpdated, j as withModifiers, x as withDirectives, y as vModelText, A as AuthCall, C as decryptAES, k as isLocal } from "./index-GNAKlyBz.js"; import { _ as _sfc_main$4, a as _sfc_main$5 } from "./DialogComp-Ba5-BUTe.js"; /** * @license @tabler/icons-vue v3.30.0 - MIT * * This source code is licensed under the MIT license. * See the LICENSE file in the root directory of this source tree. */ var IconAlertTriangle = createVueComponent("outline", "alert-triangle", "IconAlertTriangle", [["path", { "d": "M12 9v4", "key": "svg-0" }], ["path", { "d": "M10.363 3.591l-8.106 13.534a1.914 1.914 0 0 0 1.636 2.871h16.214a1.914 1.914 0 0 0 1.636 -2.87l-8.106 -13.536a1.914 1.914 0 0 0 -3.274 0z", "key": "svg-1" }], ["path", { "d": "M12 16h.01", "key": "svg-2" }]]); /** * @license @tabler/icons-vue v3.30.0 - MIT * * This source code is licensed under the MIT license. * See the LICENSE file in the root directory of this source tree. */ var IconCheck = createVueComponent("outline", "check", "IconCheck", [["path", { "d": "M5 12l5 5l10 -10", "key": "svg-0" }]]); /** * @license @tabler/icons-vue v3.30.0 - MIT * * This source code is licensed under the MIT license. * See the LICENSE file in the root directory of this source tree. */ var IconDeviceDesktop = createVueComponent("outline", "device-desktop", "IconDeviceDesktop", [["path", { "d": "M3 5a1 1 0 0 1 1 -1h16a1 1 0 0 1 1 1v10a1 1 0 0 1 -1 1h-16a1 1 0 0 1 -1 -1v-10z", "key": "svg-0" }], ["path", { "d": "M7 20h10", "key": "svg-1" }], ["path", { "d": "M9 16v4", "key": "svg-2" }], ["path", { "d": "M15 16v4", "key": "svg-3" }]]); /** * @license @tabler/icons-vue v3.30.0 - MIT * * This source code is licensed under the MIT license. * See the LICENSE file in the root directory of this source tree. */ var IconDeviceMobile = createVueComponent("outline", "device-mobile", "IconDeviceMobile", [["path", { "d": "M6 5a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2v-14z", "key": "svg-0" }], ["path", { "d": "M11 4h2", "key": "svg-1" }], ["path", { "d": "M12 17v.01", "key": "svg-2" }]]); /** * @license @tabler/icons-vue v3.30.0 - MIT * * This source code is licensed under the MIT license. * See the LICENSE file in the root directory of this source tree. */ var IconDeviceTablet = createVueComponent("outline", "device-tablet", "IconDeviceTablet", [["path", { "d": "M5 4a1 1 0 0 1 1 -1h12a1 1 0 0 1 1 1v16a1 1 0 0 1 -1 1h-12a1 1 0 0 1 -1 -1v-16z", "key": "svg-0" }], ["path", { "d": "M11 17a1 1 0 1 0 2 0a1 1 0 0 0 -2 0", "key": "svg-1" }]]); /** * @license @tabler/icons-vue v3.30.0 - MIT * * This source code is licensed under the MIT license. * See the LICENSE file in the root directory of this source tree. */ var IconDeviceUnknown = createVueComponent("outline", "device-unknown", "IconDeviceUnknown", [["path", { "d": "M5 5a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2z", "key": "svg-0" }], ["path", { "d": "M12 16v.01", "key": "svg-1" }], ["path", { "d": "M12 13a2 2 0 0 0 .914 -3.782a1.98 1.98 0 0 0 -2.414 .483", "key": "svg-2" }]]); /** * @license @tabler/icons-vue v3.30.0 - MIT * * This source code is licensed under the MIT license. * See the LICENSE file in the root directory of this source tree. */ var IconExclamationCircle = createVueComponent("outline", "exclamation-circle", "IconExclamationCircle", [["path", { "d": "M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0", "key": "svg-0" }], ["path", { "d": "M12 9v4", "key": "svg-1" }], ["path", { "d": "M12 16v.01", "key": "svg-2" }]]); /** * @license @tabler/icons-vue v3.30.0 - MIT * * This source code is licensed under the MIT license. * See the LICENSE file in the root directory of this source tree. */ var IconInfoCircle = createVueComponent("outline", "info-circle", "IconInfoCircle", [["path", { "d": "M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0", "key": "svg-0" }], ["path", { "d": "M12 9h.01", "key": "svg-1" }], ["path", { "d": "M11 12h1v4h1", "key": "svg-2" }]]); /** * @license @tabler/icons-vue v3.30.0 - MIT * * This source code is licensed under the MIT license. * See the LICENSE file in the root directory of this source tree. */ var IconKey = createVueComponent("outline", "key", "IconKey", [["path", { "d": "M16.555 3.843l3.602 3.602a2.877 2.877 0 0 1 0 4.069l-2.643 2.643a2.877 2.877 0 0 1 -4.069 0l-.301 -.301l-6.558 6.558a2 2 0 0 1 -1.239 .578l-.175 .008h-1.172a1 1 0 0 1 -.993 -.883l-.007 -.117v-1.172a2 2 0 0 1 .467 -1.284l.119 -.13l.414 -.414h2v-2h2v-2l2.144 -2.144l-.301 -.301a2.877 2.877 0 0 1 0 -4.069l2.643 -2.643a2.877 2.877 0 0 1 4.069 0z", "key": "svg-0" }], ["path", { "d": "M15 9h.01", "key": "svg-1" }]]); /** * @license @tabler/icons-vue v3.30.0 - MIT * * This source code is licensed under the MIT license. * See the LICENSE file in the root directory of this source tree. */ var IconLinkOff = createVueComponent("outline", "link-off", "IconLinkOff", [["path", { "d": "M9 15l3 -3m2 -2l1 -1", "key": "svg-0" }], ["path", { "d": "M11 6l.463 -.536a5 5 0 0 1 7.071 7.072l-.534 .464", "key": "svg-1" }], ["path", { "d": "M3 3l18 18", "key": "svg-2" }], ["path", { "d": "M13 18l-.397 .534a5.068 5.068 0 0 1 -7.127 0a4.972 4.972 0 0 1 0 -7.071l.524 -.463", "key": "svg-3" }]]); /** * @license @tabler/icons-vue v3.30.0 - MIT * * This source code is licensed under the MIT license. * See the LICENSE file in the root directory of this source tree. */ var IconLink = createVueComponent("outline", "link", "IconLink", [["path", { "d": "M9 15l6 -6", "key": "svg-0" }], ["path", { "d": "M11 6l.463 -.536a5 5 0 0 1 7.071 7.072l-.534 .464", "key": "svg-1" }], ["path", { "d": "M13 18l-.397 .534a5.068 5.068 0 0 1 -7.127 0a4.972 4.972 0 0 1 0 -7.071l.524 -.463", "key": "svg-2" }]]); /** * @license @tabler/icons-vue v3.30.0 - MIT * * This source code is licensed under the MIT license. * See the LICENSE file in the root directory of this source tree. */ var IconPlugConnectedX = createVueComponent("outline", "plug-connected-x", "IconPlugConnectedX", [["path", { "d": "M20 16l-4 4", "key": "svg-0" }], ["path", { "d": "M7 12l5 5l-1.5 1.5a3.536 3.536 0 1 1 -5 -5l1.5 -1.5z", "key": "svg-1" }], ["path", { "d": "M17 12l-5 -5l1.5 -1.5a3.536 3.536 0 1 1 5 5l-1.5 1.5z", "key": "svg-2" }], ["path", { "d": "M3 21l2.5 -2.5", "key": "svg-3" }], ["path", { "d": "M18.5 5.5l2.5 -2.5", "key": "svg-4" }], ["path", { "d": "M10 11l-2 2", "key": "svg-5" }], ["path", { "d": "M13 14l-2 2", "key": "svg-6" }], ["path", { "d": "M16 16l4 4", "key": "svg-7" }]]); /** * @license @tabler/icons-vue v3.30.0 - MIT * * This source code is licensed under the MIT license. * See the LICENSE file in the root directory of this source tree. */ var IconReload = createVueComponent("outline", "reload", "IconReload", [["path", { "d": "M19.933 13.041a8 8 0 1 1 -9.925 -8.788c3.899 -1 7.935 1.007 9.425 4.747", "key": "svg-0" }], ["path", { "d": "M20 4v5h-5", "key": "svg-1" }]]); /** * @license @tabler/icons-vue v3.30.0 - MIT * * This source code is licensed under the MIT license. * See the LICENSE file in the root directory of this source tree. */ var IconServer = createVueComponent("outline", "server", "IconServer", [["path", { "d": "M3 4m0 3a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3z", "key": "svg-0" }], ["path", { "d": "M3 12m0 3a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3z", "key": "svg-1" }], ["path", { "d": "M7 8l0 .01", "key": "svg-2" }], ["path", { "d": "M7 16l0 .01", "key": "svg-3" }]]); const _sfc_main$3 = { __name: "AlertComp", props: { type: String // info, success, warning, error }, setup(__props) { return (_ctx, _cache) => { return openBlock(), createElementBlock("div", { class: normalizeClass(`alert alert__${__props.type}`) }, [ __props.type === "info" ? (openBlock(), createBlock(unref(IconInfoCircle), { key: 0 })) : createCommentVNode("", true), __props.type === "success" ? (openBlock(), createBlock(unref(IconCheck), { key: 1 })) : createCommentVNode("", true), __props.type === "warning" ? (openBlock(), createBlock(unref(IconExclamationCircle), { key: 2 })) : createCommentVNode("", true), __props.type === "error" ? (openBlock(), createBlock(unref(IconAlertTriangle), { key: 3 })) : createCommentVNode("", true), renderSlot(_ctx.$slots, "default", {}, void 0, true) ], 2); }; } }; const AlertComp = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-87f6de25"]]); const _hoisted_1$2 = { class: "device-overview" }; const _hoisted_2$2 = { class: "grid" }; const _hoisted_3$2 = { class: "mcrm-block block__light flex flex-wrap items-start gap-4" }; const _hoisted_4$2 = { class: "w-full flex gap-4 items-center justify-between mb-4" }; const _hoisted_5$1 = { class: "flex gap-4" }; const _hoisted_6$1 = { class: "grid gap-2" }; const _hoisted_7$1 = { class: "grid grid-cols-[auto_1fr] gap-2" }; const _hoisted_8$1 = { class: "w-full truncate" }; const _hoisted_9 = { key: 1, class: "grid w-full gap-4" }; const _hoisted_10 = { class: "grid gap-4" }; const _hoisted_11 = { class: "text-4xl font-mono tracking-wide" }; const _sfc_main$2 = { __name: "ServerView", setup(__props) { const device = useDeviceStore(); const pinDialog = ref(); const remote = reactive({ devices: [], pinlink: false }); onMounted(() => { device.serverGetRemotes(); device.$subscribe((mutation, state) => { if (Object.keys(state.remote).length) remote.devices = device.remote; }); }); async function startLink(deviceUuid) { const pin = await device.serverStartLink(deviceUuid); remote.pinlink = { uuid: deviceUuid, pin }; pinDialog.value.toggleDialog(true); pollLink(); setTimeout(() => { resetPinLink(); }, 6e4); } function pollLink() { const pollInterval = setInterval(() => { axios.post(appUrl() + "/device/link/poll", { uuid: remote.pinlink.uuid }).then((data) => { if (!data.data) { clearInterval(pollInterval); resetPinLink(); device.serverGetRemotes(); } }); }, 1e3); } function resetPinLink() { remote.pinlink = false; if (pinDialog.value) pinDialog.value.toggleDialog(false); } function unlinkDevice(id) { axios.post(appUrl() + "/device/link/remove", { uuid: id }).then((data) => { if (data.data) device.serverGetRemotes(); }); } return (_ctx, _cache) => { return openBlock(), createElementBlock("div", _hoisted_1$2, [ createVNode(AlertComp, { type: "info" }, { default: withCtx(() => [ createBaseVNode("div", _hoisted_2$2, [ _cache[1] || (_cache[1] = createBaseVNode("strong", null, "This is a server!", -1)), createBaseVNode("em", null, "UUID: " + toDisplayString(unref(device).uuid()), 1) ]) ]), _: 1 }), createBaseVNode("div", _hoisted_3$2, [ createBaseVNode("h4", _hoisted_4$2, [ createBaseVNode("span", _hoisted_5$1, [ createVNode(unref(IconDevices)), _cache[2] || (_cache[2] = createTextVNode("Remote devices ")) ]), createVNode(_sfc_main$4, { variant: "primary", onClick: _cache[0] || (_cache[0] = ($event) => unref(device).serverGetRemotes()) }, { default: withCtx(() => [ createVNode(unref(IconReload)) ]), _: 1 }) ]), Object.keys(remote.devices).length > 0 ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(remote.devices, (remoteDevice, id) => { return openBlock(), createElementBlock("div", { class: "mcrm-block block__dark block-size__sm w-64 grid !gap-4 content-start", key: id }, [ createBaseVNode("div", _hoisted_6$1, [ createBaseVNode("h5", _hoisted_7$1, [ remoteDevice.settings.type == "unknown" ? (openBlock(), createBlock(unref(IconDeviceUnknown), { key: 0 })) : createCommentVNode("", true), remoteDevice.settings.type == "mobile" ? (openBlock(), createBlock(unref(IconDeviceMobile), { key: 1 })) : createCommentVNode("", true), remoteDevice.settings.type == "tablet" ? (openBlock(), createBlock(unref(IconDeviceTablet), { key: 2 })) : createCommentVNode("", true), remoteDevice.settings.type == "desktop" ? (openBlock(), createBlock(unref(IconDeviceDesktop), { key: 3 })) : createCommentVNode("", true), createBaseVNode("span", _hoisted_8$1, toDisplayString(remoteDevice.settings.name), 1) ]), createBaseVNode("em", null, toDisplayString(id), 1) ]), remoteDevice.key ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [ createVNode(AlertComp, { type: "success" }, { default: withCtx(() => _cache[3] || (_cache[3] = [ createTextVNode("Authorized") ])), _: 1 }), createVNode(_sfc_main$4, { variant: "danger", onClick: ($event) => unlinkDevice(id) }, { default: withCtx(() => [ createVNode(unref(IconLinkOff)), _cache[4] || (_cache[4] = createTextVNode("Unlink device ")) ]), _: 2 }, 1032, ["onClick"]) ], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [ createVNode(AlertComp, { type: "warning" }, { default: withCtx(() => _cache[5] || (_cache[5] = [ createTextVNode("Unauthorized") ])), _: 1 }), createVNode(_sfc_main$4, { variant: "primary", onClick: ($event) => startLink(id) }, { default: withCtx(() => [ createVNode(unref(IconLink)), _cache[6] || (_cache[6] = createTextVNode("Link device ")) ]), _: 2 }, 1032, ["onClick"]) ], 64)), remote.pinlink.uuid == id ? (openBlock(), createBlock(AlertComp, { key: 2, type: "info" }, { default: withCtx(() => [ createTextVNode("One time pin: " + toDisplayString(remote.pinlink.pin), 1) ]), _: 1 })) : createCommentVNode("", true) ]); }), 128)) : (openBlock(), createElementBlock("div", _hoisted_9, _cache[7] || (_cache[7] = [ createBaseVNode("em", { class: "text-slate-300" }, "No remote devices", -1) ]))), createVNode(_sfc_main$5, { ref_key: "pinDialog", ref: pinDialog }, { content: withCtx(() => [ createBaseVNode("div", _hoisted_10, [ _cache[8] || (_cache[8] = createBaseVNode("h3", null, "Pin code", -1)), createBaseVNode("span", _hoisted_11, toDisplayString(remote.pinlink.pin), 1) ]) ]), _: 1 }, 512) ]) ]); }; } }; const ServerView = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-f4165abd"]]); var Ni = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}; function Ci(E) { return E && E.__esModule && Object.prototype.hasOwnProperty.call(E, "default") ? E.default : E; } var wi = { exports: {} }; (function(E, q) { (function(A, m) { var F = "1.0.37", M = "", I = "?", R = "function", V = "undefined", ii = "object", j = "string", li = "major", e = "model", a = "name", i = "type", o = "vendor", t = "version", v = "architecture", B = "console", n = "mobile", b = "tablet", h = "smarttv", N = "wearable", ei = "embedded", oi = 500, G = "Amazon", D = "Apple", di = "ASUS", mi = "BlackBerry", T = "Browser", H = "Chrome", yi = "Edge", X = "Firefox", Y = "Google", ui = "Huawei", ai = "LG", ti = "Microsoft", pi = "Motorola", K = "Opera", Z = "Samsung", hi = "Sharp", J = "Sony", ri = "Xiaomi", si = "Zebra", fi = "Facebook", vi = "Chromium OS", gi = "Mac OS", Ti = function(c, l) { var s = {}; for (var d in c) l[d] && l[d].length % 2 === 0 ? s[d] = l[d].concat(c[d]) : s[d] = c[d]; return s; }, Q = function(c) { for (var l = {}, s = 0; s < c.length; s++) l[c[s].toUpperCase()] = c[s]; return l; }, Ei = function(c, l) { return typeof c === j ? U(l).indexOf(U(c)) !== -1 : false; }, U = function(c) { return c.toLowerCase(); }, _i = function(c) { return typeof c === j ? c.replace(/[^\d\.]/g, M).split(".")[0] : m; }, ni = function(c, l) { if (typeof c === j) return c = c.replace(/^\s\s*/, M), typeof l === V ? c : c.substring(0, oi); }, L = function(c, l) { for (var s = 0, d, y, O, w, r, k; s < l.length && !r; ) { var ci = l[s], xi = l[s + 1]; for (d = y = 0; d < ci.length && !r && ci[d]; ) if (r = ci[d++].exec(c), r) for (O = 0; O < xi.length; O++) k = r[++y], w = xi[O], typeof w === ii && w.length > 0 ? w.length === 2 ? typeof w[1] == R ? this[w[0]] = w[1].call(this, k) : this[w[0]] = w[1] : w.length === 3 ? typeof w[1] === R && !(w[1].exec && w[1].test) ? this[w[0]] = k ? w[1].call(this, k, w[2]) : m : this[w[0]] = k ? k.replace(w[1], w[2]) : m : w.length === 4 && (this[w[0]] = k ? w[3].call(this, k.replace(w[1], w[2])) : m) : this[w] = k || m; s += 2; } }, bi = function(c, l) { for (var s in l) if (typeof l[s] === ii && l[s].length > 0) { for (var d = 0; d < l[s].length; d++) if (Ei(l[s][d], c)) return s === I ? m : s; } else if (Ei(l[s], c)) return s === I ? m : s; return c; }, Mi = { "1.0": "/8", "1.2": "/1", "1.3": "/3", "2.0": "/412", "2.0.2": "/416", "2.0.3": "/417", "2.0.4": "/419", "?": "/" }, Oi = { ME: "4.90", "NT 3.11": "NT3.51", "NT 4.0": "NT4.0", 2e3: "NT 5.0", XP: ["NT 5.1", "NT 5.2"], Vista: "NT 6.0", 7: "NT 6.1", 8: "NT 6.2", "8.1": "NT 6.3", 10: ["NT 6.4", "NT 10.0"], RT: "ARM" }, ki = { browser: [ [ /\b(?:crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS ], [t, [a, "Chrome"]], [ /edg(?:e|ios|a)?\/([\w\.]+)/i // Microsoft Edge ], [t, [a, "Edge"]], [ // Presto based /(opera mini)\/([-\w\.]+)/i, // Opera Mini /(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i, // Opera Mobi/Tablet /(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i // Opera ], [a, t], [ /opios[\/ ]+([\w\.]+)/i // Opera mini on iphone >= 8.0 ], [t, [a, K + " Mini"]], [ /\bopr\/([\w\.]+)/i // Opera Webkit ], [t, [a, K]], [ // Mixed /\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i // Baidu ], [t, [a, "Baidu"]], [ /(kindle)\/([\w\.]+)/i, // Kindle /(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer // Trident based /(avant|iemobile|slim)\s?(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer // Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon /(flock|rockmelt|midori|epiphany|silk|skyfire|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|qq|duckduckgo)\/([-\w\.]+)/i, // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ /(heytap|ovi)browser\/([\d\.]+)/i, // Heytap/Ovi /(weibo)__([\d\.]+)/i // Weibo ], [a, t], [ /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser ], [t, [a, "UC" + T]], [ /microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser /\bqbcore\/([\w\.]+).+microm/i, /micromessenger\/([\w\.]+)/i // WeChat ], [t, [a, "WeChat"]], [ /konqueror\/([\w\.]+)/i // Konqueror ], [t, [a, "Konqueror"]], [ /trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i // IE11 ], [t, [a, "IE"]], [ /ya(?:search)?browser\/([\w\.]+)/i // Yandex ], [t, [a, "Yandex"]], [ /slbrowser\/([\w\.]+)/i // Smart Lenovo Browser ], [t, [a, "Smart Lenovo " + T]], [ /(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser ], [[a, /(.+)/, "$1 Secure " + T], t], [ /\bfocus\/([\w\.]+)/i // Firefox Focus ], [t, [a, X + " Focus"]], [ /\bopt\/([\w\.]+)/i // Opera Touch ], [t, [a, K + " Touch"]], [ /coc_coc\w+\/([\w\.]+)/i // Coc Coc Browser ], [t, [a, "Coc Coc"]], [ /dolfin\/([\w\.]+)/i // Dolphin ], [t, [a, "Dolphin"]], [ /coast\/([\w\.]+)/i // Opera Coast ], [t, [a, K + " Coast"]], [ /miuibrowser\/([\w\.]+)/i // MIUI Browser ], [t, [a, "MIUI " + T]], [ /fxios\/([-\w\.]+)/i // Firefox for iOS ], [t, [a, X]], [ /\bqihu|(qi?ho?o?|360)browser/i // 360 ], [[a, "360 " + T]], [ /(oculus|sailfish|huawei|vivo)browser\/([\w\.]+)/i ], [[a, /(.+)/, "$1 " + T], t], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser /samsungbrowser\/([\w\.]+)/i // Samsung Internet ], [t, [a, Z + " Internet"]], [ /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon ], [[a, /_/g, " "], t], [ /metasr[\/ ]?([\d\.]+)/i // Sogou Explorer ], [t, [a, "Sogou Explorer"]], [ /(sogou)mo\w+\/([\d\.]+)/i // Sogou Mobile ], [[a, "Sogou Mobile"], t], [ /(electron)\/([\w\.]+) safari/i, // Electron-based App /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla /m?(qqbrowser|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/2345 Browser ], [a, t], [ /(lbbrowser)/i, // LieBao Browser /\[(linkedin)app\]/i // LinkedIn App for iOS & Android ], [a], [ // WebView /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android ], [[a, fi], t], [ /(Klarna)\/([\w\.]+)/i, // Klarna Shopping Browser for iOS & Android /(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App /(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp /safari (line)\/([\w\.]+)/i, // Line App for iOS /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android /(alipay)client\/([\w\.]+)/i, // Alipay /(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i // Chromium/Instagram/Snapchat ], [a, t], [ /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS ], [t, [a, "GSA"]], [ /musical_ly(?:.+app_?version\/|_)([\w\.]+)/i // TikTok ], [t, [a, "TikTok"]], [ /headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless ], [t, [a, H + " Headless"]], [ / wv\).+(chrome)\/([\w\.]+)/i // Chrome WebView ], [[a, H + " WebView"], t], [ /droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser ], [t, [a, "Android " + T]], [ /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia ], [a, t], [ /version\/([\w\.\,]+) .*mobile\/\w+ (safari)/i // Mobile Safari ], [t, [a, "Mobile Safari"]], [ /version\/([\w(\.|\,)]+) .*(mobile ?safari|safari)/i // Safari & Safari Mobile ], [t, a], [ /webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i // Safari < 3.0 ], [a, [t, bi, Mi]], [ /(webkit|khtml)\/([\w\.]+)/i ], [a, t], [ // Gecko based /(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape ], [[a, "Netscape"], t], [ /mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality ], [t, [a, X + " Reality"]], [ /ekiohf.+(flow)\/([\w\.]+)/i, // Flow /(swiftfox)/i, // Swiftfox /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\/ ]?([\w\.\+]+)/i, // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror/Klar /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i, // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix /(firefox)\/([\w\.]+)/i, // Other Firefox-based /(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i, // Mozilla // Other /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i, // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir/Obigo/Mosaic/Go/ICE/UP.Browser /(links) \(([\w\.]+)/i, // Links /panasonic;(viera)/i // Panasonic Viera ], [a, t], [ /(cobalt)\/([\w\.]+)/i // Cobalt ], [a, [t, /master.|lts./, ""]] ], cpu: [ [ /(?:(amd|x(?:(?:86|64)[-_])?|wow|win)64)[;\)]/i // AMD64 (x64) ], [[v, "amd64"]], [ /(ia32(?=;))/i // IA32 (quicktime) ], [[v, U]], [ /((?:i[346]|x)86)[;\)]/i // IA32 (x86) ], [[v, "ia32"]], [ /\b(aarch64|arm(v?8e?l?|_?64))\b/i // ARM64 ], [[v, "arm64"]], [ /\b(arm(?:v[67])?ht?n?[fl]p?)\b/i // ARMHF ], [[v, "armhf"]], [ // PocketPC mistakenly identified as PowerPC /windows (ce|mobile); ppc;/i ], [[v, "arm"]], [ /((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i // PowerPC ], [[v, /ower/, M, U]], [ /(sun4\w)[;\)]/i // SPARC ], [[v, "sparc"]], [ /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?=v(?:[1-7]|[5-7]1)l?|;|eabi)|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC ], [[v, U]] ], device: [ [ ////////////////////////// // MOBILES & TABLETS ///////////////////////// // Samsung /\b(sch-i[89]0\d|shw-m380s|sm-[ptx]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i ], [e, [o, Z], [i, b]], [ /\b((?:s[cgp]h|gt|sm)-\w+|sc[g-]?[\d]+a?|galaxy nexus)/i, /samsung[- ]([-\w]+)/i, /sec-(sgh\w+)/i ], [e, [o, Z], [i, n]], [ // Apple /(?:\/|\()(ip(?:hone|od)[\w, ]*)(?:\/|;)/i // iPod/iPhone ], [e, [o, D], [i, n]], [ /\((ipad);[-\w\),; ]+apple/i, // iPad /applecoremedia\/[\w\.]+ \((ipad)/i, /\b(ipad)\d\d?,\d\d?[;\]].+ios/i ], [e, [o, D], [i, b]], [ /(macintosh);/i ], [e, [o, D]], [ // Sharp /\b(sh-?[altvz]?\d\d[a-ekm]?)/i ], [e, [o, hi], [i, n]], [ // Huawei /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i ], [e, [o, ui], [i, b]], [ /(?:huawei|honor)([-\w ]+)[;\)]/i, /\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i ], [e, [o, ui], [i, n]], [ // Xiaomi /\b(poco[\w ]+|m2\d{3}j\d\d[a-z]{2})(?: bui|\))/i, // Xiaomi POCO /\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi /\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi /oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i, // Xiaomi Redmi 'numeric' models /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi ], [[e, /_/g, " "], [o, ri], [i, n]], [ /oid[^\)]+; (2\d{4}(283|rpbf)[cgl])( bui|\))/i, // Redmi Pad /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets ], [[e, /_/g, " "], [o, ri], [i, b]], [ // OPPO /; (\w+) bui.+ oppo/i, /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i ], [e, [o, "OPPO"], [i, n]], [ // Vivo /vivo (\w+)(?: bui|\))/i, /\b(v[12]\d{3}\w?[at])(?: bui|;)/i ], [e, [o, "Vivo"], [i, n]], [ // Realme /\b(rmx[1-3]\d{3})(?: bui|;|\))/i ], [e, [o, "Realme"], [i, n]], [ // Motorola /\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i, /\bmot(?:orola)?[- ](\w*)/i, /((?:moto[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i ], [e, [o, pi], [i, n]], [ /\b(mz60\d|xoom[2 ]{0,2}) build\//i ], [e, [o, pi], [i, b]], [ // LG /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i ], [e, [o, ai], [i, b]], [ /(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i, /\blg[-e;\/ ]+((?!browser|netcast|android tv)\w+)/i, /\blg-?([\d\w]+) bui/i ], [e, [o, ai], [i, n]], [ // Lenovo /(ideatab[-\w ]+)/i, /lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i ], [e, [o, "Lenovo"], [i, b]], [ // Nokia /(?:maemo|nokia).*(n900|lumia \d+)/i, /nokia[-_ ]?([-\w\.]*)/i ], [[e, /_/g, " "], [o, "Nokia"], [i, n]], [ // Google /(pixel c)\b/i // Google Pixel C ], [e, [o, Y], [i, b]], [ /droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i // Google Pixel ], [e, [o, Y], [i, n]], [ // Sony /droid.+ (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i ], [e, [o, J], [i, n]], [ /sony tablet [ps]/i, /\b(?:sony)?sgp\w+(?: bui|\))/i ], [[e, "Xperia Tablet"], [o, J], [i, b]], [ // OnePlus / (kb2005|in20[12]5|be20[12][59])\b/i, /(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i ], [e, [o, "OnePlus"], [i, n]], [ // Amazon /(alexa)webm/i, /(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\))/i, // Kindle Fire without Silk / Echo Show /(kf[a-z]+)( bui|\)).+silk\//i // Kindle Fire HD ], [e, [o, G], [i, b]], [ /((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i // Fire Phone ], [[e, /(.+)/g, "Fire Phone $1"], [o, G], [i, n]], [ // BlackBerry /(playbook);[-\w\),; ]+(rim)/i // BlackBerry PlayBook ], [e, o, [i, b]], [ /\b((?:bb[a-f]|st[hv])100-\d)/i, /\(bb10; (\w+)/i // BlackBerry 10 ], [e, [o, mi], [i, n]], [ // Asus /(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i ], [e, [o, di], [i, b]], [ / (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i ], [e, [o, di], [i, n]], [ // HTC /(nexus 9)/i // HTC Nexus 9 ], [e, [o, "HTC"], [i, b]], [ /(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i, // HTC // ZTE /(zte)[- ]([\w ]+?)(?: bui|\/|\))/i, /(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony ], [o, [e, /_/g, " "], [i, n]], [ // Acer /droid.+; ([ab][1-7]-?[0178a]\d\d?)/i ], [e, [o, "Acer"], [i, b]], [ // Meizu /droid.+; (m[1-5] note) bui/i, /\bmz-([-\w]{2,})/i ], [e, [o, "Meizu"], [i, n]], [ // Ulefone /; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i ], [e, [o, "Ulefone"], [i, n]], [ // MIXED /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno)[-_ ]?([-\w]*)/i, // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron /(hp) ([\w ]+\w)/i, // HP iPAQ /(asus)-?(\w+)/i, // Asus /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia /(lenovo)[-_ ]?([-\w]+)/i, // Lenovo /(jolla)/i, // Jolla /(oppo) ?([\w ]+) bui/i // OPPO ], [o, e, [i, n]], [ /(kobo)\s(ereader|touch)/i, // Kobo /(archos) (gamepad2?)/i, // Archos /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad /(kindle)\/([\w\.]+)/i, // Kindle /(nook)[\w ]+build\/(\w+)/i, // Nook /(dell) (strea[kpr\d ]*[\dko])/i, // Dell Streak /(le[- ]+pan)[- ]+(\w{1,9}) bui/i, // Le Pan Tablets /(trinity)[- ]*(t\d{3}) bui/i, // Trinity Tablets /(gigaset)[- ]+(q\w{1,9}) bui/i, // Gigaset Tablets /(vodafone) ([\w ]+)(?:\)| bui)/i // Vodafone ], [o, e, [i, b]], [ /(surface duo)/i // Surface Duo ], [e, [o, ti], [i, b]], [ /droid [\d\.]+; (fp\du?)(?: b|\))/i // Fairphone ], [e, [o, "Fairphone"], [i, n]], [ /(u304aa)/i // AT&T ], [e, [o, "AT&T"], [i, n]], [ /\bsie-(\w*)/i // Siemens ], [e, [o, "Siemens"], [i, n]], [ /\b(rct\w+) b/i // RCA Tablets ], [e, [o, "RCA"], [i, b]], [ /\b(venue[\d ]{2,7}) b/i // Dell Venue Tablets ], [e, [o, "Dell"], [i, b]], [ /\b(q(?:mv|ta)\w+) b/i // Verizon Tablet ], [e, [o, "Verizon"], [i, b]], [ /\b(?:barnes[& ]+noble |bn[rt])([\w\+ ]*) b/i // Barnes & Noble Tablet ], [e, [o, "Barnes & Noble"], [i, b]], [ /\b(tm\d{3}\w+) b/i ], [e, [o, "NuVision"], [i, b]], [ /\b(k88) b/i // ZTE K Series Tablet ], [e, [o, "ZTE"], [i, b]], [ /\b(nx\d{3}j) b/i // ZTE Nubia ], [e, [o, "ZTE"], [i, n]], [ /\b(gen\d{3}) b.+49h/i // Swiss GEN Mobile ], [e, [o, "Swiss"], [i, n]], [ /\b(zur\d{3}) b/i // Swiss ZUR Tablet ], [e, [o, "Swiss"], [i, b]], [ /\b((zeki)?tb.*\b) b/i // Zeki Tablets ], [e, [o, "Zeki"], [i, b]], [ /\b([yr]\d{2}) b/i, /\b(dragon[- ]+touch |dt)(\w{5}) b/i // Dragon Touch Tablet ], [[o, "Dragon Touch"], e, [i, b]], [ /\b(ns-?\w{0,9}) b/i // Insignia Tablets ], [e, [o, "Insignia"], [i, b]], [ /\b((nxa|next)-?\w{0,9}) b/i // NextBook Tablets ], [e, [o, "NextBook"], [i, b]], [ /\b(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i // Voice Xtreme Phones ], [[o, "Voice"], e, [i, n]], [ /\b(lvtel\-)?(v1[12]) b/i // LvTel Phones ], [[o, "LvTel"], e, [i, n]], [ /\b(ph-1) /i // Essential PH-1 ], [e, [o, "Essential"], [i, n]], [ /\b(v(100md|700na|7011|917g).*\b) b/i // Envizen Tablets ], [e, [o, "Envizen"], [i, b]], [ /\b(trio[-\w\. ]+) b/i // MachSpeed Tablets ], [e, [o, "MachSpeed"], [i, b]], [ /\btu_(1491) b/i // Rotor Tablets ], [e, [o, "Rotor"], [i, b]], [ /(shield[\w ]+) b/i // Nvidia Shield Tablets ], [e, [o, "Nvidia"], [i, b]], [ /(sprint) (\w+)/i // Sprint Phones ], [o, e, [i, n]], [ /(kin\.[onetw]{3})/i // Microsoft Kin ], [[e, /\./g, " "], [o, ti], [i, n]], [ /droid.+; (cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i // Zebra ], [e, [o, si], [i, b]], [ /droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i ], [e, [o, si], [i, n]], [ /////////////////// // SMARTTVS /////////////////// /smart-tv.+(samsung)/i // Samsung ], [o, [i, h]], [ /hbbtv.+maple;(\d+)/i ], [[e, /^/, "SmartTV"], [o, Z], [i, h]], [ /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i // LG SmartTV ], [[o, ai], [i, h]], [ /(apple) ?tv/i // Apple TV ], [o, [e, D + " TV"], [i, h]], [ /crkey/i // Google Chromecast ], [[e, H + "cast"], [o, Y], [i, h]], [ /droid.+aft(\w+)( bui|\))/i // Fire TV ], [e, [o, G], [i, h]], [ /\(dtv[\);].+(aquos)/i, /(aquos-tv[\w ]+)\)/i // Sharp ], [e, [o, hi], [i, h]], [ /(bravia[\w ]+)( bui|\))/i // Sony ], [e, [o, J], [i, h]], [ /(mitv-\w{5}) bui/i // Xiaomi ], [e, [o, ri], [i, h]], [ /Hbbtv.*(technisat) (.*);/i // TechniSAT ], [o, e, [i, h]], [ /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku /hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i // HbbTV devices ], [[o, ni], [e, ni], [i, h]], [ /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i // SmartTV from Unidentified Vendors ], [[i, h]], [ /////////////////// // CONSOLES /////////////////// /(ouya)/i, // Ouya /(nintendo) ([wids3utch]+)/i // Nintendo ], [o, e, [i, B]], [ /droid.+; (shield) bui/i // Nvidia ], [e, [o, "Nvidia"], [i, B]], [ /(playstation [345portablevi]+)/i // Playstation ], [e, [o, J], [i, B]], [ /\b(xbox(?: one)?(?!; xbox))[\); ]/i // Microsoft Xbox ], [e, [o, ti], [i, B]], [ /////////////////// // WEARABLES /////////////////// /((pebble))app/i // Pebble ], [o, e, [i, N]], [ /(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i // Apple Watch ], [e, [o, D], [i, N]], [ /droid.+; (glass) \d/i // Google Glass ], [e, [o, Y], [i, N]], [ /droid.+; (wt63?0{2,3})\)/i ], [e, [o, si], [i, N]], [ /(quest( 2| pro)?)/i // Oculus Quest ], [e, [o, fi], [i, N]], [ /////////////////// // EMBEDDED /////////////////// /(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i // Tesla ], [o, [i, ei]], [ /(aeobc)\b/i // Echo Dot ], [e, [o, G], [i, ei]], [ //////////////////// // MIXED (GENERIC) /////////////////// /droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors ], [e, [i, n]], [ /droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors ], [e, [i, b]], [ /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i // Unidentifiable Tablet ], [[i, b]], [ /(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile ], [[i, n]], [ /(android[-\w\. ]{0,9});.+buil/i // Generic Android Device ], [e, [o, "Generic"]] ], engine: [ [ /windows.+ edge\/([\w\.]+)/i // EdgeHTML ], [t, [a, yi + "HTML"]], [ /webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i // Blink ], [t, [a, "Blink"]], [ /(presto)\/([\w\.]+)/i, // Presto /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna /ekioh(flow)\/([\w\.]+)/i, // Flow /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links /(icab)[\/ ]([23]\.[\d\.]+)/i, // iCab /\b(libweb)/i ], [a, t], [ /rv\:([\w\.]{1,9})\b.+(gecko)/i // Gecko ], [t, a] ], os: [ [ // Windows /microsoft (windows) (vista|xp)/i // Windows (iTunes) ], [a, t], [ /(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i // Windows Phone ], [a, [t, bi, Oi]], [ /windows nt 6\.2; (arm)/i, // Windows RT /windows[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i, /(?:win(?=3|9|n)|win 9x )([nt\d\.]+)/i ], [[t, bi, Oi], [a, "Windows"]], [ // iOS/macOS /ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS /(?:ios;fbsv\/|iphone.+ios[\/ ])([\d\.]+)/i, /cfnetwork\/.+darwin/i ], [[t, /_/g, "."], [a, "iOS"]], [ /(mac os x) ?([\w\. ]*)/i, /(macintosh|mac_powerpc\b)(?!.+haiku)/i // Mac OS ], [[a, gi], [t, /_/g, "."]], [ // Mobile OSes /droid ([\w\.]+)\b.+(android[- ]x86|harmonyos)/i // Android-x86/HarmonyOS ], [t, a], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\/ ]?([\w\.]*)/i, /(blackberry)\w*\/([\w\.]*)/i, // Blackberry /(tizen|kaios)[\/ ]([\w\.]+)/i, // Tizen/KaiOS /\((series40);/i // Series 40 ], [a, t], [ /\(bb(10);/i // BlackBerry 10 ], [t, [a, mi]], [ /(?:symbian ?os|symbos|s60(?=;)|series60)[-\/ ]?([\w\.]*)/i // Symbian ], [t, [a, "Symbian"]], [ /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i // Firefox OS ], [t, [a, X + " OS"]], [ /web0s;.+rt(tv)/i, /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i // WebOS ], [t, [a, "webOS"]], [ /watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i // watchOS ], [t, [a, "watchOS"]], [ // Google Chromecast /crkey\/([\d\.]+)/i // Google Chromecast ], [t, [a, H + "cast"]], [ /(cros) [\w]+(?:\)| ([\w\.]+)\b)/i // Chromium OS ], [[a, vi], t], [ // Smart TVs /panasonic;(viera)/i, // Panasonic Viera /(netrange)mmh/i, // Netrange /(nettv)\/(\d+\.[\w\.]+)/i, // NetTV // Console /(nintendo|playstation) ([wids345portablevuch]+)/i, // Nintendo/Playstation /(xbox); +xbox ([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S) // Other /\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i, // Joli/Palm /(mint)[\/\(\) ]?(\w*)/i, // Mint /(mageia|vectorlinux)[; ]/i, // Mageia/VectorLinux /([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire)(?: gnu\/linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i, // Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki/Deepin/Manjaro/elementary/Sabayon/Linspire /(hurd|linux) ?([\w\.]*)/i, // Hurd/Linux /(gnu) ?([\w\.]*)/i, // GNU /\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly /(haiku) (\w+)/i // Haiku ], [a, t], [ /(sunos) ?([\w\.\d]*)/i // Solaris ], [[a, "Solaris"], t], [ /((?:open)?solaris)[-\/ ]?([\w\.]*)/i, // Solaris /(aix) ((\d)(?=\.|\)| )[\w\.])*/i, // AIX /\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux|serenityos)/i, // BeOS/OS2/AmigaOS/MorphOS/OpenVMS/Fuchsia/HP-UX/SerenityOS /(unix) ?([\w\.]*)/i // UNIX ], [a, t] ] }, g = function(c, l) { if (typeof c === ii && (l = c, c = m), !(this instanceof g)) return new g(c, l).getResult(); var s = typeof A !== V && A.navigator ? A.navigator : m, d = c || (s && s.userAgent ? s.userAgent : M), y = s && s.userAgentData ? s.userAgentData : m, O = l ? Ti(ki, l) : ki, w = s && s.userAgent == d; return this.getBrowser = function() { var r = {}; return r[a] = m, r[t] = m, L.call(r, d, O.browser), r[li] = _i(r[t]), w && s && s.brave && typeof s.brave.isBrave == R && (r[a] = "Brave"), r; }, this.getCPU = function() { var r = {}; return r[v] = m, L.call(r, d, O.cpu), r; }, this.getDevice = function() { var r = {}; return r[o] = m, r[e] = m, r[i] = m, L.call(r, d, O.device), w && !r[i] && y && y.mobile && (r[i] = n), w && r[e] == "Macintosh" && s && typeof s.standalone !== V && s.maxTouchPoints && s.maxTouchPoints > 2 && (r[e] = "iPad", r[i] = b), r; }, this.getEngine = function() { var r = {}; return r[a] = m, r[t] = m, L.call(r, d, O.engine), r; }, this.getOS = function() { var r = {}; return r[a] = m, r[t] = m, L.call(r, d, O.os), w && !r[a] && y && y.platform != "Unknown" && (r[a] = y.platform.replace(/chrome os/i, vi).replace(/macos/i, gi)), r; }, this.getResult = function() { return { ua: this.getUA(), browser: this.getBrowser(), engine: this.getEngine(), os: this.getOS(), device: this.getDevice(), cpu: this.getCPU() }; }, this.getUA = function() { return d; }, this.setUA = function(r) { return d = typeof r === j && r.length > oi ? ni(r, oi) : r, this; }, this.setUA(d), this; }; g.VERSION = F, g.BROWSER = Q([a, t, li]), g.CPU = Q([v]), g.DEVICE = Q([e, o, i, B, n, h, b, N, ei]), g.ENGINE = g.OS = Q([a, t]), E.exports && (q = E.exports = g), q.UAParser = g; var C = typeof A !== V && (A.jQuery || A.Zepto); if (C && !C.ua) { var $ = new g(); C.ua = $.getResult(), C.ua.get = function() { return $.getUA(); }, C.ua.set = function(c) { $.setUA(c); var l = $.getResult(); for (var s in l) C.ua[s] = l[s]; }; } })(typeof window == "object" ? window : Ni); })(wi, wi.exports); var Pi = wi.exports; const Bi = /* @__PURE__ */ Ci(Pi), S = { CONSOLE: "console", DESKTOP: void 0, EMBEDDED: "embedded", MOBILE: "mobile", SMART_TV: "smarttv", TABLET: "tablet", WEARABLE: "wearable" }, _ = { ANDROID: "Android", IOS: "iOS", LINUX: "Linux", MAC_OS: "Mac OS", WINDOWS_PHONE: "Windows Phone", WINDOWS: "Windows" }, p = { CHROME: "Chrome", CHROMIUM: "Chromium", EDGE: "Edge", FIREFOX: "Firefox", IE: "IE", INTERNET_EXPLORER: "Internet Explorer", MIUI: "MIUI Browser", MOBILE_SAFARI: "Mobile Safari", OPERA: "Opera", SAFARI: "Safari", SAMSUNG_BROWSER: "Samsung Browser", YANDEX: "Yandex" }, z = new Bi(), f = z.getDevice(), x = z.getOS(), u = z.getBrowser(); z.getEngine(); const P = z.getUA(), W = () => /iPad/.test(P), Ai = () => x.name === _.WINDOWS && x.version === "10" && P.indexOf("Edg/") !== -1; x.name === _.ANDROID; u.name === p.CHROME; u.name === p.CHROMIUM; f.type === S.CONSOLE; f.type === S.DESKTOP; u.name === p.EDGE || Ai(); Ai(); u.name === p.EDGE; /electron/.test(P.toLowerCase()); f.type === S.EMBEDDED; u.name === p.FIREFOX; u.name === p.INTERNET_EXPLORER || u.name === p.IE; x.name === _.IOS || W(); x.name === _.LINUX; x.name === _.MAC_OS; u.name === p.MIUI; f.type === S.MOBILE || f.type === S.TABLET || W(); f.type === S.MOBILE; u.name === p.MOBILE_SAFARI || W(); u.name === p.OPERA; u.name === p.SAFARI || u.name === p.MOBILE_SAFARI; u.name === p.SAMSUNG_BROWSER; f.type === S.SMART_TV; f.type === S.TABLET || W(); f.type === S.WEARABLE; x.name === _.WINDOWS; x.name === _.WINDOWS_PHONE; u.name === p.YANDEX; const fe = () => f.model, ve = () => f.type || "desktop", ge = () => f.vendor; const _hoisted_1$1 = { class: "server-overview" }; const _hoisted_2$1 = { class: "grid" }; const _hoisted_3$1 = { class: "mcrm-block block__light grid gap-4" }; const _hoisted_4$1 = { class: "text-lg flex gap-4 items-center justify-between" }; const _hoisted_5 = { class: "flex gap-4" }; const _hoisted_6 = { class: "grid gap-2" }; const _hoisted_7 = { key: 0, class: "grid grid-cols-[2rem_1fr] gap-2" }; const _hoisted_8 = { class: "grid gap-4 w-64" }; const _sfc_main$1 = { __name: "RemoteView", setup(__props) { const device = useDeviceStore(); const linkPinDialog = ref(); const server = reactive({ host: "", status: false, link: false, inputPin: "", encryptedKey: "", key: "" }); onMounted(async () => { server.host = window.location.host; }); onUpdated(() => { if (!server.status) checkServerStatus(); }); async function checkServerStatus(request = true) { const status = await device.remoteCheckServerAccess(); server.status = status; if (status === "unlinked" || status === "unauthorized") { if (request) requestAccess(); return true; } if (!device.key()) { server.status = "unauthorized"; return true; } const handshake = await device.remoteHandshake(device.key()); if (handshake) server.key = device.key(); else { device.removeDeviceKey(); server.status = "unlinked"; if (request) requestAccess(); } return true; } function requestAccess() { let deviceName = `${ge() ? ge() : "Unknown"} ${ge() ? fe() : ve()}`; device.remoteRequestServerAccess(deviceName, ve()).then((data) => { if (data.data) server.status = data.data, pingLink(); }); } function pingLink() { server.link = "checking"; device.remotePingLink((encryptedKey) => { server.link = true; server.encryptedKey = encryptedKey; linkPinDialog.value.toggleDialog(true); }); } async function decryptKey() { const decryptedKey = decryptAES(server.inputPin, server.encryptedKey); const handshake = await device.remoteHandshake(decryptedKey); if (handshake) { device.setDeviceKey(decryptedKey); server.key = decryptedKey; linkPinDialog.value.toggleDialog(false); server.status = "authorized"; } } function disonnectFromServer() { axios.post(appUrl() + "/device/link/remove", AuthCall({ uuid: device.uuid() })).then((data) => { if (data.data) checkServerStatus(false); }); } return (_ctx, _cache) => { return openBlock(), createElementBlock("div", _hoisted_1$1, [ createVNode(AlertComp, { type: "info" }, { default: withCtx(() => [ createBaseVNode("div", _hoisted_2$1, [ _cache[6] || (_cache[6] = createBaseVNode("strong", null, "This is a remote device.", -1)), createBaseVNode("em", null, "UUID: " + toDisplayString(unref(device).uuid()), 1) ]) ]), _: 1 }), createBaseVNode("div", _hoisted_3$1, [ createBaseVNode("h4", _hoisted_4$1, [ createBaseVNode("span", _hoisted_5, [ createVNode(unref(IconServer)), _cache[7] || (_cache[7] = createTextVNode("Server")) ]), createVNode(_sfc_main$4, { variant: "primary", onClick: _cache[0] || (_cache[0] = ($event) => checkServerStatus()) }, { default: withCtx(() => [ createVNode(unref(IconReload)) ]), _: 1 }) ]), createBaseVNode("p", null, [ _cache[8] || (_cache[8] = createTextVNode(" Connected to: ")), createBaseVNode("strong", null, toDisplayString(server.host), 1) ]), server.status === "authorized" ? (openBlock(), createBlock(AlertComp, { key: 0, type: "success" }, { default: withCtx(() => _cache[9] || (_cache[9] = [ createTextVNode("Authorized") ])), _: 1 })) : createCommentVNode("", true), server.status === "unlinked" ? (openBlock(), createBlock(AlertComp, { key: 1, type: "warning" }, { default: withCtx(() => _cache[10] || (_cache[10] = [ createTextVNode("Not linked") ])), _: 1 })) : createCommentVNode("", true), server.status === "unauthorized" ? (openBlock(), createBlock(AlertComp, { key: 2, type: "info" }, { default: withCtx(() => [ createBaseVNode("div", _hoisted_6, [ _cache[13] || (_cache[13] = createBaseVNode("strong", null, "Access requested", -1)), _cache[14] || (_cache[14] = createBaseVNode("p", null, [ createTextVNode(" Navigate to "), createBaseVNode("em", { class: "font-semibold" }, "http://localhost:6970/devices"), createTextVNode(" on your pc to authorize. ") ], -1)), server.link == "checking" ? (openBlock(), createElementBlock("div", _hoisted_7, [ createVNode(unref(IconReload), { class: "animate-spin" }), _cache[11] || (_cache[11] = createTextVNode(" Checking server for link... ")) ])) : createCommentVNode("", true), server.link === false ? (openBlock(), createBlock(_sfc_main$4, { key: 1, variant: "subtle", onClick: _cache[1] || (_cache[1] = ($event) => pingLink()), class: "w-fit" }, { default: withCtx(() => [ createVNode(unref(IconReload)), _cache[12] || (_cache[12] = createTextVNode("Check for server link ")) ]), _: 1 })) : createCommentVNode("", true) ]) ]), _: 1 })) : createCommentVNode("", true), server.status === "unauthorized" ? (openBlock(), createBlock(_sfc_main$4, { key: 3, variant: "primary", onClick: _cache[2] || (_cache[2] = ($event) => requestAccess()) }, { default: withCtx(() => [ createVNode(unref(IconKey)), _cache[15] || (_cache[15] = createTextVNode(" Request access ")) ]), _: 1 })) : createCommentVNode("", true), server.status === "authorized" ? (openBlock(), createBlock(_sfc_main$4, { key: 4, variant: "danger", onClick: _cache[3] || (_cache[3] = ($event) => disonnectFromServer()) }, { default: withCtx(() => [ createVNode(unref(IconPlugConnectedX)), _cache[16] || (_cache[16] = createTextVNode(" Disconnect ")) ]), _: 1 })) : createCommentVNode("", true) ]), createVNode(_sfc_main$5, { ref_key: "linkPinDialog", ref: linkPinDialog }, { content: withCtx(() => [ createBaseVNode("div", _hoisted_8, [ _cache[18] || (_cache[18] = createBaseVNode("h3", null, "Server link pin:", -1)), createBaseVNode("form", { class: "grid gap-4", onSubmit: _cache[5] || (_cache[5] = withModifiers(($event) => decryptKey(), ["prevent"])) }, [ withDirectives(createBaseVNode("input", { class: "input", id: "input-pin", type: "text", pattern: "[0-9]{4}", "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => server.inputPin = $event) }, null, 512), [ [vModelText, server.inputPin] ]), createVNode(_sfc_main$4, { variant: "primary" }, { default: withCtx(() => _cache[17] || (_cache[17] = [ createTextVNode("Enter") ])), _: 1 }) ], 32) ]) ]), _: 1 }, 512) ]); }; } }; const RemoteView = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-3109048f"]]); const _hoisted_1 = { id: "devices-view", class: "panel" }; const _hoisted_2 = { class: "panel__title" }; const _hoisted_3 = { class: "text-sm" }; const _hoisted_4 = { class: "panel__content grid gap-8" }; const _sfc_main = { __name: "DevicesView", setup(__props) { return (_ctx, _cache) => { return openBlock(), createElementBlock("div", _hoisted_1, [ createBaseVNode("h1", _hoisted_2, [ _cache[0] || (_cache[0] = createTextVNode(" Devices ")), createBaseVNode("span", _hoisted_3, toDisplayString(unref(isLocal)() ? "remote" : "servers"), 1) ]), createBaseVNode("div", _hoisted_4, [ unref(isLocal)() ? (openBlock(), createBlock(ServerView, { key: 0 })) : (openBlock(), createBlock(RemoteView, { key: 1 })) ]) ]); }; } }; const DevicesView = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-97929e31"]]); export { DevicesView as default };