{"version":3,"sources":["jsdelivr-header.js","/npm/@heyputer/puter.js@2.2.10/src/index.js"],"names":[],"mappings":"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","file":"/npm/@heyputer/puter.js@2.2.10/src/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/@heyputer/puter.js@2.2.10/src/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","import kvjs from '@heyputer/kv.js';\nimport APICallLogger from './lib/APICallLogger.js';\nimport path from './lib/path.js';\nimport localStorageMemory from './lib/polyfills/localStorage.js';\nimport xhrshim from './lib/polyfills/xhrshim.js';\nimport * as utils from './lib/utils.js';\nimport AI from './modules/AI.js';\nimport Apps from './modules/Apps.js';\nimport Auth from './modules/Auth.js';\nimport { Debug } from './modules/Debug.js';\nimport Drivers from './modules/Drivers.js';\nimport { PuterJSFileSystemModule } from './modules/FileSystem/index.js';\nimport FSItem from './modules/FSItem.js';\nimport Hosting from './modules/Hosting.js';\nimport KV from './modules/KV.js';\nimport { PSocket } from './modules/networking/PSocket.js';\nimport { PTLSSocket } from './modules/networking/PTLS.js';\nimport { pFetch } from './modules/networking/requests.js';\nimport OS from './modules/OS.js';\nimport Perms from './modules/Perms.js';\nimport UI from './modules/UI.js';\nimport Util from './modules/Util.js';\nimport { WorkersHandler } from './modules/Workers.js';\n\nclass SimpleLogger {\n    constructor (fields = {}) {\n        this.fieldsObj = fields;\n        this.enabled = new Set();\n    }\n\n    on (category) {\n        this.enabled.add(category);\n    }\n\n    fields (extra = {}) {\n        return new SimpleLogger({ ...this.fieldsObj, ...extra });\n    }\n\n    info (...args) {\n        console.log(...this._prefix(), ...args);\n    }\n\n    warn (...args) {\n        console.warn(...this._prefix(), ...args);\n    }\n\n    error (...args) {\n        console.error(...this._prefix(), ...args);\n    }\n\n    debug (...args) {\n        console.debug(...this._prefix(), ...args);\n    }\n\n    _prefix () {\n        const entries = Object.entries(this.fieldsObj);\n        if ( ! entries.length ) return [];\n        return [`[${ entries.map(([k, v]) => `${k}=${v}`).join(' ')}]`];\n    }\n}\n\nclass Lock {\n    constructor () {\n        this.locked = false;\n        this.queue = [];\n    }\n\n    async acquire () {\n        if ( ! this.locked ) {\n            this.locked = true;\n            return;\n        }\n\n        await new Promise(resolve => this.queue.push(resolve));\n        this.locked = true;\n    }\n\n    release () {\n        const next = this.queue.shift();\n        if ( next ) {\n            next();\n            return;\n        }\n        this.locked = false;\n    }\n}\n// TODO: This is for a safe-guard below; we should check if we can\n//       generalize this behavior rather than hard-coding it.\n//       (using defaultGUIOrigin breaks locally-hosted apps)\nconst PROD_ORIGIN = 'https://puter.com';\n\nconst puterInit = (function () {\n    'use strict';\n\n    class Puter {\n        // The environment that the SDK is running in. Can be 'gui', 'app' or 'web'.\n        // 'gui' means the SDK is running in the Puter GUI, i.e. Puter.com.\n        // 'app' means the SDK is running as a Puter app, i.e. within an iframe in the Puter GUI.\n        // 'web' means the SDK is running in a 3rd-party website.\n        env;\n\n        #defaultAPIOrigin = 'https://api.puter.com';\n        #defaultGUIOrigin = 'https://puter.com';\n\n        get defaultAPIOrigin () {\n            return globalThis.PUTER_API_ORIGIN || globalThis.PUTER_API_ORIGIN_ENV || this.#defaultAPIOrigin;\n        }\n        set defaultAPIOrigin (v) {\n            this.#defaultAPIOrigin = v;\n        }\n\n        get defaultGUIOrigin () {\n            return globalThis.PUTER_ORIGIN || globalThis.PUTER_ORIGIN_ENV || this.#defaultGUIOrigin;\n        }\n        set defaultGUIOrigin (v) {\n            this.#defaultGUIOrigin = v;\n        }\n\n        // An optional callback when the user is authenticated. This can be set by the app using the SDK.\n        onAuth;\n\n        /**\n         * State object to keep track of the authentication request status.\n         * This is used to prevent multiple authentication popups from showing up by different parts of the app.\n         */\n        puterAuthState = {\n            isPromptOpen: false,\n            authGranted: null,\n            resolver: null,\n        };\n\n        // Holds the unique app instance ID that is provided by the host environment\n        appInstanceID;\n\n        // Holds the unique app instance ID for the parent (if any), which is provided by the host environment\n        parentInstanceID;\n\n        // Expose the FSItem class\n        static FSItem = FSItem;\n\n        // Event handling properties\n        eventHandlers = {};\n\n        // debug flag\n        debugMode = false;\n\n        /**\n         * Puter.js Modules\n         *\n         * These are the modules you see on docs.puter.com; for example:\n         * - puter.fs\n         * - puter.kv\n         * - puter.ui\n         *\n         * initSubmodules is called from the constructor of this class.\n         */\n        initSubmodules = function () {\n            // Util\n            this.util = new Util();\n\n            this.registerModule('auth', Auth);\n            this.registerModule('os', OS);\n            this.registerModule('fs', PuterJSFileSystemModule);\n            this.registerModule('ui', UI, {\n                appInstanceID: this.appInstanceID,\n                parentInstanceID: this.parentInstanceID,\n            });\n            this.registerModule('hosting', Hosting);\n            this.registerModule('apps', Apps);\n            this.registerModule('ai', AI);\n            this.registerModule('kv', KV);\n            this.registerModule('perms', Perms);\n            this.registerModule('drivers', Drivers);\n            this.registerModule('debug', Debug);\n\n            // Path\n            this.path = path;\n        };\n\n        // --------------------------------------------\n        // Constructor\n        // --------------------------------------------\n        constructor () {\n\n            // Initialize the cache using kv.js\n            this._cache = new kvjs({ dbName: 'puter_cache' });\n            this._opscache = new kvjs();\n\n            // \"modules\" in puter.js are external interfaces for the developer\n            this.modules_ = [];\n\n            // Holds the query parameters found in the current URL\n            let URLParams = new URLSearchParams(globalThis.location?.search);\n\n            // Figure out the environment in which the SDK is running\n            if ( URLParams.has('puter.app_instance_id') ) {\n                this.env = 'app';\n            } else if ( globalThis.puter_gui_enabled === true )\n            {\n                this.env = 'gui';\n            }\n            else if ( globalThis.WorkerGlobalScope ) {\n                if ( globalThis.ServiceWorkerGlobalScope ) {\n                    this.env = 'service-worker';\n                    if ( ! globalThis.XMLHttpRequest ) {\n                        globalThis.XMLHttpRequest = xhrshim;\n                    }\n                    if ( ! globalThis.location ) {\n                        globalThis.location = new URL('https://puter.site/');\n                    }\n                    // XHRShimGlobalize here\n                } else {\n                    this.env = 'web-worker';\n                }\n                if ( ! globalThis.localStorage ) {\n                    globalThis.localStorage = localStorageMemory;\n                }\n            } else if ( globalThis.process ) {\n                this.env = 'nodejs';\n                if ( ! globalThis.localStorage ) {\n                    globalThis.localStorage = localStorageMemory;\n                }\n                if ( ! globalThis.XMLHttpRequest ) {\n                    globalThis.XMLHttpRequest = xhrshim;\n                }\n                if ( ! globalThis.location ) {\n                    globalThis.location = new URL('https://nodejs.puter.site/');\n                }\n                if ( ! globalThis.addEventListener ) {\n                    globalThis.addEventListener = () => {\n                    }; // API Stub\n                }\n            } else {\n                this.env = 'web';\n            }\n\n            // There are some specific situations where puter is definitely loaded in GUI mode\n            // we're going to check for those situations here so that we don't break anything unintentionally\n            // if navigator URL's hostname is 'puter.com'\n            if ( this.env !== 'gui' ) {\n                // Retrieve the hostname from the URL: Remove the trailing dot if it exists. This is to handle the case where the URL is, for example, `https://puter.com.` (note the trailing dot).\n                // This is necessary because the trailing dot can cause the hostname to not match the expected value.\n                let hostname = location.hostname.replace(/\\.$/, '');\n\n                // Create a new URL object with the URL string\n                const url = new URL(PROD_ORIGIN);\n\n                // Extract hostname from the URL object\n                const gui_hostname = url.hostname;\n\n                // If the hostname matches the GUI hostname, then the SDK is running in the GUI environment\n                if ( hostname === gui_hostname ) {\n                    this.env = 'gui';\n                }\n            }\n\n            // Get the 'args' from the URL. This is used to pass arguments to the app.\n            if ( URLParams.has('puter.args') ) {\n                this.args = JSON.parse(decodeURIComponent(URLParams.get('puter.args')));\n            } else {\n                this.args = {};\n            }\n\n            // Try to extract appInstanceID from the URL. appInstanceID is included in every messaage\n            // sent to the host environment. This is used to help host environment identify the app\n            // instance that sent the message and communicate back to it.\n            if ( URLParams.has('puter.app_instance_id') ) {\n                this.appInstanceID = decodeURIComponent(URLParams.get('puter.app_instance_id'));\n            }\n\n            // Try to extract parentInstanceID from the URL. If another app launched this app instance, parentInstanceID\n            // holds its instance ID, and is used to communicate with that parent app.\n            if ( URLParams.has('puter.parent_instance_id') ) {\n                this.parentInstanceID = decodeURIComponent(URLParams.get('puter.parent_instance_id'));\n            }\n\n            // Try to extract `puter.app.id` from the URL. `puter.app.id` is the unique ID of the app.\n            // App ID is useful for identifying the app when communicating with the Puter API, among other things.\n            if ( URLParams.has('puter.app.id') ) {\n                this.appID = decodeURIComponent(URLParams.get('puter.app.id'));\n            }\n\n            // Extract app name (added later)\n            if ( URLParams.has('puter.app.name') ) {\n                this.appName = decodeURIComponent(URLParams.get('puter.app.name'));\n            }\n\n            // Construct this App's AppData path based on the appID. AppData path is used to store files that are specific to this app.\n            // The default AppData path is `~/AppData/<appID>`.\n            if ( this.appID ) {\n                this.appDataPath = `~/AppData/${this.appID}`;\n            }\n\n            // Construct APIOrigin from the URL. APIOrigin is used to build the URLs for the Puter API endpoints.\n            // The default APIOrigin is https://api.puter.com. However, if the URL contains a `puter.api_origin` query parameter,\n            // then that value is used as the APIOrigin. If the URL contains a `puter.domain` query parameter, then the APIOrigin\n            // is constructed as `https://api.<puter.domain>`.\n            // This should only be done when the SDK is running in 'app' mode.\n            this.APIOrigin = this.defaultAPIOrigin;\n            if ( URLParams.has('puter.api_origin') && this.env === 'app' ) {\n                this.APIOrigin = decodeURIComponent(URLParams.get('puter.api_origin'));\n            } else if ( URLParams.has('puter.domain') && this.env === 'app' ) {\n                this.APIOrigin = `https://api.${ URLParams.get('puter.domain')}`;\n            }\n\n            // === START :: Logger ===\n\n            // Basic logger replacement (console-based)\n            let logger = new SimpleLogger();\n            this.logger = logger;\n\n            // Initialize API call logger\n            this.apiCallLogger = new APICallLogger({\n                enabled: false, // Disabled by default\n            });\n\n            // === Start :: Modules === //\n\n            // The SDK is running in the Puter GUI (i.e. 'gui')\n            if ( this.env === 'gui' ) {\n                this.authToken = window.auth_token;\n                // initialize submodules\n                this.initSubmodules();\n            }\n            // Loaded in an iframe in the Puter GUI (i.e. 'app')\n            // When SDK is loaded in App mode the initiation process should start when the DOM is ready\n            else if ( this.env === 'app' ) {\n                this.authToken = decodeURIComponent(URLParams.get('puter.auth.token'));\n                // initialize submodules\n                this.initSubmodules();\n                // If the authToken is already set in localStorage, then we don't need to show the dialog\n                try {\n                    if ( localStorage.getItem('puter.auth.token') ) {\n                        this.setAuthToken(localStorage.getItem('puter.auth.token'));\n                    }\n                    // if appID is already set in localStorage, then we don't need to show the dialog\n                    if ( localStorage.getItem('puter.app.id') ) {\n                        this.setAppID(localStorage.getItem('puter.app.id'));\n                    }\n                } catch ( error ) {\n                    // Handle the error here\n                    console.error('Error accessing localStorage:', error);\n                }\n            }\n            // SDK was loaded in a 3rd-party website.\n            // When SDK is loaded in GUI the initiation process should start when the DOM is ready. This is because\n            // the SDK needs to show a dialog to the user to ask for permission to access their Puter account.\n            else if ( this.env === 'web' ) {\n                // initialize submodules\n                this.initSubmodules();\n                try {\n                    // If the authToken is already set in localStorage, then we don't need to show the dialog\n                    if ( localStorage.getItem('puter.auth.token') ) {\n                        this.setAuthToken(localStorage.getItem('puter.auth.token'));\n                    }\n                    // if appID is already set in localStorage, then we don't need to show the dialog\n                    if ( localStorage.getItem('puter.app.id') ) {\n                        this.setAppID(localStorage.getItem('puter.app.id'));\n                    }\n                } catch ( error ) {\n                    // Handle the error here\n                    console.error('Error accessing localStorage:', error);\n                }\n            } else if ( this.env === 'web-worker' || this.env === 'service-worker' || this.env === 'nodejs' ) {\n                this.initSubmodules();\n            }\n\n            // Add prefix logger (needed to happen after modules are initialized)\n            (async () => {\n                try {\n                    const whoami = await this.auth.whoami();\n                    const prefix = `[${\n                        whoami?.app_name ?? this.appInstanceID ?? 'HOST'\n                    }]`;\n                    logger = logger.fields({ prefix });\n                    this.logger = logger;\n                } catch ( error ) {\n                    if ( this.debugMode ) {\n                        console.error('Failed to initialize prefix logger', error);\n                    }\n                }\n            })();\n\n            // Lock to prevent multiple requests to `/rao`\n            this.lock_rao_ = new Lock();\n            // Promise that resolves when it's okay to request `/rao`\n            this.p_can_request_rao_ = Promise.resolve();\n            // Flag that indicates if a request to `/rao` has been made\n            this.rao_requested_ = false;\n\n            this.net = {\n                generateWispV1URL: async () => {\n                    const { token: wispToken, server: wispServer } = (await (await fetch(`${this.APIOrigin }/wisp/relay-token/create`, {\n                        method: 'POST',\n                        headers: {\n                            Authorization: `Bearer ${this.authToken}`,\n                            'Content-Type': 'application/json',\n                        },\n                        body: JSON.stringify({}),\n                    })).json());\n                    return `${wispServer}/${wispToken}/`;\n                },\n                Socket: PSocket,\n                tls: {\n                    TLSSocket: PTLSSocket,\n                },\n                fetch: pFetch,\n            };\n\n            this.workers = new WorkersHandler(this.authToken);\n\n            // Initialize network connectivity monitoring and cache purging\n            this.initNetworkMonitoring();\n        }\n\n        /**\n         * @internal\n         * Makes a request to `/rao`. This method aquires a lock to prevent\n         * multiple requests, and is effectively idempotent.\n         */\n        async request_rao_ () {\n            await this.p_can_request_rao_;\n\n            if ( this.env === 'gui' ) {\n                return;\n            }\n\n            // setAuthToken is called more than once when auth completes, which\n            // causes multiple requests to /rao. This lock prevents that.\n            await this.lock_rao_.acquire();\n            if ( this.rao_requested_ ) {\n                this.lock_rao_.release();\n                return;\n            }\n\n            let had_error = false;\n            try {\n                const resp = await fetch(`${this.APIOrigin }/rao`, {\n                    method: 'POST',\n                    headers: {\n                        Authorization: `Bearer ${this.authToken}`,\n                        Origin: location.origin, // This is ignored in the browser but needed for workers and nodejs\n                    },\n                });\n                return await resp.json();\n            } catch ( e ) {\n                had_error = true;\n                console.error(e);\n            } finally {\n                this.lock_rao_.release();\n            }\n            if ( ! had_error ) {\n                this.rao_requested_ = true;\n            }\n        }\n\n        registerModule (name, cls, parameters = {}) {\n            const instance = new cls(this, parameters);\n            instance.puter = this;\n            this.modules_.push(name);\n            this[name] = instance;\n            if ( instance._init ) instance._init({ puter: this });\n        }\n\n        updateSubmodules () {\n            // Update submodules with new auth token and API origin\n            for ( const name of this.modules_ ) {\n                if ( ! this[name] ) continue;\n                this[name]?.setAuthToken?.(this.authToken);\n                this[name]?.setAPIOrigin?.(this.APIOrigin);\n            }\n        }\n\n        setAppID = function (appID) {\n            // save to localStorage\n            try {\n                localStorage.setItem('puter.app.id', appID);\n            } catch ( error ) {\n                // Handle the error here\n                console.error('Error accessing localStorage:', error);\n            }\n            this.appID = appID;\n        };\n\n        setAuthToken = function (authToken) {\n            this.authToken = authToken;\n            // If the SDK is running on a 3rd-party site or an app, then save the authToken in localStorage\n            if ( this.env === 'web' || this.env === 'app' ) {\n                try {\n                    localStorage.setItem('puter.auth.token', authToken);\n                } catch ( error ) {\n                    // Handle the error here\n                    console.error('Error accessing localStorage:', error);\n                }\n            }\n            // initialize loop for updating caches for major directories\n            if ( this.env === 'gui' ) {\n                // check and update gui fs cache regularly\n                setInterval(puter.checkAndUpdateGUIFScache, 10000);\n            }\n            // reinitialize submodules\n            this.updateSubmodules();\n\n            // rao\n            this.request_rao_();\n\n            // perform whoami and cache results\n            this.getUser().then((user) => {\n                this.whoami = user;\n            });\n        };\n\n        setAPIOrigin = function (APIOrigin) {\n            this.APIOrigin = APIOrigin;\n            // reinitialize submodules\n            this.updateSubmodules();\n        };\n\n        runWhenPuterHappensCallbacks = function () {\n            if ( this.env !== 'gui' ) return;\n            if ( ! globalThis.when_puter_happens ) return;\n\n            const callbacks = Array.isArray(globalThis.when_puter_happens)\n                ? globalThis.when_puter_happens\n                : [globalThis.when_puter_happens];\n\n            for ( const fn of callbacks ) {\n                try {\n                    fn({ puter: this });\n                } catch ( error ) {\n                    if ( this.debugMode ) {\n                        console.error('when_puter_happens callback failed', error);\n                    }\n                }\n            }\n        };\n\n        resetAuthToken = function () {\n            if ( this.env === 'worker' || this.env === 'service-worker' ) {\n                throw new Error('Sign out is not permitted from WebWorkers or ServiceWorkers');\n            }\n            this.authToken = null;\n            // If the SDK is running on a 3rd-party site or an app, then save the authToken in localStorage\n            if ( this.env === 'web' || this.env === 'app' ) {\n                try {\n                    localStorage.removeItem('puter.auth.token');\n                } catch ( error ) {\n                    // Handle the error here\n                    console.error('Error accessing localStorage:', error);\n                }\n            }\n            // reinitialize submodules\n            this.updateSubmodules();\n        };\n\n        exit = function (statusCode = 0) {\n            if ( statusCode && (typeof statusCode !== 'number') ) {\n                console.warn('puter.exit() requires status code to be a number. Treating it as 1');\n                statusCode = 1;\n            }\n\n            globalThis.parent.postMessage({\n                msg: 'exit',\n                appInstanceID: this.appInstanceID,\n                statusCode,\n            }, '*');\n        };\n\n        /**\n         * A function that generates a domain-safe name by combining a random adjective, a random noun, and a random number (between 0 and 9999).\n         * The result is returned as a string with components separated by hyphens.\n         * It is useful when you need to create unique identifiers that are also human-friendly.\n         *\n         * @param {string} [separateWith='-'] - The character to use to separate the components of the generated name.\n         * @returns {string} A unique, hyphen-separated string comprising of an adjective, a noun, and a number.\n         *\n         */\n        randName = function (separateWith = '-') {\n            const first_adj = ['helpful', 'sensible', 'loyal', 'honest', 'clever', 'capable', 'calm', 'smart', 'genius', 'bright', 'charming', 'creative', 'diligent', 'elegant', 'fancy',\n                'colorful', 'avid', 'active', 'gentle', 'happy', 'intelligent', 'jolly', 'kind', 'lively', 'merry', 'nice', 'optimistic', 'polite',\n                'quiet', 'relaxed', 'silly', 'victorious', 'witty', 'young', 'zealous', 'strong', 'brave', 'agile', 'bold'];\n\n            const nouns = ['street', 'roof', 'floor', 'tv', 'idea', 'morning', 'game', 'wheel', 'shoe', 'bag', 'clock', 'pencil', 'pen',\n                'magnet', 'chair', 'table', 'house', 'dog', 'room', 'book', 'car', 'cat', 'tree',\n                'flower', 'bird', 'fish', 'sun', 'moon', 'star', 'cloud', 'rain', 'snow', 'wind', 'mountain',\n                'river', 'lake', 'sea', 'ocean', 'island', 'bridge', 'road', 'train', 'plane', 'ship', 'bicycle',\n                'horse', 'elephant', 'lion', 'tiger', 'bear', 'zebra', 'giraffe', 'monkey', 'snake', 'rabbit', 'duck',\n                'goose', 'penguin', 'frog', 'crab', 'shrimp', 'whale', 'octopus', 'spider', 'ant', 'bee', 'butterfly', 'dragonfly',\n                'ladybug', 'snail', 'camel', 'kangaroo', 'koala', 'panda', 'piglet', 'sheep', 'wolf', 'fox', 'deer', 'mouse', 'seal',\n                'chicken', 'cow', 'dinosaur', 'puppy', 'kitten', 'circle', 'square', 'garden', 'otter', 'bunny', 'meerkat', 'harp'];\n\n            // return a random combination of first_adj + noun + number (between 0 and 9999)\n            // e.g. clever-idea-123\n            return first_adj[Math.floor(Math.random() * first_adj.length)] + separateWith + nouns[Math.floor(Math.random() * nouns.length)] + separateWith + Math.floor(Math.random() * 10000);\n        };\n\n        getUser = function (...args) {\n            let options;\n\n            // If first argument is an object, it's the options\n            if ( typeof args[0] === 'object' && args[0] !== null ) {\n                options = args[0];\n            } else {\n                // Otherwise, we assume separate arguments are provided\n                options = {\n                    success: args[0],\n                    error: args[1],\n                };\n            }\n\n            return new Promise((resolve, reject) => {\n                const xhr = utils.initXhr('/whoami', this.APIOrigin, this.authToken, 'get');\n                // set up event handlers for load and error events\n                utils.setupXhrEventHandlers(xhr, options.success, options.error, resolve, reject);\n\n                xhr.send();\n            });\n        };\n\n        print = function (...args) {\n            // Check if the last argument is an options object with escapeHTML or code property\n            let options = {};\n            if ( args.length > 0 && typeof args[args.length - 1] === 'object' && args[args.length - 1] !== null &&\n                ('escapeHTML' in args[args.length - 1] || 'code' in args[args.length - 1]) ) {\n                options = args.pop();\n            }\n\n            for ( let arg of args ) {\n                // Escape HTML if the option is set to true or if code option is true\n                if ( (options.escapeHTML === true || options.code === true) && typeof arg === 'string' ) {\n                    arg = arg.replace(/&/g, '&amp;')\n                        .replace(/</g, '&lt;')\n                        .replace(/>/g, '&gt;')\n                        .replace(/\"/g, '&quot;')\n                        .replace(/'/g, '&#039;');\n                }\n\n                // Wrap in code/pre tags if code option is true\n                if ( options.code === true ) {\n                    arg = `<code><pre>${arg}</pre></code>`;\n                }\n\n                document.body.innerHTML += arg;\n            }\n        };\n\n        /**\n         * Configures API call logging settings\n         * @param {Object} config - Configuration options for API call logging\n         * @param {boolean} config.enabled - Enable/disable API call logging\n          * @param {boolean} config.enabled - Enable/disable API call logging\n         */\n        configureAPILogging = function (config = {}) {\n            if ( this.apiCallLogger ) {\n                this.apiCallLogger.updateConfig(config);\n            }\n            return this;\n        };\n\n        /**\n         * Enables API call logging with optional configuration\n         * @param {Object} config - Optional configuration to apply when enabling\n         */\n        enableAPILogging = function (config = {}) {\n            if ( this.apiCallLogger ) {\n                this.apiCallLogger.updateConfig({ ...config, enabled: true });\n            }\n            return this;\n        };\n\n        /**\n         * Disables API call logging\n         */\n        disableAPILogging = function () {\n            if ( this.apiCallLogger ) {\n                this.apiCallLogger.disable();\n            }\n            return this;\n        };\n\n        /**\n         * Initializes network connectivity monitoring to purge cache when connection is lost\n         * @private\n         */\n        initNetworkMonitoring = function () {\n            // Only initialize in environments that support navigator.onLine and window events\n            if ( typeof globalThis.navigator === 'undefined' ||\n                typeof globalThis.addEventListener !== 'function' ) {\n                return;\n            }\n\n            // Track previous online state\n            let wasOnline = navigator.onLine;\n\n            // Function to handle network state changes\n            const handleNetworkChange = () => {\n                const isOnline = navigator.onLine;\n\n                // If we went from online to offline, purge the cache\n                if ( wasOnline && !isOnline ) {\n                    console.log('Network connection lost - purging cache');\n                    try {\n                        this._cache.flushall();\n                        console.log('Cache purged successfully');\n                    } catch ( error ) {\n                        console.error('Error purging cache:', error);\n                    }\n                }\n\n                // Update the previous state\n                wasOnline = isOnline;\n            };\n\n            // Listen for online/offline events\n            globalThis.addEventListener('online', handleNetworkChange);\n            globalThis.addEventListener('offline', handleNetworkChange);\n\n            // Also listen for visibility change as an additional indicator\n            // (some browsers don't fire offline events reliably)\n            if ( typeof document !== 'undefined' ) {\n                document.addEventListener('visibilitychange', () => {\n                    // Small delay to allow network state to update\n                    setTimeout(handleNetworkChange, 100);\n                });\n            }\n        };\n\n        /**\n         * Checks and updates the GUI FS cache for most-commonly used paths\n         * @private\n         */\n        checkAndUpdateGUIFScache = function () {\n            // only run in gui environment\n            if ( puter.env !== 'gui' ) return;\n            // only run if user is authenticated\n            if ( ! puter.whoami ) return;\n\n            let username = puter.whoami.username;\n\n            // common paths\n            let home_path = `/${username}`;\n            let desktop_path = `/${username}/Desktop`;\n            let documents_path = `/${username}/Documents`;\n            let public_path = `/${username}/Public`;\n\n            // item:Home\n            if ( ! puter._cache.get(`item:${ home_path}`) ) {\n                console.log(`/${username} item is not cached, refetching cache`);\n                // fetch home\n                puter.fs.stat(home_path);\n            }\n            // item:Desktop\n            if ( ! puter._cache.get(`item:${ desktop_path}`) ) {\n                console.log(`/${username}/Desktop item is not cached, refetching cache`);\n                // fetch desktop\n                puter.fs.stat(desktop_path);\n            }\n            // item:Documents\n            if ( ! puter._cache.get(`item:${ documents_path}`) ) {\n                console.log(`/${username}/Documents item is not cached, refetching cache`);\n                // fetch documents\n                puter.fs.stat(documents_path);\n            }\n            // item:Public\n            if ( ! puter._cache.get(`item:${ public_path}`) ) {\n                console.log(`/${username}/Public item is not cached, refetching cache`);\n                // fetch public\n                puter.fs.stat(public_path);\n            }\n\n            // readdir:Home\n            if ( ! puter._cache.get(`readdir:${ home_path}`) ) {\n                console.log(`/${username} is not cached, refetching cache`);\n                // fetch home\n                puter.fs.readdir(home_path);\n            }\n            // readdir:Desktop\n            if ( ! puter._cache.get(`readdir:${ desktop_path}`) ) {\n                console.log(`/${username}/Desktop is not cached, refetching cache`);\n                // fetch desktop\n                puter.fs.readdir(desktop_path);\n            }\n            // readdir:Documents\n            if ( ! puter._cache.get(`readdir:${ documents_path}`) ) {\n                console.log(`/${username}/Documents is not cached, refetching cache`);\n                // fetch documents\n                puter.fs.readdir(documents_path);\n            }\n            // readdir:Public\n            if ( ! puter._cache.get(`readdir:${ public_path}`) ) {\n                console.log(`/${username}/Public is not cached, refetching cache`);\n                // fetch public\n                puter.fs.readdir(public_path);\n            }\n        };\n    }\n\n    // Create a new Puter object and return it\n    const puterobj = new Puter();\n\n    // Return the Puter object\n    return puterobj;\n});\n\nexport const puter =  puterInit();\nexport default puter;\nglobalThis.puter = puter;\nputer.runWhenPuterHappensCallbacks();\n\nputer.tools = [];\n/**\n * @type {{messageTarget: Window}}\n */\nconst puterParent = puter.ui.parentApp();\nglobalThis.puterParent = puterParent;\nif ( puterParent ) {\n    console.log('I have a parent, registering tools');\n    puterParent.on('message', async (event) => {\n        console.log('Got tool req ', event);\n        if ( event.$ === 'requestTools' ) {\n            console.log('Responding with tools');\n            puterParent.postMessage({\n                $: 'providedTools',\n                tools: JSON.parse(JSON.stringify(puter.tools)),\n            });\n        }\n\n        if ( event.$ === 'executeTool' ) {\n            console.log('xecuting tools');\n            /**\n             * Puter tools format\n             * @type {[{exec: Function, function: {description: string, name: string, parameters: {properties: any, required: Array<string>}, type: string}}]}\n             */\n            const [tool] = puter.tools.filter(e => e.function.name === event.toolName);\n\n            const response = await tool.exec(event.parameters);\n            puterParent.postMessage({\n                $: 'toolResponse',\n                response,\n                tag: event.tag,\n            });\n        }\n    });\n    puterParent.postMessage({ $: 'ready' });\n}\n\nglobalThis.addEventListener && globalThis.addEventListener('message', async (event) => {\n    // if the message is not from Puter, then ignore it\n    if ( event.origin !== puter.defaultGUIOrigin ) return;\n\n    if ( event.data.msg && event.data.msg === 'requestOrigin' ) {\n        event.source.postMessage({\n            msg: 'originResponse',\n        }, '*');\n    }\n    else if ( event.data.msg === 'puter.token' ) {\n        // puterDialog.close();\n        // Set the authToken property\n        puter.setAuthToken(event.data.token);\n        // update appID\n        puter.setAppID(event.data.app_uid);\n        // Remove the event listener to avoid memory leaks\n        // window.removeEventListener('message', messageListener);\n\n        puter.puterAuthState.authGranted = true;\n        // Resolve the promise\n        // resolve();\n\n        // Call onAuth callback\n        if ( puter.onAuth && typeof puter.onAuth === 'function' ) {\n            puter.getUser().then((user) => {\n                puter.onAuth(user);\n            });\n        }\n\n        puter.puterAuthState.isPromptOpen = false;\n        // Resolve or reject any waiting promises.\n        if ( puter.puterAuthState.resolver ) {\n            if ( puter.puterAuthState.authGranted ) {\n                puter.puterAuthState.resolver.resolve();\n            } else {\n                puter.puterAuthState.resolver.reject();\n            }\n            puter.puterAuthState.resolver = null;\n        };\n    }\n});\n"]}