{"version":3,"file":"index.cjs","sources":["../../src/browser/copyToClipboard.js","../../src/browser/getBrowser.js","../../src/browser/safeLocalStorage.js","../../src/browser/index.js","../../src/browser/safeLocalStorageSimple.js"],"sourcesContent":["const isCopyToClipboardSupported = function () {\n    const flag = (\n        typeof navigator === 'object' &&\n        navigator &&\n        navigator.clipboard &&\n        typeof navigator.clipboard.writeText === 'function'\n    );\n\n    return !!flag;\n};\n\nconst copyToClipboard = async function (simpleText) {\n    if (isCopyToClipboardSupported()) {\n        // Ref: https://caniuse.com/?search=navigator.clipboard.writeText\n        //      * Must be called within user gesture event handlers such as pointerdown or pointerup.\n        //      * Writing to the clipboard is available without permission in secure contexts and browser extensions, but only\n        //        from user-initiated event callbacks. Browser extensions with the \"clipboardWrite\" permission can write to the\n        //        clipboard at any time.\n        await navigator.clipboard.writeText(simpleText);\n        return true;\n    } else {\n        return false;\n    }\n};\n\nexport {\n    copyToClipboard,\n    isCopyToClipboardSupported\n};\n","/* global window, chrome, browser */\n\nconst getBrowserStrategyGetManifest = function () {\n    let name = 'not-available';\n\n    const manifest = (\n        typeof chrome === 'object' &&\n        chrome &&\n        chrome.runtime &&\n        typeof chrome.runtime.getManifest === 'function' &&\n        chrome.runtime.getManifest()\n    );\n\n    if (\n        manifest &&\n        manifest['applications'] &&\n        manifest['applications']['gecko']\n    ) {\n        name = 'Firefox';\n    }\n\n    return {\n        name: name.toLowerCase()\n    };\n};\n\nconst getBrowserStrategyGetBrowserInfo = async function () {\n    let name = 'not-available';\n    let version = 'not-available';\n\n    const browserInfo = (\n        typeof browser === 'object' &&\n        browser &&\n        browser.runtime &&\n        typeof browser.runtime.getBrowserInfo === 'function' &&\n        await browser.runtime.getBrowserInfo()\n    );\n\n    if (browserInfo) {\n        name = browserInfo.name;\n        version = browserInfo.version;\n    }\n\n    return {\n        name: name.toLowerCase(),\n        version\n    };\n};\n\nconst getBrowserStrategyCustomHacks = function () {\n    let name = 'not-available';\n    const version = 'not-available';\n    let byPassedUserAgentModification = false;\n\n    identifyBrowserName: {\n        // Detect browser (without using window.navigator.userAgent)\n\n        if (typeof window.mozInnerScreenX === 'number') {\n            // DATED-CODE\n            name = 'Firefox';\n            break identifyBrowserName;\n        }\n\n        if (typeof window.opr === 'object' && window.opr) {\n            // DATED-CODE\n            name = 'Opera';\n            break identifyBrowserName;\n        }\n\n        if (typeof window.navigator.brave === 'object' && window.navigator.brave) {\n            // DATED-CODE\n            name = 'Brave';\n            break identifyBrowserName;\n        }\n\n        // Just a block\n        {\n            const userAgentData = window.navigator.userAgentData || {};\n            const brands = userAgentData.brands;\n\n            if (Array.isArray(brands)) {\n                if (!brands.length) {\n                    // DATED-CODE: As of 2023-Jan, the code would reach here if a user has customized the User-Agent string on\n                    // Chrome / Chromium based browser. Firefox does not support `window.navigator.userAgentData` yet.\n                    byPassedUserAgentModification = true;\n                    name = 'Chrome'; // Note: This is still a guess which should be true for most of the users.\n                    break identifyBrowserName;\n                }\n            }\n        }\n    }\n\n    return {\n        name: name.toLowerCase(),\n        version,\n        byPassedUserAgentModification\n    };\n};\n\nconst getBrowserStrategyUserAgentData = function () {\n    let name = 'not-available';\n    let version = 'not-available';\n\n    const userAgentData = window.navigator.userAgentData || {};\n    const brands = userAgentData.brands || [];\n\n    for (const ob of brands) {\n        const brand = ((brand) => {\n            if (brand === 'Google Chrome') {\n                return 'Chrome';\n            } else if (brand === 'Microsoft Edge') {\n                return 'Edge';\n            } else {\n                return brand.toLowerCase();\n            }\n        })(ob.brand);\n        if (\n            brand === 'Chrome' ||\n            brand === 'Edge' ||\n            brand === 'Brave' ||\n            brand === 'Opera' ||\n            (\n                brand === 'Chromium' &&\n                name === 'not-available'\n            )\n        ) {\n            name = brand;\n            version = ob.version || 'not-available';\n        }\n    }\n\n    return {\n        name: name.toLowerCase(),\n        version\n    };\n};\n\nconst getBrowserStrategyUserAgent = function () {\n    // https://stackoverflow.com/questions/5916900/how-can-you-detect-the-version-of-a-browser/16938481#16938481\n    const ua = navigator.userAgent;\n    let tem;\n    let M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\\/))\\/?\\s*(\\d+)/i) || [];\n    if (/trident/i.test(M[1])) {\n        tem = /\\brv[ :]+(\\d+)/g.exec(ua) || [];\n        return { name: 'IE', version: (tem[1] || '') };\n    }\n    if (M[1] === 'Chrome') {\n        tem = ua.match(/\\bOPR|Edge\\/(\\d+)/);\n        if (tem !== null) { return { name: 'Opera', version: tem[1] }; }\n    }\n    M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?'];\n    if ((tem = ua.match(/version\\/(\\d+)/i)) !== null) { M.splice(1, 1, tem[1]); }\n\n    const name = M[0] || 'not-available';\n    const version = M[1] || 'not-available';\n\n    return {\n        name: name.toLowerCase(),\n        version\n    };\n};\n\nconst getBrowser = (function () {\n    let confidenceLevel = 0;\n    let sourceOfConfidence = 'not-available';\n    let name = 'not-available';\n    let flagChromiumBased = null;\n    let encounteredError = null;\n\n    return async function () {\n        if (name === 'not-available') {\n            try {\n                identifyBrowserNameAndConfidenceLevel: {\n                    name = getBrowserStrategyGetManifest().name;\n                    if (name !== 'not-available') {\n                        sourceOfConfidence = 'getManifest';\n                        confidenceLevel = 1;\n                        break identifyBrowserNameAndConfidenceLevel;\n                    }\n\n                    name = (await getBrowserStrategyGetBrowserInfo()).name;\n                    if (name !== 'not-available') {\n                        sourceOfConfidence = 'getBrowserInfo';\n                        confidenceLevel = 1;\n                        break identifyBrowserNameAndConfidenceLevel;\n                    }\n\n                    name = getBrowserStrategyCustomHacks().name;\n                    if (name !== 'not-available') {\n                        sourceOfConfidence = 'customHacks';\n                        confidenceLevel = 0.9;\n                        break identifyBrowserNameAndConfidenceLevel;\n                    }\n\n                    name = getBrowserStrategyUserAgentData().name;\n                    if (name !== 'not-available') {\n                        sourceOfConfidence = 'userAgentData';\n                        confidenceLevel = 0.8;\n                        break identifyBrowserNameAndConfidenceLevel;\n                    }\n\n                    name = getBrowserStrategyUserAgent().name;\n                    if (name !== 'not-available') {\n                        sourceOfConfidence = 'userAgent';\n                        confidenceLevel = 0.7;\n                        break identifyBrowserNameAndConfidenceLevel;\n                    }\n\n                    name = 'chrome';\n                    sourceOfConfidence = 'blind-guess';\n                    confidenceLevel = 0.1;\n                }\n            } catch (err) {\n                encounteredError = err;\n            }\n\n            if (name === 'firefox') {\n                flagChromiumBased = false;\n            } else if (\n                [\n                    'brave',\n                    'chrome',\n                    'chromium',\n                    'opera',\n                    'edge'\n                ].includes(name)\n            ) {\n                flagChromiumBased = true;\n            }\n        }\n\n        return {\n            confidenceLevel,\n            sourceOfConfidence,\n            name,\n            flagChromiumBased,\n            encounteredError\n        };\n    };\n})();\n\nexport {\n    getBrowserStrategyGetManifest,\n    getBrowserStrategyGetBrowserInfo,\n    getBrowserStrategyCustomHacks,\n    getBrowserStrategyUserAgentData,\n    getBrowserStrategyUserAgent,\n    getBrowser\n};\n","/*\nNotes and Limitations:\n    * The `fallbackStorage` object is not shared between multiple browser tabs / windows\n    * The `.key()` method does not utilize the `fallbackStorage` object, so that it can be as compatible to multiple browser tabs as possible\n    * The `.length` getter does not utilize the `fallbackStorage` object, so that it can be as compatible to multiple browser tabs as possible\n    * The `handleError.onError` function is not reset by `handleError.reset()`\n*/\n\nconst handleError = {\n    errorCount: 0,\n    firstError: null,\n    lastError: null,\n    onError: null\n\n    // avoidDeadCodeElimination: null // The purpose of `handleError.avoidDeadCodeElimination` is to set an accessed value to it for avoiding the code usage from being removed by a dead code elimination tool\n};\nhandleError.reset = () => {\n    handleError.errorCount = 0;\n    handleError.firstError = null;\n    handleError.lastError = null;\n    // Note: `handleError.onError` is not being reset\n\n    // handleError.avoidDeadCodeElimination = null;\n};\n\nconst recordError = function (err) {\n    handleError.errorCount++;\n\n    if (handleError.firstError === null) {\n        handleError.firstError = err;\n    }\n\n    handleError.lastError = err;\n\n    if (typeof handleError.onError === 'function') {\n        handleError.onError(err);\n    }\n};\n\nconst fallbackStorage = Object.create(null); // No inherited properties, like `toString`, `hasOwnProperty`, etc.\n\nconst safeLocalStorage = {\n    getItem: function (key) {\n        try {\n            const value = localStorage.getItem(key);\n\n            if (value !== null) {\n                return value;\n            }\n        } catch (err) {\n            recordError(err);\n        }\n\n        if (Object.prototype.hasOwnProperty.call(fallbackStorage, key)) {\n            // Note: Not doing a check for `fallbackStorage[key] === undefined` since that case should not occur in normal usage\n            return fallbackStorage[key];\n        }\n        return null;\n    },\n\n    setItem: function (key, value) {\n        try {\n            fallbackStorage[key] = String(value);\n            localStorage.setItem(key, value);\n        } catch (err) {\n            recordError(err);\n        }\n    },\n\n    removeItem: function (key) {\n        try {\n            delete fallbackStorage[key];\n            localStorage.removeItem(key);\n        } catch (err) {\n            recordError(err);\n        }\n    },\n\n    clear: function () {\n        try {\n            for (const key in fallbackStorage) {\n                delete fallbackStorage[key];\n            }\n            localStorage.clear();\n        } catch (err) {\n            recordError(err);\n        }\n    },\n\n    key: function (index) {\n        /*\n        // This approach isn't compatible with multiple browser tabs, hence, it's not being used\n        const computedIndex = Number(index) || 0;\n        const keys = Object.keys(fallbackStorage);\n        const key = keys[computedIndex] || null;\n        try {\n            // Here, we are not utilizing the value of `localStorage.key(index)`. We are just checking if localStorage is available for access without error\n            handleError.avoidDeadCodeElimination = localStorage.key(index);\n        } catch (err) {\n            recordError(err);\n        }\n        return key;\n        */\n\n        try {\n            const key = localStorage.key(index);\n            return key;\n        } catch (err) {\n            recordError(err);\n            return null;\n        }\n    },\n\n    get length() {\n        /*\n        // This approach isn't compatible with multiple browser tabs, hence, it's not being used\n        const fallbackStorageLength = Object.keys(fallbackStorage).length;\n        try {\n            // Here, we are not utilizing the value of `localStorage.length`. We are just checking if localStorage is available for access without error.\n            handleError.avoidDeadCodeElimination = localStorage.length;\n        } catch (err) {\n            recordError(err);\n        }\n        return fallbackStorageLength;\n        */\n\n        try {\n            return localStorage.length;\n        } catch (err) {\n            recordError(err);\n            return 0;\n        }\n    }\n};\n\nexport {\n    safeLocalStorage,\n    fallbackStorage,\n    handleError\n};\n","import { copyToClipboard } from './copyToClipboard.js';\nimport { getBrowser } from './getBrowser.js';\nimport { safeLocalStorage } from './safeLocalStorage.js';\nimport { safeLocalStorageSimple } from './safeLocalStorageSimple.js';\n\nconst browser = {\n    copyToClipboard,\n    getBrowser,\n    safeLocalStorage,\n    safeLocalStorageSimple\n};\n\nexport { browser };\n","const safeLocalStorageSimple = {\n    getItem: function (key) {\n        try {\n            return localStorage.getItem(key);\n        } catch (err) { // eslint-disable-line no-unused-vars\n            return null;\n        }\n    },\n    setItem: function (key, value) {\n        try {\n            localStorage.setItem(key, value);\n        } catch (err) { // eslint-disable-line no-unused-vars\n            // do nothing\n        }\n    },\n    removeItem: function (key) {\n        try {\n            localStorage.removeItem(key);\n        } catch (err) { // eslint-disable-line no-unused-vars\n            // do nothing\n        }\n    },\n    key: function (index) {\n        try {\n            return localStorage.key(index);\n        } catch (err) { // eslint-disable-line no-unused-vars\n            return null;\n        }\n    },\n    clear: function () {\n        try {\n            localStorage.clear();\n        } catch (err) { // eslint-disable-line no-unused-vars\n            // do nothing\n        }\n    }\n};\n\nexport { safeLocalStorageSimple };\n"],"names":["getBrowser","confidenceLevel","sourceOfConfidence","name","flagChromiumBased","encounteredError","async","manifest","chrome","runtime","getManifest","toLowerCase","getBrowserStrategyGetManifest","version","browserInfo","browser","getBrowserInfo","getBrowserStrategyGetBrowserInfo","byPassedUserAgentModification","identifyBrowserName","window","mozInnerScreenX","opr","navigator","brave","brands","userAgentData","Array","isArray","length","getBrowserStrategyCustomHacks","ob","brand","getBrowserStrategyUserAgentData","ua","userAgent","tem","M","match","test","exec","appName","appVersion","splice","getBrowserStrategyUserAgent","err","includes","fallbackStorage","Object","create","copyToClipboard","simpleText","clipboard","writeText","safeLocalStorage","getItem","key","value","localStorage","prototype","hasOwnProperty","call","setItem","String","removeItem","clear","index","safeLocalStorageSimple"],"mappings":"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"}