From 828ecbbf101e3fb7e2222d9f2f872f5453bdcd4a Mon Sep 17 00:00:00 2001 From: Mauro Balades Date: Tue, 6 Aug 2024 20:05:53 +0200 Subject: [PATCH] refactor: Remove unused type declarations and package.json dependencies --- @types/common.d.ts | 5 - @types/gecko.d.ts | 525 ------------ @types/split-views.d.ts | 13 - package-lock.json | 1551 ------------------------------------ package.json | 16 - src/ZenSidebarManager.mjs | 551 +++++++++++++ src/ZenViewSplitter.mjs | 349 ++++++++ src/ZenWorkspaces.mjs | 426 ++++++++++ src/browser-splitViews.mjs | 330 -------- tsconfig.json | 106 --- 10 files changed, 1326 insertions(+), 2546 deletions(-) delete mode 100644 @types/common.d.ts delete mode 100644 @types/gecko.d.ts delete mode 100644 @types/split-views.d.ts delete mode 100644 package-lock.json delete mode 100644 package.json create mode 100644 src/ZenSidebarManager.mjs create mode 100644 src/ZenViewSplitter.mjs create mode 100644 src/ZenWorkspaces.mjs delete mode 100644 src/browser-splitViews.mjs delete mode 100644 tsconfig.json diff --git a/@types/common.d.ts b/@types/common.d.ts deleted file mode 100644 index 9cbebb3..0000000 --- a/@types/common.d.ts +++ /dev/null @@ -1,5 +0,0 @@ - -export interface Config { - debug: boolean; - browserName: string; -}; diff --git a/@types/gecko.d.ts b/@types/gecko.d.ts deleted file mode 100644 index 366f1d2..0000000 --- a/@types/gecko.d.ts +++ /dev/null @@ -1,525 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// https://github.com/Floorp-Projects/Floorp-core/blob/95ce9eb44c06a682e9d6379eaa4a5d1bbd5db6cd/%40types/gecko.d.ts#L198 - -/** - * Namespace anything that has its types mocked out here. These definitions are - * only "good enough" to get the type checking to pass in this directory. - * Eventually some more structured solution should be found. This namespace is - * global and makes sure that all the definitions inside do not clash with - * naming. - */ -declare namespace MockedExports { - /** - * This interface teaches ChromeUtils.import how to find modules. - */ - interface KnownModules { - "resource://gre/modules/FileUtils.sys.mjs": FileUtils; - "resource://gre/modules/FileUtils.jsm": FileUtils; - - Services: Services; - "resource://gre/modules/Services.jsm": Services; - "resource://gre/modules/AppConstants.sys.mjs": typeof AppConstantsSYSMJS; - "resource:///modules/CustomizableUI.sys.mjs": typeof CustomizableUISYSMJS; - "resource:///modules/CustomizableWidgets.sys.mjs": typeof CustomizableWidgetsSYSMJS; - "resource://devtools/shared/loader/Loader.sys.mjs": typeof LoaderESM; - //"resource://devtools/client/performance-new/shared/background.jsm.js": typeof import("resource://devtools/client/performance-new/shared/background.jsm.js"); - //"resource://devtools/client/performance-new/shared/symbolication.jsm.js": typeof import("resource://devtools/client/performance-new/shared/symbolication.jsm.js"); - "resource://devtools/shared/loader/browser-loader.js": any; - //"resource://devtools/client/performance-new/popup/menu-button.jsm.js": typeof import("resource://devtools/client/performance-new/popup/menu-button.jsm.js"); - //"resource://devtools/client/performance-new/shared/typescript-lazy-load.jsm.js": typeof import("resource://devtools/client/performance-new/shared/typescript-lazy-load.jsm.js"); - //"resource://devtools/client/performance-new/popup/logic.jsm.js": typeof import("resource://devtools/client/performance-new/popup/logic.jsm.js"); - "resource:///modules/PanelMultiView.sys.mjs": typeof PanelMultiViewSYSMJS; - } - - type Services = { - Services: import("firefox").Services; - }; - - type FileUtils = { - FileUtils: IFileUtils; - }; - - interface IFileUtils { - MODE_RDONLY: number; - MODE_WRONLY: number; - MODE_RDWR: number; - MODE_CREATE: number; - MODE_APPEND: number; - MODE_TRUNCATE: number; - - PERMS_FILE: number; - PERMS_DIRECTORY: number; - /** - * Gets a file at the specified hierarchy under a nsIDirectoryService key. - * @param key - * The Directory Service Key to start from - * @param pathArray - * An array of path components to locate beneath the directory - * specified by |key|. The last item in this array must be the - * leaf name of a file. - * @return nsIFile object for the file specified. The file is NOT created - * if it does not exist, however all required directories along - * the way are if pathArray has more than one item. - */ - getFile: (key: any, pathArray: any) => any; - /** - * Gets a directory at the specified hierarchy under a nsIDirectoryService - * key. - * @param key - * The Directory Service Key to start from - * @param pathArray - * An array of path components to locate beneath the directory - * specified by |key| - * @param shouldCreate - * true if the directory hierarchy specified in |pathArray| - * should be created if it does not exist, false otherwise. - * @return nsIFile object for the location specified. - */ - getDir: (key, pathArray, shouldCreate) => any; - /** - * Opens a file output stream for writing. - * @param file - * The file to write to. - * @param modeFlags - * (optional) File open flags. Can be undefined. - * @returns nsIFileOutputStream to write to. - * @note The stream is initialized with the DEFER_OPEN behavior flag. - * See nsIFileOutputStream. - */ - openFileOutputStream: (file, modeFlags) => any; - /** - * Opens an atomic file output stream for writing. - * @param file - * The file to write to. - * @param modeFlags - * (optional) File open flags. Can be undefined. - * @returns nsIFileOutputStream to write to. - * @note The stream is initialized with the DEFER_OPEN behavior flag. - * See nsIFileOutputStream. - * OpeanAtomicFileOutputStream is generally better than openSafeFileOutputStream - * baecause flushing is not needed in most of the issues. - */ - openAtomicFileOutputStream: (file, modeFlags) => any; - /** - * Opens a safe file output stream for writing. - * @param file - * The file to write to. - * @param modeFlags - * (optional) File open flags. Can be undefined. - * @returns nsIFileOutputStream to write to. - * @note The stream is initialized with the DEFER_OPEN behavior flag. - * See nsIFileOutputStream. - */ - openSafeFileOutputStream: (file, modeFlags) => any; - - _initFileOutputStream: (fos, file, modeFlags) => any; - /** - * Closes an atomic file output stream. - * @param stream - * The stream to close. - */ - - closeAtomicFileOutputStream: < - Stream extends - import("firefox").Components_Interfaces["nsISafeOutputStream"] & any, - >( - stream: Stream - ) => void; - /** - * Closes a safe file output stream. - * @param stream - * The stream to close. - */ - closeSafeFileOutputStream: < - Stream extends - import("firefox").Components_Interfaces["nsISafeOutputStream"] & any, - >( - stream: Stream - ) => void; - File: any; - } - - //TODO: add to window - interface MozXULElement { - /** - * Allows eager deterministic construction of XUL elements with XBL attached, by - * parsing an element tree and returning a DOM fragment to be inserted in the - * document before any of the inner elements is referenced by JavaScript. - * - * This process is required instead of calling the createElement method directly - * because bindings get attached when: - * - * 1. the node gets a layout frame constructed, or - * 2. the node gets its JavaScript reflector created, if it's in the document, - * - * whichever happens first. The createElement method would return a JavaScript - * reflector, but the element wouldn't be in the document, so the node wouldn't - * get XBL attached. After that point, even if the node is inserted into a - * document, it won't get XBL attached until either the frame is constructed or - * the reflector is garbage collected and the element is touched again. - * - * @param {string} str - * String with the XML representation of XUL elements. - * @param {string[]} [entities] - * An array of DTD URLs containing entity definitions. - * - * @return {DocumentFragment} `DocumentFragment` instance containing - * the corresponding element tree, including element nodes - * but excluding any text node. - */ - parseXULToFragment: (str: string, entities: string[]) => DocumentFragment; - } - - interface ChromeUtils { - /** - * This function reads the KnownModules and resolves which import to use. - * If you are getting the TS2345 error: - * - * Argument of type '"resource:///.../file.jsm"' is not assignable to parameter - * of type - * - * Then add the file path to the KnownModules above. - */ - import: (module: S) => KnownModules[S]; - importESModule: ( - module: S - ) => KnownModules[S]; - defineModuleGetter: (target: any, variable: string, path: string) => void; - defineESModuleGetters: (target: any, mappings: any) => void; - } - - interface MessageManager { - loadFrameScript(url: string, flag: boolean): void; - sendAsyncMessage: (event: string, data: any) => void; - addMessageListener: (event: string, listener: (event: any) => void) => void; - } - - interface Browser extends HTMLElement { - addWebTab: (url: string, options: any) => BrowserTab; - contentPrincipal: any; - selectedTab: BrowserTab; - selectedBrowser?: ChromeBrowser; - messageManager: MessageManager; - ownerDocument?: ChromeDocument; - } - - interface BrowserTab extends HTMLElement { - linkedBrowser: Browser; - } - - interface ChromeWindow { - gBrowser: Browser; - focus(): void; - openWebLinkIn( - url: string, - where: "current" | "tab" | "window", - options: Partial<{ - // Not all possible options are present, please add more if/when needed. - userContextId: number; - forceNonPrivate: boolean; - resolveOnContentBrowserCreated: ( - contentBrowser: ChromeBrowser - ) => unknown; - }> - ): void; - } - - interface ChromeBrowser { - browsingContext?: BrowsingContext; - } - - interface BrowsingContext { - /** - * A unique identifier for the browser element that is hosting this - * BrowsingContext tree. Every BrowsingContext in the element's tree will - * return the same ID in all processes and it will remain stable regardless of - * process changes. When a browser element's frameloader is switched to - * another browser element this ID will remain the same but hosted under the - * under the new browser element. - * We are using this identifier for getting the active tab ID and passing to - * the profiler back-end. See `getActiveBrowserID` for the usage. - */ - browserId: number; - } - - type GetPref = (prefName: string, defaultValue?: T) => T; - type SetPref = (prefName: string, value?: T) => T; - - type PrefObserverFunction = ( - aSubject: import("./firefox/modules/libpref/nsIPrefBranch").nsIPrefBranch, - aTopic: "nsPref:changed", - aData: string - ) => unknown; - type PrefObserver = PrefObserverFunction | { observe: PrefObserverFunction }; - - interface SharedLibrary { - start: number; - end: number; - offset: number; - name: string; - path: string; - debugName: string; - debugPath: string; - breakpadId: string; - arch: string; - } - - interface ProfileGenerationAdditionalInformation { - sharedLibraries: SharedLibrary[]; - } - - interface ProfileAndAdditionalInformation { - profile: ArrayBuffer; - additionalInformation?: ProfileGenerationAdditionalInformation; - } - - const EventEmitter: { - decorate: (target: object) => void; - }; - - const AppConstantsSYSMJS: { - AppConstants: { - platform: string; - }; - }; - - interface BrowsingContextStub {} - interface PrincipalStub {} - - interface WebChannelTarget { - browsingContext: BrowsingContextStub; - browser: Browser; - eventTarget: null; - principal: PrincipalStub; - } - - // TS-TODO - const CustomizableUISYSMJS: any; - const CustomizableWidgetsSYSMJS: any; - const PanelMultiViewSYSMJS: any; - - const LoaderESM: { - require: (path: string) => any; - }; - - //const Services: Services; - - // This class is needed by the Cc importing mechanism. e.g. - // Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); - //class nsIFilePicker {} - - interface FilePicker { - init: (window: Window, title: string, mode: number) => void; - open: (callback: (rv: number) => unknown) => void; - // The following are enum values. - modeGetFolder: number; - returnOK: number; - file: { - path: string; - }; - } - - // interface Cc { - // "@mozilla.org/filepicker;1": { - // createInstance(instance: nsIFilePicker): FilePicker; - // }; - // } - - // interface Ci { - // nsIFilePicker: nsIFilePicker; - // } - - // interface Cu { - // /** - // * This function reads the KnownModules and resolves which import to use. - // * If you are getting the TS2345 error: - // * - // * Argument of type '"resource:///.../file.jsm"' is not assignable to parameter - // * of type - // * - // * Then add the file path to the KnownModules above. - // */ - // import: (module: S) => KnownModules[S]; - // exportFunction: (fn: Function, scope: object, options?: object) => void; - // cloneInto: (value: any, scope: object, options?: object) => void; - // isInAutomation: boolean; - // } - - interface FluentLocalization { - /** - * This function sets the attributes data-l10n-id and possibly data-l10n-args - * on the element. - */ - setAttributes( - target: Element, - id?: string, - args?: Record - ): void; - } -} - -interface PathUtilsInterface { - split: (path: string) => string[]; - isAbsolute: (path: string) => boolean; -} - -// export module "resource://devtools/client/shared/vendor/react.js" { -// import * as React from "react"; -// export = React; -// } - -// declare module "resource://devtools/client/shared/vendor/react-dom-factories.js" { -// import * as ReactDomFactories from "react-dom-factories"; -// export = ReactDomFactories; -// } - -// declare module "resource://devtools/client/shared/vendor/redux.js" { -// import * as Redux from "redux"; -// export = Redux; -// } - -// declare module "resource://devtools/client/shared/vendor/react-redux.js" { -// import * as ReactRedux from "react-redux"; -// export = ReactRedux; -// } - -// declare module "resource://devtools/shared/event-emitter2.js" { -// export = MockedExports.EventEmitter; -// } - -// declare module "Services" { -// export = Services; -// } - -// declare module "ChromeUtils" { -// export = ChromeUtils; -// } - -// declare module "resource://gre/modules/AppConstants.sys.mjs" { -// export = MockedExports.AppConstantsSYSMJS; -// } - -// declare module "resource://devtools/client/performance-new/shared/background.jsm.js" { -// import * as Background from "devtools/client/performance-new/shared/background.jsm.js"; -// export = Background; -// } - -// declare module "resource://devtools/client/performance-new/shared/symbolication.jsm.js" { -// import * as PerfSymbolication from "devtools/client/performance-new/shared/symbolication.jsm.js"; -// export = PerfSymbolication; -// } - -// declare module "resource:///modules/CustomizableUI.sys.mjs" { -// export = MockedExports.CustomizableUISYSMJS; -// } - -// declare module "resource:///modules/CustomizableWidgets.sys.mjs" { -// export = MockedExports.CustomizableWidgetsSYSMJS; -// } - -// declare module "resource:///modules/PanelMultiView.sys.mjs" { -// export = MockedExports.PanelMultiViewSYSMJS; -// } - -// declare module "resource://devtools/shared/loader/Loader.sys.mjs" { -// export = MockedExports.LoaderESM; -// } - -declare var ChromeUtils: MockedExports.ChromeUtils; - -declare var PathUtils: PathUtilsInterface; - -/** - * This is a variant on the normal Document, as it contains chrome-specific properties. - */ -declare interface ChromeDocument extends Document { - /** - * Create a XUL element of a specific type. Right now this function - * only refines iframes, but more tags could be added. - */ - createXULElement: ((type: "iframe") => XULIframeElement) & - ((type: string) => XULElement); - - /** - * This is a fluent instance connected to this document. - */ - l10n: MockedExports.FluentLocalization; -} - -/** - * This is a variant on the HTMLElement, as it contains chrome-specific properties. - */ -declare interface ChromeHTMLElement extends HTMLElement { - ownerDocument: ChromeDocument; -} - -declare interface XULElement extends HTMLElement { - ownerDocument: ChromeDocument; -} - -declare interface XULIframeElement extends XULElement { - contentWindow: ChromeWindow; - src: string; -} - -declare interface ChromeWindow extends Window { - openWebLinkIn: ( - url: string, - where: "current" | "tab" | "tabshifted" | "window" | "save", - // TS-TODO - params?: unknown - ) => void; - openTrustedLinkIn: ( - url: string, - where: "current" | "tab" | "tabshifted" | "window" | "save", - // TS-TODO - params?: unknown - ) => void; -} - -declare class ChromeWorker extends Worker {} - -declare interface MenuListElement extends XULElement { - value: string; - disabled: boolean; -} - -declare interface XULCommandEvent extends Event { - target: XULElement; -} - -declare interface XULElementWithCommandHandler { - addEventListener: ( - type: "command", - handler: (event: XULCommandEvent) => void, - isCapture?: boolean - ) => void; - removeEventListener: ( - type: "command", - handler: (event: XULCommandEvent) => void, - isCapture?: boolean - ) => void; -} - -//declare type nsIPrefBranch = MockedExports.nsIPrefBranch; - -// chrome context-only DOM isInstance method -// XXX: This hackishly extends Function because there is no way to extend DOM constructors. -// Callers should manually narrow the type when needed. -// See also https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/222 -interface Function { - isInstance(obj: any): boolean; -} - -declare module "resource://gre/modules/FileUtils.sys.mjs" { - const FileUtils: MockedExports.IFileUtils; - export { FileUtils }; -} - -// Extend "window" to extend "ChromeWindow" -declare global { - interface Window extends ChromeWindow {} -} \ No newline at end of file diff --git a/@types/split-views.d.ts b/@types/split-views.d.ts deleted file mode 100644 index 839eba3..0000000 --- a/@types/split-views.d.ts +++ /dev/null @@ -1,13 +0,0 @@ - -declare type SplitType = 'horizontal' | 'vertical' | 'grid'; - -declare interface SplitViewConfig extends Config { - splitIndicator: string; // e.g. "split-tab='true'" - defaultSplitView: SplitType; -}; - -declare interface SplitView { - type: SplitType; - tabs: MockedExports.BrowserTab[]; - id: number; -}; diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 06ed587..0000000 --- a/package-lock.json +++ /dev/null @@ -1,1551 +0,0 @@ -{ - "name": "components", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "components", - "version": "1.0.0", - "license": "ISC", - "devDependencies": { - "ts-loader": "^9.5.1", - "typescript": "^5.5.4", - "webpack": "^5.93.0", - "webpack-cli": "^5.1.4" - } - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@types/eslint": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.0.tgz", - "integrity": "sha512-gi6WQJ7cHRgZxtkQEoyHMppPjq9Kxo5Tjn2prSKDSmZrCz8TZ3jSRCeTJm+WoM+oB0WG37bRqLzaaU3q7JypGg==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, - "node_modules/@types/node": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", - "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==", - "dev": true, - "dependencies": { - "undici-types": "~6.13.0" - } - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", - "dev": true, - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "dev": true, - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "dev": true, - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "dev": true, - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webpack-cli/configtest": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", - "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/info": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", - "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/serve": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", - "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "dev": true, - "peerDependencies": { - "acorn": "^8" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", - "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001646", - "electron-to-chromium": "^1.5.4", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001649", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001649.tgz", - "integrity": "sha512-fJegqZZ0ZX8HOWr6rcafGr72+xcgJKI9oWfDW5DrD7ExUtgZC7a7R7ZYmZqplh7XDocFdGeIFn7roAxhOeYrPQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", - "dev": true, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.4.tgz", - "integrity": "sha512-orzA81VqLyIGUEA77YkVA1D+N+nNfl2isJVjjmOyrlxuooZ19ynb+dOlaDTqd/idKRS9lDCSBmtzM+kyCsMnkA==", - "dev": true - }, - "node_modules/enhanced-resolve": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", - "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/envinfo": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", - "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", - "dev": true, - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/es-module-lexer": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", - "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", - "dev": true - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true, - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/import-local": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", - "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", - "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/is-core-module": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", - "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", - "dev": true, - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "dev": true, - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", - "dev": true, - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", - "dev": true - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dev": true, - "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/terser": { - "version": "5.31.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.3.tgz", - "integrity": "sha512-pAfYn3NIZLyZpa83ZKigvj6Rn9c/vd5KfYGX7cN1mnzqgDcxWvrU5ZtAfIKhEXz9nRecw4z3LXkjaq96/qZqAA==", - "dev": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.20", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/ts-loader": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", - "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4", - "source-map": "^0.7.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "typescript": "*", - "webpack": "^5.0.0" - } - }, - "node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", - "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==", - "dev": true - }, - "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/watchpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", - "dev": true, - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack": { - "version": "5.93.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", - "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", - "dev": true, - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.0", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-cli": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", - "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", - "dev": true, - "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.1", - "@webpack-cli/info": "^2.0.2", - "@webpack-cli/serve": "^2.0.5", - "colorette": "^2.0.14", - "commander": "^10.0.1", - "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "5.x.x" - }, - "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/webpack-cli/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "dev": true, - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "dev": true - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index 44209f0..0000000 --- a/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "components", - "version": "1.0.0", - "description": "Some components used by @zen-browser and @Floorp-Projects as an attempt to make firefox forks a better place", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "check": "tsc" - }, - "keywords": [], - "author": "", - "license": "ISC", - "devDependencies": { - "typescript": "^5.5.4" - } -} diff --git a/src/ZenSidebarManager.mjs b/src/ZenSidebarManager.mjs new file mode 100644 index 0000000..cea753f --- /dev/null +++ b/src/ZenSidebarManager.mjs @@ -0,0 +1,551 @@ + + + +export var gZenBrowserManagerSidebar = { + _sidebarElement: null, + _currentPanel: null, + _lastOpenedPanel: null, + _hasChangedConfig: true, + _splitterElement: null, + _hSplitterElement: null, + _hasRegisteredPinnedClickOutside: false, + _isDragging: false, + contextTab: null, + + DEFAULT_MOBILE_USER_AGENT: "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36 Edg/114.0.1823.79", + MAX_SIDEBAR_PANELS: 8, // +1 for the add panel button + MAX_RUNS: 3, + + init() { + this.update(); + this.close(); // avoid caching + this.listenForPrefChanges(); + this.insertIntoContextMenu(); + }, + + get sidebarData() { + let services = Services.prefs.getStringPref("zen.sidebar.data"); + if (services === "") { + return {}; + } + return JSON.parse(services); + }, + + get shouldCloseOnBlur() { + return Services.prefs.getBoolPref("zen.sidebar.close-on-blur"); + }, + + listenForPrefChanges() { + Services.prefs.addObserver("zen.sidebar.data", this.handleEvent.bind(this)); + Services.prefs.addObserver("zen.sidebar.enabled", this.handleEvent.bind(this)); + + let sidebar = document.getElementById("zen-sidebar-web-panel"); + this.splitterElement.addEventListener("mousedown", (function(event) { + let computedStyle = window.getComputedStyle(sidebar); + let maxWidth = parseInt(computedStyle.getPropertyValue("max-width").replace("px", "")); + let minWidth = parseInt(computedStyle.getPropertyValue("min-width").replace("px", "")); + + if (!this._isDragging) { // Prevent multiple resizes + this._isDragging = true; + let sidebarWidth = sidebar.getBoundingClientRect().width; + let startX = event.clientX; + let startWidth = sidebarWidth; + let mouseMove = (function(e) { + let newWidth = startWidth + e.clientX - startX; + if (newWidth <= minWidth+10) { + newWidth = minWidth+1; + } else if (newWidth >= maxWidth-10) { + newWidth = maxWidth-1; + } + sidebar.style.width = `${newWidth}px`; + }); + let mouseUp = (function() { + this.handleEvent(); + this._isDragging = false; + document.removeEventListener("mousemove", mouseMove); + document.removeEventListener("mouseup", mouseUp); + }).bind(this); + document.addEventListener("mousemove", mouseMove); + document.addEventListener("mouseup", mouseUp); + } + }).bind(this)); + + this.hSplitterElement.addEventListener("mousedown", (function(event) { + let computedStyle = window.getComputedStyle(sidebar); + const parent = sidebar.parentElement; + // relative to avoid the top margin + // 20px is the padding + let parentRelativeHeight = parent.getBoundingClientRect().height - parent.getBoundingClientRect().top + 20; + let minHeight = parseInt(computedStyle.getPropertyValue("min-height").replace("px", "")); + if (!this._isDragging) { // Prevent multiple resizes + this._isDragging = true; + let sidebarHeight = sidebar.getBoundingClientRect().height; + let startY = event.clientY; + let startHeight = sidebarHeight; + let mouseMove = (function(e) { + let newHeight = startHeight + e.clientY - startY; + if (newHeight <= minHeight+10) { + newHeight = minHeight+1; + } else if (newHeight >= parentRelativeHeight) { // 10px is the padding + newHeight = parentRelativeHeight; + } + sidebar.style.height = `${newHeight}px`; + }); + let mouseUp = (function() { + this.handleEvent(); + this._isDragging = false; + document.removeEventListener("mousemove", mouseMove); + document.removeEventListener("mouseup", mouseUp); + }).bind(this); + document.addEventListener("mousemove", mouseMove); + document.addEventListener("mouseup", mouseUp); + } + }).bind(this)); + + this.handleEvent(); + }, + + get isFloating() { + return document.getElementById("zen-sidebar-web-panel").hasAttribute("pinned"); + }, + + handleEvent() { + this._hasChangedConfig = true; + this.update(); + this._hasChangedConfig = false; + + // https://stackoverflow.com/questions/11565471/removing-event-listener-which-was-added-with-bind + var clickOutsideHandler = this._handleClickOutside.bind(this); + let isFloating = this.isFloating; + if (isFloating && !this._hasRegisteredPinnedClickOutside) { + document.addEventListener("mouseup", clickOutsideHandler); + this._hasRegisteredPinnedClickOutside = true; + } else if (!isFloating && this._hasRegisteredPinnedClickOutside) { + document.removeEventListener("mouseup", clickOutsideHandler); + this._hasRegisteredPinnedClickOutside = false; + } + + const button = document.getElementById("zen-sidepanel-button"); + if (Services.prefs.getBoolPref("zen.sidebar.enabled")) { + button.removeAttribute("hidden"); + } else { + button.setAttribute("hidden", "true"); + this._closeSidebarPanel(); + return; + } + }, + + _handleClickOutside(event) { + let sidebar = document.getElementById("zen-sidebar-web-panel"); + if (!sidebar.hasAttribute("pinned") || this._isDragging || !this.shouldCloseOnBlur) { + return; + } + let target = event.target; + const closestSelector = [ + "#zen-sidebar-web-panel", + "#zen-sidebar-panels-wrapper", + "#zenWebPanelContextMenu", + "#zen-sidebar-web-panel-splitter", + "#contentAreaContextMenu" + ].join(", "); + if (target.closest(closestSelector)) { + return; + } + this.close(); + }, + + toggle() { + if (!this._currentPanel) { + this._currentPanel = this._lastOpenedPanel; + } + if (document.getElementById("zen-sidebar-web-panel").hasAttribute("hidden")) { + this.open(); + return; + } + this.close(); + }, + + open() { + let sidebar = document.getElementById("zen-sidebar-web-panel"); + sidebar.removeAttribute("hidden"); + this.update(); + }, + + update() { + this._updateWebPanels(); + this._updateSidebarButton(); + this._updateWebPanel(); + this._updateButtons(); + }, + + _updateSidebarButton() { + let button = document.getElementById("zen-sidepanel-button"); + if (!document.getElementById("zen-sidebar-web-panel").hasAttribute("hidden")) { + button.setAttribute("open", "true"); + } else { + button.removeAttribute("open"); + } + }, + + _updateWebPanels() { + if (Services.prefs.getBoolPref("zen.sidebar.enabled")) { + this.sidebarElement.removeAttribute("hidden"); + } else { + this.sidebarElement.setAttribute("hidden", "true"); + this._closeSidebarPanel(); + return; + } + + let data = this.sidebarData; + if (!data.data || !data.index) { + return; + } + this.sidebarElement.innerHTML = ""; + for (let site of data.index) { + let panel = data.data[site]; + if (!panel || !panel.url) { + continue; + } + let button = document.createXULElement("toolbarbutton"); + button.classList.add("zen-sidebar-panel-button", "toolbarbutton-1", "chromeclass-toolbar-additional"); + button.setAttribute("flex", "1"); + button.setAttribute("zen-sidebar-id", site); + button.setAttribute("context", "zenWebPanelContextMenu"); + this._getWebPanelIcon(panel.url, button); + button.addEventListener("click", this._handleClick.bind(this)); + this.sidebarElement.appendChild(button); + } + const addButton = document.getElementById("zen-sidebar-add-panel-button"); + if (data.index.length < this.MAX_SIDEBAR_PANELS) { + addButton.removeAttribute("hidden"); + } else { + addButton.setAttribute("hidden", "true"); + } + }, + + async _openAddPanelDialog() { + let dialogURL = "chrome://browser/content/places/zenNewWebPanel.xhtml"; + let features = "centerscreen,chrome,modal,resizable=no"; + let aParentWindow = Services.wm.getMostRecentWindow("navigator:browser"); + + if (aParentWindow?.gDialogBox) { + await aParentWindow.gDialogBox.open(dialogURL, {}); + } else { + aParentWindow.openDialog(dialogURL, "", features, {}); + } + }, + + _setPinnedToElements() { + let sidebar = document.getElementById("zen-sidebar-web-panel"); + sidebar.setAttribute("pinned", "true"); + document.getElementById("zen-sidebar-web-panel-pinned").setAttribute("pinned", "true"); + }, + + _removePinnedFromElements() { + let sidebar = document.getElementById("zen-sidebar-web-panel"); + sidebar.removeAttribute("pinned"); + document.getElementById("zen-sidebar-web-panel-pinned").removeAttribute("pinned"); + }, + + _closeSidebarPanel() { + let sidebar = document.getElementById("zen-sidebar-web-panel"); + sidebar.setAttribute("hidden", "true"); + this._lastOpenedPanel = this._currentPanel; + this._currentPanel = null; + }, + + _handleClick(event) { + let target = event.target; + let panelId = target.getAttribute("zen-sidebar-id"); + if (this._currentPanel === panelId) { + return; + } + this._currentPanel = panelId; + this._updateWebPanel(); + }, + + _createNewPanel(url) { + let data = this.sidebarData; + let newName = "p" + new Date().getTime(); + data.index.push(newName); + data.data[newName] = { + url: url, + ua: false, + }; + Services.prefs.setStringPref("zen.sidebar.data", JSON.stringify(data)); + this._currentPanel = newName; + this.open(); + }, + + _updateButtons() { + for (let button of this.sidebarElement.querySelectorAll(".zen-sidebar-panel-button")) { + if (button.getAttribute("zen-sidebar-id") === this._currentPanel) { + button.setAttribute("selected", "true"); + } else { + button.removeAttribute("selected"); + } + } + }, + + _hideAllWebPanels() { + let sidebar = document.getElementById("zen-sidebar-web-panel"); + for (let browser of sidebar.querySelectorAll("browser[zen-sidebar-id]")) { + browser.setAttribute("hidden", "true"); + browser.docShellIsActive = false; + } + }, + + get introductionPanel() { + return document.getElementById("zen-sidebar-introduction-panel"); + }, + + _updateWebPanel() { + this._updateButtons(); + let sidebar = document.getElementById("zen-sidebar-web-panel"); + this._hideAllWebPanels(); + if (!this._currentPanel) { + this.introductionPanel.removeAttribute("hidden"); + return; + } + this.introductionPanel.setAttribute("hidden", "true"); + let existantWebview = this._getCurrentBrowser(); + if (existantWebview) { + existantWebview.docShellIsActive = true; + existantWebview.removeAttribute("hidden"); + document.getElementById("zen-sidebar-web-panel-title").textContent = existantWebview.contentTitle; + return; + } + let data = this._getWebPanelData(this._currentPanel); + let browser = this._createWebPanelBrowser(data); + let browserContainers = document.getElementById("zen-sidebar-web-panel-browser-containers"); + browserContainers.appendChild(browser); + if (data.ua) { + browser.browsingContext.customUserAgent = this.DEFAULT_MOBILE_USER_AGENT; + } + browser.docShellIsActive = true; + }, + + _getWebPanelData(id) { + let data = this.sidebarData; + let panel = data.data[id]; + if (!panel || !panel.url) { + return {}; + } + return { + id: id, + ...panel, + }; + }, + + _createWebPanelBrowser(data) { + const titleContainer = document.getElementById("zen-sidebar-web-panel-title"); + titleContainer.textContent = "Loading..."; + let browser = gBrowser.createBrowser({}); + browser.setAttribute("disablefullscreen", "true"); + browser.setAttribute("src", data.url); + browser.setAttribute("zen-sidebar-id", data.id); + browser.setAttribute("disableglobalhistory", "true"); + browser.setAttribute("autoscroll", "false"); + browser.setAttribute("autocompletepopup", "PopupAutoComplete"); + browser.setAttribute("contextmenu", "contentAreaContextMenu"); + browser.setAttribute("disablesecurity", "true"); + browser.addEventListener("pagetitlechanged", (function(event) { + let browser = event.target; + let title = browser.contentTitle; + if (!title) { + return; + } + let id = browser.getAttribute("zen-sidebar-id"); + if (id === this._currentPanel) { + titleContainer.textContent = title; + } + }).bind(this)); + return browser; + }, + + _getWebPanelIcon(url, element) { + let { preferredURI } = Services.uriFixup.getFixupURIInfo(url); + element.setAttribute("image", `page-icon:${preferredURI.spec}`); + fetch(`https://s2.googleusercontent.com/s2/favicons?domain_url=${preferredURI.spec}`).then(async response => { + if (response.ok) { + let blob = await response.blob(); + let reader = new FileReader(); + reader.onload = function() { + element.setAttribute("image", reader.result); + }; + reader.readAsDataURL(blob); + } + }); + }, + + _getBrowserById(id) { + let sidebar = document.getElementById("zen-sidebar-web-panel"); + return sidebar.querySelector(`browser[zen-sidebar-id="${id}"]`); + }, + + _getCurrentBrowser() { + return this._getBrowserById(this._currentPanel); + }, + + reload() { + let browser = this._getCurrentBrowser(); + if (browser) { + browser.reload(); + } + }, + + forward() { + let browser = this._getCurrentBrowser(); + if (browser) { + browser.goForward(); + } + }, + + back() { + let browser = this._getCurrentBrowser(); + if (browser) { + browser.goBack(); + } + }, + + home() { + let browser = this._getCurrentBrowser(); + if (browser) { + browser.gotoIndex(); + } + }, + + close() { + this._hideAllWebPanels(); + this._closeSidebarPanel(); + this._updateSidebarButton(); + }, + + togglePinned(elem) { + let sidebar = document.getElementById("zen-sidebar-web-panel"); + if (sidebar.hasAttribute("pinned")) { + this._removePinnedFromElements(); + } else { + this._setPinnedToElements(); + } + this.update(); + }, + + get sidebarElement() { + if (!this._sidebarElement) { + this._sidebarElement = document.getElementById("zen-sidebar-panels-sites"); + } + return this._sidebarElement; + }, + + get splitterElement() { + if (!this._splitterElement) { + this._splitterElement = document.getElementById("zen-sidebar-web-panel-splitter"); + } + return this._splitterElement; + }, + + get hSplitterElement() { + if (!this._hSplitterElement) { + this._hSplitterElement = document.getElementById("zen-sidebar-web-panel-hsplitter"); + } + return this._hSplitterElement; + }, + + // Context menu + + updateContextMenu(aPopupMenu) { + let panel = + aPopupMenu.triggerNode && + (aPopupMenu.triggerNode || aPopupMenu.triggerNode.closest("toolbarbutton[zen-sidebar-id]")); + if (!panel) { + return; + } + let id = panel.getAttribute("zen-sidebar-id"); + this.contextTab = id; + let data = this._getWebPanelData(id); + let browser = this._getBrowserById(id); + let isMuted = browser && browser.audioMuted; + let mutedContextItem = document.getElementById("context_zenToggleMuteWebPanel"); + document.l10n.setAttributes(mutedContextItem, + !isMuted ? "zen-web-side-panel-context-mute-panel" : "zen-web-side-panel-context-unmute-panel"); + if (!isMuted) { + mutedContextItem.setAttribute("muted", "true"); + } else { + mutedContextItem.removeAttribute("muted"); + } + document.l10n.setAttributes(document.getElementById("context_zenToogleUAWebPanel"), + data.ua ? "zen-web-side-panel-context-disable-ua" : "zen-web-side-panel-context-enable-ua"); + if (!browser) { + document.getElementById("context_zenUnloadWebPanel").setAttribute("disabled", "true"); + } else { + document.getElementById("context_zenUnloadWebPanel").removeAttribute("disabled"); + } + }, + + contextOpenNewTab() { + let browser = this._getBrowserById(this.contextTab); + let data = this.sidebarData; + let panel = data.data[this.contextTab]; + let url = (browser == null) ? panel.url : browser.currentURI.spec; + gZenUIManager.openAndChangeToTab(url); + this.close(); + }, + + contextToggleMuteAudio() { + let browser = this._getBrowserById(this.contextTab); + if (browser.audioMuted) { + browser.unmute(); + } else { + browser.mute(); + } + }, + + contextToggleUserAgent() { + let browser = this._getBrowserById(this.contextTab); + browser.browsingContext.customUserAgent = browser.browsingContext.customUserAgent ? null : this.DEFAULT_MOBILE_USER_AGENT; + let data = this.sidebarData; + data.data[this.contextTab].ua = !data.data[this.contextTab].ua; + Services.prefs.setStringPref("zen.sidebar.data", JSON.stringify(data)); + browser.reload(); + }, + + contextDelete() { + let data = this.sidebarData; + delete data.data[this.contextTab]; + data.index = data.index.filter(id => id !== this.contextTab); + let browser = this._getBrowserById(this.contextTab); + if (browser) { + browser.remove(); + } + this._currentPanel = null; + this._lastOpenedPanel = null; + this.update(); + Services.prefs.setStringPref("zen.sidebar.data", JSON.stringify(data)); + }, + + contextUnload() { + let browser = this._getBrowserById(this.contextTab); + browser.remove(); + this._closeSidebarPanel(); + this.close(); + this._lastOpenedPanel = null; + }, + + insertIntoContextMenu() { + const sibling = document.getElementById("context-stripOnShareLink"); + const menuitem = document.createXULElement("menuitem"); + menuitem.setAttribute("id", "context-zenAddToWebPanel"); + menuitem.setAttribute("hidden", "true"); + menuitem.setAttribute("oncommand", "gZenBrowserManagerSidebar.addPanelFromContextMenu();"); + menuitem.setAttribute("data-l10n-id", "zen-web-side-panel-context-add-to-panel"); + sibling.insertAdjacentElement("afterend", menuitem); + }, + + addPanelFromContextMenu() { + const url = gContextMenu.linkURL || gContextMenu.target.ownerDocument.location.href; + this._createNewPanel(url); + }, +}; + +gZenBrowserManagerSidebar.init(); diff --git a/src/ZenViewSplitter.mjs b/src/ZenViewSplitter.mjs new file mode 100644 index 0000000..ef295e8 --- /dev/null +++ b/src/ZenViewSplitter.mjs @@ -0,0 +1,349 @@ + +export var gZenViewSplitter = { + /** + * [ + * { + * tabs: [ + * tab1, + * tab2, + * tab3, + * ], + * gridType: "vsep" | "hsep" | "grid", + * } + * ] + */ + _data: [], + currentView: -1, + + init() { + Services.prefs.setBoolPref("zen.splitView.working", false); + window.addEventListener("TabClose", this); + this.initializeUI(); + console.log("ZenViewSplitter initialized"); + }, + + initializeUI() { + this.insertIntoContextMenu(); + this.initializeUpdateContextMenuItems(); + this.initializeTabContextMenu(); + this.initializeZenSplitBox(); + }, + + initializeZenSplitBox() { + const fragment = window.MozXULElement.parseXULToFragment(` + `); + document.getElementById("star-button-box").after(fragment); + }, + + initializeTabContextMenu() { + const fragment = window.MozXULElement.parseXULToFragment(` + + + `); + document.getElementById("tabContextMenu").appendChild(fragment); + }, + + initializeUpdateContextMenuItems() { + const contentAreaContextMenu = document.getElementById("tabContextMenu"); + contentAreaContextMenu.addEventListener("popupshowing", () => { + const tabCountInfo = JSON.stringify({ + tabCount: window.gBrowser.selectedTabs.length, + }); + document + .getElementById("context_zenSplitTabs") + .setAttribute("data-l10n-args", tabCountInfo); + document.getElementById("context_zenSplitTabs").disabled = + !this.contextCanSplitTabs(); + }); + }, + + handleEvent(event) { + switch (event.type) { + case "TabClose": + this.onTabClose(event); + } + }, + + insertIntoContextMenu() { + const sibling = document.getElementById("context-stripOnShareLink"); + const menuitem = document.createXULElement("menuitem"); + menuitem.setAttribute("id", "context-zenSplitLink"); + menuitem.setAttribute("hidden", "true"); + menuitem.setAttribute("oncommand", "gZenViewSplitter.contextSplitLink();"); + menuitem.setAttribute("data-l10n-id", "zen-split-link"); + const separator = document.createXULElement("menuseparator"); + sibling.insertAdjacentElement("afterend", menuitem); + sibling.insertAdjacentElement("afterend", separator); + }, + + get tabBrowserPanel() { + if (!this._tabBrowserPanel) { + this._tabBrowserPanel = document.getElementById("tabbrowser-tabpanels"); + } + return this._tabBrowserPanel; + }, + + onTabClose(event) { + const tab = event.target; + let index = this._data.findIndex((group) => group.tabs.includes(tab)); + if (index < 0) { + return; + } + let dataTab = this._data[index].tabs; + dataTab.splice(dataTab.indexOf(tab), 1); + tab._zenSplitted = false; + tab.linkedBrowser.zenModeActive = false; + let container = tab.linkedBrowser.closest(".browserSidebarContainer"); + container.removeAttribute("zen-split"); + if (!event.forUnsplit) { + tab.linkedBrowser.docShellIsActive = false; + container.style.display = "none"; + } else { + container.style.gridArea = "1 / 1"; + } + if (dataTab.length < 2) { + this._data.splice(index, 1); + if (this.currentView == index) { + console.assert(dataTab.length == 1, "Data tab length is not 1"); + this.currentView = -1; + this.tabBrowserPanel.removeAttribute("zen-split-view"); + this.tabBrowserPanel.style.gridTemplateAreas = ""; + this.tabBrowserPanel.style.gridGap = "0px"; + Services.prefs.setBoolPref("zen.splitView.working", false); + for (const tab of dataTab) { + let container = tab.linkedBrowser.closest(".browserSidebarContainer"); + container.removeAttribute("zen-split"); + container.style.gridArea = "1 / 1"; + tab._zenSplitted = false; + } + } + return; + } + let lastTab = dataTab[dataTab.length - 1]; + this._showSplitView(lastTab); + }, + + contextSplitLink() { + const url = gContextMenu.linkURL || gContextMenu.target.ownerDocument.location.href; + const tab = gBrowser.selectedTab; + const newTab = gZenUIManager.openAndChangeToTab(url); + this.splitTabs([tab, newTab]); + }, + + onLocationChange(browser) { + let tab = gBrowser.getTabForBrowser(browser); + this.updateSplitViewButton(!(tab && tab._zenSplitted)); + if (!tab) { + return; + } + + this._showSplitView(tab); + }, + + splitTabs(tabs) { + if (tabs.length < 2) { + return; + } + // Check if any tab is already split + for (const tab of tabs) { + if (tab._zenSplitted) { + let index = this._data.findIndex((group) => group.tabs.includes(tab)); + if (index < 0) { + return; + } + this._showSplitView(tab); + return; + } + } + this._data.push({ + tabs, + gridType: "grid", + }); + gBrowser.selectedTab = tabs[0]; + this._showSplitView(tabs[0]); + }, + + _showSplitView(tab) { + const splitData = this._data.find((group) => group.tabs.includes(tab)); + function modifyDecks(tabs, add) { + for (const tab of tabs) { + tab.linkedBrowser.zenModeActive = add; + tab.linkedBrowser.docShellIsActive = add; + let browser = tab.linkedBrowser.closest(".browserSidebarContainer"); + if (add) { + browser.setAttribute("zen-split", "true"); + continue; + } + browser.removeAttribute("zen-split"); + } + } + const handleClick = (tab) => { + return ((event) => { + gBrowser.selectedTab = tab; + }) + }; + if (!splitData || (this.currentView >= 0 && !this._data[this.currentView].tabs.includes(tab))) { + this.updateSplitViewButton(true); + if (this.currentView < 0) { + return; + } + for (const tab of this._data[this.currentView].tabs) { + //tab._zenSplitted = false; + let container = tab.linkedBrowser.closest(".browserSidebarContainer"); + container.removeAttribute("zen-split-active"); + container.classList.remove("deck-selected"); + console.assert(container, "No container found for tab"); + container.removeEventListener("click", handleClick(tab)); + container.style.gridArea = ""; + } + this.tabBrowserPanel.removeAttribute("zen-split-view"); + this.tabBrowserPanel.style.gridTemplateAreas = ""; + Services.prefs.setBoolPref("zen.splitView.working", false); + modifyDecks(this._data[this.currentView].tabs, false); + // console.log("Setting the active tab to be active", gBrowser.selectedTab); + gBrowser.selectedTab.linkedBrowser.docShellIsActive = true; // Make sure the active tab is active + this.currentView = -1; + if (!splitData) { + return; + } + } + this.tabBrowserPanel.setAttribute("zen-split-view", "true"); + Services.prefs.setBoolPref("zen.splitView.working", true); + this.currentView = this._data.indexOf(splitData); + let gridType = splitData.gridType || "grid"; // TODO: let user decide the grid type + let i = 0; + // 2 rows, infinite columns + let currentRowGridArea = ["", ""/* first row, second row */]; + let numberOfRows = 0; + for (const _tab of splitData.tabs) { + _tab._zenSplitted = true; + let container = _tab.linkedBrowser.closest(".browserSidebarContainer"); + console.assert(container, "No container found for tab"); + container.removeAttribute("zen-split-active"); + if (_tab == tab) { + container.setAttribute("zen-split-active", "true"); + } + container.setAttribute("zen-split-anim", "true"); + container.addEventListener("click", handleClick(_tab)); + // Set the grid type for the container. If the grid type is not "grid", then set the grid type contain + // each column or row. If it's "grid", then try to create + if (gridType == "grid") { + // Each 2 tabs, create a new row + if (i % 2 == 0) { + currentRowGridArea[0] += ` tab${i + 1}`; + } else { + currentRowGridArea[1] += ` tab${i + 1}`; + numberOfRows++; + } + container.style.gridArea = `tab${i + 1}`; + } + i++; + } + if (gridType == "grid") { + if ((numberOfRows < splitData.tabs.length / 2) && (splitData.tabs.length != 2)) { + // Make the last tab occupy the last row + currentRowGridArea[1] += ` tab${i}`; + } + if (gridType == "grid" && (splitData.tabs.length === 2)) { + currentRowGridArea[0] = `tab1 tab2`; + currentRowGridArea[1] = ""; + } + this.tabBrowserPanel.style.gridTemplateAreas = `'${currentRowGridArea[0]}'`; + if (currentRowGridArea[1] != "") { + this.tabBrowserPanel.style.gridTemplateAreas += ` '${currentRowGridArea[1]}'`; + } + } else if (gridType == "vsep") { + this.tabBrowserPanel.style.gridTemplateAreas = `'${splitData.tabs.map((_, i) => `tab${i + 1}`).join(" ")}'`; + } else if (gridType == "hsep") { + this.tabBrowserPanel.style.gridTemplateAreas = `${splitData.tabs.map((_, i) => `'tab${i + 1}'`).join(" ")}`; + } + modifyDecks(splitData.tabs, true); + this.updateSplitViewButton(false); + }, + + contextSplitTabs() { + let tabs = gBrowser.selectedTabs; + this.splitTabs(tabs); + }, + + contextCanSplitTabs() { + if (gBrowser.selectedTabs.length < 2) { + return false; + } + // Check if any tab is already split + for (const tab of gBrowser.selectedTabs) { + if (tab._zenSplitted) { + return false; + } + } + return true; + }, + + // Panel and url button + + updateSplitViewButton(hidden) { + let button = document.getElementById("zen-split-views-box"); + if (hidden) { + button.setAttribute("hidden", "true"); + return; + } + button.removeAttribute("hidden"); + }, + + get _modifierElement() { + if (!this.__modifierElement) { + let wrapper = document.getElementById("template-zen-split-view-modifier"); + const panel = wrapper.content.firstElementChild; + wrapper.replaceWith(wrapper.content); + this.__modifierElement = panel; + } + return this.__modifierElement; + }, + + async openSplitViewPanel(event) { + let panel = this._modifierElement; + let target = event.target.parentNode; + for (const gridType of ["hsep", "vsep", "grid", "unsplit"]) { + let selector = panel.querySelector(`.zen-split-view-modifier-preview.${gridType}`); + selector.classList.remove("active"); + if (this.currentView >= 0 && this._data[this.currentView].gridType == gridType) { + selector.classList.add("active"); + } + if (this.__hasSetMenuListener) { + continue; + } + selector.addEventListener("click", ((gridType) => { + if (gridType === "unsplit") { + let currentTab = gBrowser.selectedTab; + let tabs = this._data[this.currentView].tabs; + for (const tab of tabs) { + this.onTabClose({ target: tab, forUnsplit: true }); + } + gBrowser.selectedTab = currentTab; + panel.hidePopup(); + this.updateSplitViewButton(true); + return; + } + this._data[this.currentView].gridType = gridType; + this._showSplitView(gBrowser.selectedTab); + panel.hidePopup(); + }).bind(this, gridType)); + } + this.__hasSetMenuListener = true; + PanelMultiView.openPopup(panel, target, { + position: "bottomright topright", + triggerEvent: event, + }).catch(console.error); + }, +}; + +gZenViewSplitter.init(); \ No newline at end of file diff --git a/src/ZenWorkspaces.mjs b/src/ZenWorkspaces.mjs new file mode 100644 index 0000000..41c6501 --- /dev/null +++ b/src/ZenWorkspaces.mjs @@ -0,0 +1,426 @@ + +export var ZenWorkspaces = { + async init() { + let docElement = document.documentElement; + if (docElement.getAttribute("chromehidden").includes("toolbar") + || docElement.getAttribute("chromehidden").includes("menubar") + || docElement.hasAttribute("privatebrowsingmode")) { + console.warn("ZenWorkspaces: !!! ZenWorkspaces is disabled in hidden windows !!!"); + return; // We are in a hidden window, don't initialize ZenWorkspaces + } + console.log("ZenWorkspaces: Initializing ZenWorkspaces..."); + await this.initializeWorkspaces(); + console.log("ZenWorkspaces: ZenWorkspaces initialized"); + }, + + get workspaceEnabled() { + return Services.prefs.getBoolPref("zen.workspaces.enabled", false); + }, + + // Wrorkspaces saving/loading + get _storeFile() { + return PathUtils.join( + PathUtils.profileDir, + "zen-workspaces", + "Workspaces.json", + ); + }, + + async _workspaces() { + if (!this._workspaceCache) { + this._workspaceCache = await IOUtils.readJSON(this._storeFile); + if (!this._workspaceCache.workspaces) { + this._workspaceCache.workspaces = []; + } + } + return this._workspaceCache; + }, + + onWorkspacesEnabledChanged() { + if (this.workspaceEnabled) { + this.initializeWorkspaces(); + } else { + this._workspaceCache = null; + document.getElementById("zen-workspaces-button")?.remove(); + for (let tab of gBrowser.tabs) { + gBrowser.showTab(tab); + } + } + }, + + async initializeWorkspaces() { + Services.prefs.addObserver("zen.workspaces.enabled", this.onWorkspacesEnabledChanged.bind(this)); + this.initializeWorkspacesButton(); + let file = new FileUtils.File(this._storeFile); + if (!file.exists()) { + await IOUtils.writeJSON(this._storeFile, {}); + } + if (this.workspaceEnabled) { + let workspaces = await this._workspaces(); + if (workspaces.workspaces.length === 0) { + await this.createAndSaveWorkspace("Default Workspace", true); + } else { + let activeWorkspace = workspaces.workspaces.find(workspace => workspace.default); + if (!activeWorkspace) { + activeWorkspace = workspaces.workspaces.find(workspace => workspace.used); + activeWorkspace.used = true; + await this.saveWorkspaces(); + } + if (!activeWorkspace) { + activeWorkspace = workspaces.workspaces[0]; + activeWorkspace.used = true; + await this.saveWorkspaces(); + } + await this.changeWorkspace(activeWorkspace); + } + this._initializeWorkspaceIcons(); + } + }, + + _initializeWorkspaceIcons() { + const kIcons = ["🏠", "📄", "💹", "💼", "📧", "✅", "👥"]; + let container = document.getElementById("PanelUI-zen-workspaces-create-icons-container"); + for (let icon of kIcons) { + let button = document.createXULElement("toolbarbutton"); + button.className = "toolbarbutton-1"; + button.setAttribute("label", icon); + button.onclick = ((event) => { + for (let button of container.children) { + button.removeAttribute("selected"); + } + button.setAttribute("selected", "true"); + }).bind(this, button); + container.appendChild(button); + } + }, + + async saveWorkspace(workspaceData) { + let json = await IOUtils.readJSON(this._storeFile); + if (typeof json.workspaces === "undefined") { + json.workspaces = []; + } + json.workspaces.push(workspaceData); + console.log("ZenWorkspaces: Saving workspace", workspaceData); + await IOUtils.writeJSON(this._storeFile, json); + this._workspaceCache = null; + }, + + async removeWorkspace(windowID) { + let json = await this._workspaces(); + console.log("ZenWorkspaces: Removing workspace", windowID); + await this.changeWorkspace(json.workspaces.find(workspace => workspace.uuid !== windowID)); + this._deleteAllTabsInWorkspace(windowID); + json.workspaces = json.workspaces.filter(workspace => workspace.uuid !== windowID); + await this.unsafeSaveWorkspaces(json); + await this._propagateWorkspaceData(); + }, + + async saveWorkspaces() { + await IOUtils.writeJSON(this._storeFile, await this._workspaces()); + this._workspaceCache = null; + }, + + async unsafeSaveWorkspaces(workspaces) { + await IOUtils.writeJSON(this._storeFile, workspaces); + this._workspaceCache = null; + }, + + // Workspaces dialog UI management + + openSaveDialog() { + let parentPanel = document.getElementById("PanelUI-zen-workspaces-multiview"); + PanelUI.showSubView("PanelUI-zen-workspaces-create", parentPanel); + }, + + cancelWorkspaceCreation() { + let parentPanel = document.getElementById("PanelUI-zen-workspaces-multiview"); + parentPanel.goBack(); + }, + + workspaceHasIcon(workspace) { + return typeof workspace.icon !== "undefined" && workspace.icon !== ""; + }, + + getWorkspaceIcon(workspace) { + if (this.workspaceHasIcon(workspace)) { + return workspace.icon; + } + return workspace.name[0].toUpperCase(); + }, + + async _propagateWorkspaceData() { + let currentContainer = document.getElementById("PanelUI-zen-workspaces-current-info"); + let workspaceList = document.getElementById("PanelUI-zen-workspaces-list"); + const createWorkspaceElement = (workspace) => { + let element = document.createXULElement("toolbarbutton"); + element.className = "subviewbutton"; + element.setAttribute("tooltiptext", workspace.name); + element.setAttribute("zen-workspace-id", workspace.uuid); + //element.setAttribute("context", "zenWorkspaceActionsMenu"); + let childs = window.MozXULElement.parseXULToFragment(` +
+ ${this.getWorkspaceIcon(workspace)} +
+
+ ${workspace.name} +
+ + + + `); + childs.querySelector(".zen-workspace-actions").addEventListener("command", ((event) => { + let button = event.target; + this._contextMenuId = button.closest("toolbarbutton[zen-workspace-id]").getAttribute("zen-workspace-id"); + const popup = button.ownerDocument.getElementById( + "zenWorkspaceActionsMenu" + ); + popup.openPopup(button, "after_end"); + }).bind(this)); + element.appendChild(childs); + element.onclick = (async () => { + if (event.target.closest(".zen-workspace-actions")) { + return; // Ignore clicks on the actions button + } + await this.changeWorkspace(workspace) + let panel = document.getElementById("PanelUI-zen-workspaces"); + PanelMultiView.hidePopup(panel); + }).bind(this, workspace); + return element; + } + let workspaces = await this._workspaces(); + let activeWorkspace = workspaces.workspaces.find(workspace => workspace.used); + currentContainer.innerHTML = ""; + workspaceList.innerHTML = ""; + workspaceList.parentNode.style.display = "flex"; + if (workspaces.workspaces.length - 1 <= 0) { + workspaceList.innerHTML = "No workspaces available"; + workspaceList.setAttribute("empty", "true"); + } else { + workspaceList.removeAttribute("empty"); + } + if (activeWorkspace) { + let currentWorkspace = createWorkspaceElement(activeWorkspace); + currentContainer.appendChild(currentWorkspace); + } + for (let workspace of workspaces.workspaces) { + if (workspace.used) { + continue; + } + let workspaceElement = createWorkspaceElement(workspace); + workspaceList.appendChild(workspaceElement); + } + }, + + async openWorkspacesDialog(event) { + if (!this.workspaceEnabled) { + return; + } + let target = event.target; + let panel = document.getElementById("PanelUI-zen-workspaces"); + await this._propagateWorkspaceData(); + PanelMultiView.openPopup(panel, target, { + position: "bottomright topright", + triggerEvent: event, + }).catch(console.error); + }, + + initializeWorkspacesButton() { + if (!this.workspaceEnabled) { + return; + } else if (document.getElementById("zen-workspaces-button")) { + let button = document.getElementById("zen-workspaces-button"); + button.removeAttribute("hidden"); + return; + } + let browserTabs = document.getElementById("tabbrowser-tabs"); + let button = document.createElement("toolbarbutton"); + button.id = "zen-workspaces-button"; + button.className = "toolbarbutton-1 chromeclass-toolbar-additional"; + button.setAttribute("label", "Workspaces"); + button.setAttribute("tooltiptext", "Workspaces"); + button.onclick = this.openWorkspacesDialog.bind(this); + browserTabs.insertAdjacentElement("beforebegin", button); + }, + + async _updateWorkspacesButton() { + let button = document.getElementById("zen-workspaces-button"); + if (!button) { + return; + } + let activeWorkspace = (await this._workspaces()).workspaces.find(workspace => workspace.used); + if (activeWorkspace) { + button.innerHTML = ` +
+ ${this.getWorkspaceIcon(activeWorkspace)} +
+
+ ${activeWorkspace.name} +
+ `; + if (!this.workspaceHasIcon(activeWorkspace)) { + button.querySelector(".zen-workspace-sidebar-icon").setAttribute("no-icon", "true"); + } + } + }, + + // Workspaces management + + get _workspaceInput() { + return document.getElementById("PanelUI-zen-workspaces-create-input"); + }, + + _deleteAllTabsInWorkspace(workspaceID) { + for (let tab of gBrowser.tabs) { + if (tab.getAttribute("zen-workspace-id") === workspaceID) { + gBrowser.removeTab(tab, { + animate: true, + skipSessionStore: true, + closeWindowWithLastTab: false, + }); + } + } + }, + + _prepareNewWorkspace(window) { + document.documentElement.setAttribute("zen-workspace-id", window.uuid); + let tabCount = 0; + for (let tab of gBrowser.tabs) { + if (!tab.hasAttribute("zen-workspace-id")) { + tab.setAttribute("zen-workspace-id", window.uuid); + tabCount++; + } + } + if (tabCount === 0) { + this._createNewTabForWorkspace(window); + } + }, + + _createNewTabForWorkspace(window) { + let tab = gZenUIManager.openAndChangeToTab(Services.prefs.getStringPref("browser.startup.homepage")); + tab.setAttribute("zen-workspace-id", window.uuid); + }, + + async saveWorkspaceFromInput() { + // Go to the next view + let parentPanel = document.getElementById("PanelUI-zen-workspaces-multiview"); + PanelUI.showSubView("PanelUI-zen-workspaces-create-icons", parentPanel); + }, + + async saveWorkspaceFromIcon() { + let workspaceName = this._workspaceInput.value; + if (!workspaceName) { + return; + } + this._workspaceInput.value = ""; + let icon = document.querySelector("#PanelUI-zen-workspaces-create-icons-container [selected]"); + icon?.removeAttribute("selected"); + await this.createAndSaveWorkspace(workspaceName, false, icon?.label); + document.getElementById("PanelUI-zen-workspaces").hidePopup(true); + }, + + onWorkspaceNameChange(event) { + let button = document.getElementById("PanelUI-zen-workspaces-create-save"); + if (this._workspaceInput.value === "") { + button.setAttribute("disabled", "true"); + return; + } + button.removeAttribute("disabled"); + }, + + async changeWorkspace(window) { + if (!this.workspaceEnabled) { + return; + } + let firstTab = undefined; + let workspaces = await this._workspaces(); + for (let workspace of workspaces.workspaces) { + workspace.used = workspace.uuid === window.uuid; + } + this.unsafeSaveWorkspaces(workspaces); + console.log("ZenWorkspaces: Changing workspace to", window.uuid); + for (let tab of gBrowser.tabs) { + if (tab.getAttribute("zen-workspace-id") === window.uuid && !tab.pinned) { + if (!firstTab) { + firstTab = tab; + gBrowser.selectedTab = firstTab; + } + gBrowser.showTab(tab); + } + } + if (typeof firstTab === "undefined") { + this._createNewTabForWorkspace(window); + } + for (let tab of gBrowser.tabs) { + if (tab.getAttribute("zen-workspace-id") !== window.uuid) { + gBrowser.hideTab(tab); + } + } + document.documentElement.setAttribute("zen-workspace-id", window.uuid); + await this.saveWorkspaces(); + await this._updateWorkspacesButton(); + await this._propagateWorkspaceData(); + }, + + _createWorkspaceData(name, isDefault, icon) { + let window = { + uuid: gZenUIManager.generateUuidv4(), + default: isDefault, + used: true, + icon: icon, + name: name, + }; + this._prepareNewWorkspace(window); + return window; + }, + + async createAndSaveWorkspace(name = "New Workspace", isDefault = false, icon = undefined) { + if (!this.workspaceEnabled) { + return; + } + let workspaceData = this._createWorkspaceData(name, isDefault, icon); + await this.saveWorkspace(workspaceData); + await this.changeWorkspace(workspaceData); + }, + + async onLocationChange(browser) { + let tab = gBrowser.getTabForBrowser(browser); + let workspaceID = tab.getAttribute("zen-workspace-id"); + if (!workspaceID) { + let workspaces = await this._workspaces(); + let activeWorkspace = workspaces.workspaces.find(workspace => workspace.used); + if (!activeWorkspace) { + return; + } + tab.setAttribute("zen-workspace-id", activeWorkspace.uuid); + } + }, + + // Context menu management + + _contextMenuId: null, + async updateContextMenu(_) { + console.assert(this._contextMenuId, "No context menu ID set"); + document.querySelector(`#PanelUI-zen-workspaces [zen-workspace-id="${this._contextMenuId}"] .zen-workspace-actions`).setAttribute("active", "true"); + const workspaces = await this._workspaces(); + let deleteMenuItem = document.getElementById("context_zenDeleteWorkspace"); + if (workspaces.workspaces.length <= 1 || workspaces.workspaces.find(workspace => workspace.uuid === this._contextMenuId).default) { + deleteMenuItem.setAttribute("disabled", "true"); + } else { + deleteMenuItem.removeAttribute("disabled"); + } + }, + + onContextMenuClose() { + let target = document.querySelector(`#PanelUI-zen-workspaces [zen-workspace-id="${this._contextMenuId}"] .zen-workspace-actions`); + if (target) { + target.removeAttribute("active"); + } + this._contextMenuId = null; + }, + + async contextDelete() { + await this.removeWorkspace(this._contextMenuId); + } +}; + +ZenWorkspaces.init(); diff --git a/src/browser-splitViews.mjs b/src/browser-splitViews.mjs deleted file mode 100644 index af2e55c..0000000 --- a/src/browser-splitViews.mjs +++ /dev/null @@ -1,330 +0,0 @@ - -class SplitViewsUtils { - /** - * @returns {HTMLDivElement} - */ - get tabBrowser() { - if (!this._tabBrowser) { - this._tabBrowser = document.getElementById('tabbrowser-tabpanels'); - } - // @ts-ignore - return this._tabBrowser; - } -} - -class SplitViewsBase extends SplitViewsUtils { - /** - * @type {SplitView[]} - */ - data; - - /** - * @param {SplitViewConfig} config - */ - constructor(config) { - super(); - this.config = config; - this.data = []; - this.currentView = -1; - this.globalIdCounter = 0; - // Added to "navigator-toolbox" element - this.parentSplitIndicator = this.config.splitIndicator + '-view'; - this.log('SplitViewsBase initialized'); - } - - /** - * @param {string} message - * @protected - */ - log(message) { - console.log(`SplitViews: ${message}`); - } - - get isActivated() { - return this.currentView !== -1; - } - - get activeView() { - if (!this.isActivated) { - throw new Error('No active view'); - } - return this.data[this.currentView]; - } - - /** - * @param {MockedExports.BrowserTab} tab - */ - getTabView(tab) { - return this.data.find(view => view.tabs.includes(tab)); - } - - /** - * @param {MockedExports.BrowserTab} tab - */ - isTabSplit(tab) { - return tab.hasAttribute(this.config.splitIndicator); - } - - /** - * @param {MockedExports.BrowserTab} tab - * @param {SplitType} type - * @param {MockedExports.BrowserTab[]} tabs - */ - changeSplitViewBase(tab, type, tabs) { - let view = this.getTabView(tab); - if (!view) { - return -1; - } - view.type = type; - view.tabs.push(...tabs.filter(t => !view.tabs.includes(t))); - return view.id; - } - - /** - * @param {MockedExports.BrowserTab[]} tabs - * @param {SplitType} type - */ - createSplitViewBase(tabs, type) { - let view = { - id: this.globalIdCounter++, - type, - tabs, - }; - this.data.push(view); - this.currentView = this.data.length - 1; - return view.id; - } - - /** - * Applies the grid layout to the tabs. - * - * @param {MockedExports.BrowserTab[]} tabs - The tabs to apply the grid layout to. - * @param {string} gridType - The type of grid layout. - * @param {MockedExports.BrowserTab} activeTab - The active tab. - */ - applyGridLayout(tabs, gridType, activeTab) { - const gridAreas = this.calculateGridAreas(tabs, gridType); - this.tabBrowser.style.gridTemplateAreas = gridAreas; - - tabs.forEach((tab, index) => { - tab.setAttribute(this.config.splitIndicator, "true"); - const container = tab.linkedBrowser.closest(".browserSidebarContainer"); - if (!container) { - throw new Error("Container not found"); - } - this.styleContainer(container, tab === activeTab, index, gridType); - }); - } - - /** - * Styles the container for a tab. - * - * @param {Element} container - The container element. - * @param {boolean} isActive - Indicates if the tab is active. - * @param {number} index - The index of the tab. - * @param {string} gridType - The type of grid layout. - */ - styleContainer(container, isActive, index, gridType) { - container.removeAttribute("split-active"); - container.setAttribute(this.config.splitIndicator, "true"); - if (isActive) { - container.setAttribute("split-active", "true"); - } - container.setAttribute("split-anim", "true"); - container.addEventListener("click", this.handleTabClick); - - if (gridType === "grid") { - // @ts-ignore - container.style.gridArea = `tab${index + 1}`; - } - } - - /** - * Calculates the grid areas for the tabs. - * - * @param {MockedExports.BrowserTab[]} tabs - The tabs. - * @param {string} gridType - The type of grid layout. - * @returns {string} The calculated grid areas. - */ - calculateGridAreas(tabs, gridType) { - if (gridType === "grid") { - return this.calculateGridAreasForGrid(tabs); - } - if (gridType === "vsep") { - return `'${tabs.map((_, j) => `tab${j + 1}`).join(" ")}'`; - } - if (gridType === "hsep") { - return tabs.map((_, j) => `'tab${j + 1}'`).join(" "); - } - return ""; - } - - /** - * Handles the tab click event. - * - * @param {Event} event - The click event. - */ - handleTabClick(event) { - const container = event.currentTarget; - // @ts-ignore - const tab = window.gBrowser.tabs.find( - // @ts-ignore - t => t.linkedBrowser.closest(".browserSidebarContainer") === container - ); - if (tab) { - // @ts-ignore - window.gBrowser.selectedTab = tab; - } - }; - - /** - * Calculates the grid areas for the tabs in a grid layout. - * - * @param {MockedExports.BrowserTab[]} tabs - The tabs. - * @returns {string} The calculated grid areas. - */ - calculateGridAreasForGrid(tabs) { - const rows = ["", ""]; - tabs.forEach((_, i) => { - if (i % 2 === 0) { - rows[0] += ` tab${i + 1}`; - } else { - rows[1] += ` tab${i + 1}`; - } - }); - - if (tabs.length === 2) { - return "'tab1 tab2'"; - } - - if (tabs.length % 2 !== 0) { - rows[1] += ` tab${tabs.length}`; - } - - return `'${rows[0].trim()}' '${rows[1].trim()}'`; - } - - /** - * @param {number} viewId - * @protected - */ - updateSplitView(viewId) { - let view = this.data.find(view => view.id === viewId); - this.log(`updateSplitView: ${viewId}`); - this.currentView = viewId; - if (!view) { - this.tabBrowser.removeAttribute(this.parentSplitIndicator); - throw new Error('TODO: Remove split view'); - return; - } - this.tabBrowser.setAttribute(this.parentSplitIndicator, "true"); - this.applyGridLayout(view.tabs, view.type, view.tabs[0]); - } - - /** - * @param {MockedExports.BrowserTab[]} tabs - * @param {SplitType} type - * @protected - */ - createOrChangeSplitView(tabs, type) { - let activeTab = tabs.find(tab => this.isTabSplit(tab)); - this.log(`createOrChangeSplitView: ${type}`); - let viewId = -1; - if (activeTab) { - viewId = this.changeSplitViewBase(activeTab, type, tabs); - } else { - viewId = this.createSplitViewBase(tabs, type); - } - this.updateSplitView(viewId); - } -} - -// Public API exposed by the module -export class SplitViews extends SplitViewsBase { - /** - * @param {SplitViewConfig} config - */ - constructor(config) { - super(config); - this.addEventListeners(); - } - - addEventListeners() { - window.addEventListener('TabClose', this); - } - - /** - * @param {Event} event - */ - handleEvent(event) { - switch (event.type) { - case 'TabClose': - this.onTabClose(event); - break; - } - } - - /** - * @param {Event} event - */ - // @ts-ignore - // @ts-ignore - onTabClose(event) { - } - - /** - * @param {MockedExports.Browser} browser - */ - // @ts-ignore - // @ts-ignore - onLocationChange(browser) { - this.log('onLocationChange'); - } - - /** - * @param {SplitType} type - */ - // @ts-ignore - // @ts-ignore - tileCurrentView(type) { - this.log('tileCurrentView'); - } - - closeCurrentView() { - this.log('closeCurrentView'); - } - - /** - * @param {MockedExports.BrowserTab} tab - */ - // @ts-ignore - // @ts-ignore - tabIsInActiveView(tab) { - this.log('tabIsInActiveView'); - return false; - } - - getActiveViewTabs() { - this.log('getActiveViewTabs'); - return []; - } - - getActiveViewType() { - if (!this.isActivated) { - return undefined; - } - return this.activeView.type; - } - - /** - * @param {MockedExports.BrowserTab[]} tabs - * @param {SplitType} type - * @public - */ - createSplitView(tabs, type = this.config.defaultSplitView) { - if (tabs.length < 2) { - return; - } - this.createOrChangeSplitView(tabs, type); - } -}; diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index 4db6c40..0000000 --- a/tsconfig.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - - /* Projects */ - // "incremental": true, /* Enable incremental compilation */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - - /* Language and Environment */ - // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ - // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - // Make the type checking as strict as possible. - // TypeScript will check JS files only if they have a @ts-check comment in them. - "allowJs": true, - // Allow esnext syntax. Otherwise the default is ES5 only. - "target": "esnext", - "lib": ["esnext", "dom"], - - /* Modules */ - "module": "CommonJS", /* Specify what module code is generated. */ - "rootDir": "./src", /* Specify the root folder within your source files. */ - // "moduleResolution": "NodeNext", /* Specify how TypeScript looks up a file from a given module specifier. */ - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ - "typeRoots": ["./@types"], /* Specify type package names to be included without being referenced in a source file. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "resolveJsonModule": true, /* Enable importing .json files */ - // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ - - /* JavaScript Support */ - // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ - "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ - - /* Emit */ - "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "outFile": "./dist/components.js", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ - "outDir": "./dist", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ - - /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ - - /* Type Checking */ - "strict": true, /* Enable all strict type-checking options. */ - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ - // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ - // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ - } -}