From 8d6af2bd839f698910cfdb448222272ccbf177c6 Mon Sep 17 00:00:00 2001 From: Rolf Heij Date: Tue, 13 Feb 2024 17:16:31 -0500 Subject: [PATCH 01/22] initial commit --- .../src/web-views/hello-world-2.web-view.tsx | 6 + lib/papi-dts/edit-papi-d-ts.ts | 5 +- lib/papi-dts/papi.d.ts | 597 +++--------------- lib/platform-bible-react/dist/index.d.ts | 2 - lib/platform-bible-utils/dist/index.cjs | 2 +- lib/platform-bible-utils/dist/index.cjs.map | 2 +- lib/platform-bible-utils/dist/index.d.ts | 13 +- lib/platform-bible-utils/dist/index.js | 564 ++++++++++------- lib/platform-bible-utils/dist/index.js.map | 2 +- lib/platform-bible-utils/package-lock.json | 10 + lib/platform-bible-utils/package.json | 1 + lib/platform-bible-utils/src/index.ts | 1 + lib/platform-bible-utils/src/string-util.ts | 28 + src/extension-host/extension-host.ts | 4 +- .../extension-asset-protocol.service.ts | 11 +- .../services/web-view.service-host.ts | 10 +- src/shared/models/data-provider.model.ts | 4 +- src/shared/services/network.service.ts | 3 +- src/shared/utils/util.ts | 8 +- 19 files changed, 512 insertions(+), 761 deletions(-) create mode 100644 lib/platform-bible-utils/src/string-util.ts diff --git a/extensions/src/hello-world/src/web-views/hello-world-2.web-view.tsx b/extensions/src/hello-world/src/web-views/hello-world-2.web-view.tsx index b9a3fafd88..668c5d9111 100644 --- a/extensions/src/hello-world/src/web-views/hello-world-2.web-view.tsx +++ b/extensions/src/hello-world/src/web-views/hello-world-2.web-view.tsx @@ -1,5 +1,6 @@ import papi from '@papi/frontend'; import { useEvent, Button } from 'platform-bible-react'; +import { indexOf } from 'platform-bible-utils'; import { useCallback, useState } from 'react'; import type { HelloWorldEvent } from 'hello-world'; import { WebViewProps } from '@papi/core'; @@ -22,8 +23,13 @@ globalThis.webViewComponent = function HelloWorld2({ useWebViewState }: WebViewP useCallback(({ times }: HelloWorldEvent) => setClicks(times), []), ); + const someIndex = indexOf('SomeStringWithABunchOfWords', 'i', 15); + return ( <> +
+ Index: {someIndex} +
Hello World React 2
diff --git a/lib/papi-dts/edit-papi-d-ts.ts b/lib/papi-dts/edit-papi-d-ts.ts index 1dd544071e..a547ad6356 100644 --- a/lib/papi-dts/edit-papi-d-ts.ts +++ b/lib/papi-dts/edit-papi-d-ts.ts @@ -4,6 +4,7 @@ import fs from 'fs'; import typescript from 'typescript'; import escapeStringRegexp from 'escape-string-regexp'; import { exit } from 'process'; +import {substring} from 'platform-bible-utils' const start = performance.now(); @@ -143,9 +144,9 @@ if (paths) { const asteriskIndex = path.indexOf('*'); // Get the path alias without the * at the end but with the @ - const pathAlias = path.substring(0, asteriskIndex); + const pathAlias = substring(path, 0, asteriskIndex); // Get the path alias without the @ at the start - const pathAliasNoAt = pathAlias.substring(1); + const pathAliasNoAt = substring(pathAlias, 1); // Regex-escaped path alias without @ to be used in a regex string const pathAliasNoAtRegex = escapeStringRegexp(pathAliasNoAt); diff --git a/lib/papi-dts/papi.d.ts b/lib/papi-dts/papi.d.ts index 31ffe4d16f..f21f6ee9ef 100644 --- a/lib/papi-dts/papi.d.ts +++ b/lib/papi-dts/papi.d.ts @@ -171,6 +171,7 @@ declare module 'shared/models/web-view.model' { */ export type WebViewDefinitionUpdateInfo = Partial; /** + * JSDOC SOURCE UseWebViewStateHook * * A React hook for working with a state object tied to a webview. Returns a WebView state value and * a function to set it. Use similarly to `useState`. @@ -216,6 +217,7 @@ declare module 'shared/models/web-view.model' { resetWebViewState: () => void, ]; /** + * JSDOC SOURCE GetWebViewDefinitionUpdatableProperties * * Gets the updatable properties on this WebView's WebView definition * @@ -226,6 +228,7 @@ declare module 'shared/models/web-view.model' { | WebViewDefinitionUpdatableProperties | undefined; /** + * JSDOC SOURCE UpdateWebViewDefinition * * Updates this WebView with the specified properties * @@ -243,67 +246,11 @@ declare module 'shared/models/web-view.model' { export type UpdateWebViewDefinition = (updateInfo: WebViewDefinitionUpdateInfo) => boolean; /** Props that are passed into the web view itself inside the iframe in the web view tab component */ export type WebViewProps = { - /** - * - * A React hook for working with a state object tied to a webview. Returns a WebView state value and - * a function to set it. Use similarly to `useState`. - * - * Only used in WebView iframes. - * - * _@param_ `stateKey` Key of the state value to use. The webview state holds a unique value per - * key. - * - * WARNING: MUST BE STABLE - const or wrapped in useState, useMemo, etc. The reference must not be - * updated every render - * - * _@param_ `defaultStateValue` Value to use if the web view state didn't contain a value for the - * given 'stateKey' - * - * Note: this parameter is internally assigned to a `ref`, so changing it will not cause any hooks - * to re-run with its new value. Running `resetWebViewState()` will always update the state value - * returned to the latest `defaultStateValue`, and changing the `stateKey` will use the latest - * `defaultStateValue`. However, if `defaultStateValue` is changed while a state is - * `defaultStateValue` (meaning it is reset and has no value), the returned state value will not be - * updated to the new `defaultStateValue`. - * - * _@returns_ `[stateValue, setStateValue, resetWebViewState]` - * - * - `webViewStateValue`: The current value for the web view state at the key specified or - * `defaultStateValue` if a state was not found - * - `setWebViewState`: Function to use to update the web view state value at the key specified - * - `resetWebViewState`: Function that removes the web view state and resets the value to - * `defaultStateValue` - * - * _@example_ - * - * ```typescript - * const [lastPersonSeen, setLastPersonSeen] = useWebViewState('lastSeen', 'No one'); - * ``` - */ + /** JSDOC DESTINATION UseWebViewStateHook */ useWebViewState: UseWebViewStateHook; - /** - * - * Gets the updatable properties on this WebView's WebView definition - * - * _@returns_ updatable properties this WebView's WebView definition or undefined if not found for - * some reason - */ + /** JSDOC DESTINATION GetWebViewDefinitionUpdatableProperties */ getWebViewDefinitionUpdatableProperties: GetWebViewDefinitionUpdatableProperties; - /** - * - * Updates this WebView with the specified properties - * - * _@param_ `updateInfo` properties to update on the WebView. Any unspecified properties will stay - * the same - * - * _@returns_ true if successfully found the WebView to update; false otherwise - * - * _@example_ - * - * ```typescript - * updateWebViewDefinition({ title: `Hello ${name}` }); - * ``` - */ + /** JSDOC DESTINATION UpdateWebViewDefinition */ updateWebViewDefinition: UpdateWebViewDefinition; }; /** Options that affect what `webViews.getWebView` does */ @@ -363,43 +310,7 @@ declare module 'shared/global-this.model' { * in WebView iframes. */ var webViewComponent: FunctionComponent; - /** - * - * A React hook for working with a state object tied to a webview. Returns a WebView state value and - * a function to set it. Use similarly to `useState`. - * - * Only used in WebView iframes. - * - * _@param_ `stateKey` Key of the state value to use. The webview state holds a unique value per - * key. - * - * WARNING: MUST BE STABLE - const or wrapped in useState, useMemo, etc. The reference must not be - * updated every render - * - * _@param_ `defaultStateValue` Value to use if the web view state didn't contain a value for the - * given 'stateKey' - * - * Note: this parameter is internally assigned to a `ref`, so changing it will not cause any hooks - * to re-run with its new value. Running `resetWebViewState()` will always update the state value - * returned to the latest `defaultStateValue`, and changing the `stateKey` will use the latest - * `defaultStateValue`. However, if `defaultStateValue` is changed while a state is - * `defaultStateValue` (meaning it is reset and has no value), the returned state value will not be - * updated to the new `defaultStateValue`. - * - * _@returns_ `[stateValue, setStateValue, resetWebViewState]` - * - * - `webViewStateValue`: The current value for the web view state at the key specified or - * `defaultStateValue` if a state was not found - * - `setWebViewState`: Function to use to update the web view state value at the key specified - * - `resetWebViewState`: Function that removes the web view state and resets the value to - * `defaultStateValue` - * - * _@example_ - * - * ```typescript - * const [lastPersonSeen, setLastPersonSeen] = useWebViewState('lastSeen', 'No one'); - * ``` - */ + /** JSDOC DESTINATION UseWebViewStateHook */ var useWebViewState: UseWebViewStateHook; /** * Retrieve the value from web view state with the given 'stateKey', if it exists. Otherwise @@ -417,29 +328,9 @@ declare module 'shared/global-this.model' { webViewId: string, webViewDefinitionUpdateInfo: WebViewDefinitionUpdateInfo, ) => boolean; - /** - * - * Gets the updatable properties on this WebView's WebView definition - * - * _@returns_ updatable properties this WebView's WebView definition or undefined if not found for - * some reason - */ + /** JSDOC DESTINATION GetWebViewDefinitionUpdatableProperties */ var getWebViewDefinitionUpdatableProperties: GetWebViewDefinitionUpdatableProperties; - /** - * - * Updates this WebView with the specified properties - * - * _@param_ `updateInfo` properties to update on the WebView. Any unspecified properties will stay - * the same - * - * _@returns_ true if successfully found the WebView to update; false otherwise - * - * _@example_ - * - * ```typescript - * updateWebViewDefinition({ title: `Hello ${name}` }); - * ``` - */ + /** JSDOC DESTINATION UpdateWebViewDefinition */ var updateWebViewDefinition: UpdateWebViewDefinition; } /** Type of Paranext process */ @@ -864,6 +755,7 @@ declare module 'shared/services/logger.service' { */ export function formatLog(message: string, serviceName: string, tag?: string): string; /** + * JSDOC SOURCE logger * * All extensions and services should use this logger to provide a unified output of logs */ @@ -885,7 +777,8 @@ declare module 'client/services/web-socket.interface' { declare module 'renderer/services/renderer-web-socket.service' { /** Once our network is running, run this to stop extensions from connecting to it directly */ export const blockWebSocketsToPapiNetwork: () => void; - /** This wraps the browser's WebSocket implementation to provide + /** + * JSDOC SOURCE PapiRendererWebSocket This wraps the browser's WebSocket implementation to provide * better control over internet access. It is isomorphic with the standard WebSocket, so it should * act as a drop-in replacement. * @@ -1440,6 +1333,7 @@ declare module 'shared/services/network.service' { getNetworkEvent: typeof getNetworkEvent; } /** + * JSDOC SOURCE papiNetworkService * * Service that provides a way to send and receive network events */ @@ -1937,6 +1831,7 @@ declare module 'shared/models/data-provider-engine.model' { } from 'shared/models/data-provider.model'; import { NetworkableObject } from 'shared/models/network-object.model'; /** + * JSDOC SOURCE DataProviderEngineNotifyUpdate * * Method to run to send clients updates for a specific data type outside of the `set` * method. papi overwrites this function on the DataProviderEngine itself to emit an update after @@ -1983,41 +1878,7 @@ declare module 'shared/models/data-provider-engine.model' { * @see IDataProviderEngine for more information on using this type. */ export type WithNotifyUpdate = { - /** - * - * Method to run to send clients updates for a specific data type outside of the `set` - * method. papi overwrites this function on the DataProviderEngine itself to emit an update after - * running the `notifyUpdate` method in the DataProviderEngine. - * - * @example To run `notifyUpdate` function so it updates the Verse and Heresy data types (in a data - * provider engine): - * - * ```typescript - * this.notifyUpdate(['Verse', 'Heresy']); - * ``` - * - * @example You can log the manual updates in your data provider engine by specifying the following - * `notifyUpdate` function in the data provider engine: - * - * ```typescript - * notifyUpdate(updateInstructions) { - * papi.logger.info(updateInstructions); - * } - * ``` - * - * Note: This function's return is treated the same as the return from `set` - * - * @param updateInstructions Information that papi uses to interpret whether to send out updates. - * Defaults to `'*'` (meaning send updates for all data types) if parameter `updateInstructions` - * is not provided or is undefined. Otherwise returns `updateInstructions`. papi passes the - * interpreted update value into this `notifyUpdate` function. For example, running - * `this.notifyUpdate()` will call the data provider engine's `notifyUpdate` with - * `updateInstructions` of `'*'`. - * @see DataProviderUpdateInstructions for more info on the `updateInstructions` parameter - * - * WARNING: Do not update a data type in its `get` method (unless you make a base case)! - * It will create a destructive infinite loop. - */ + /** JSDOC DESTINATION DataProviderEngineNotifyUpdate */ notifyUpdate: DataProviderEngineNotifyUpdate; }; /** @@ -2373,6 +2234,7 @@ declare module 'shared/services/command.service' { handler: CommandHandlers[CommandName], ) => Promise; /** + * JSDOC SOURCE commandService * * The command service allows you to exchange messages with other components in the platform. You * can register a command that other services and extensions can send you. You can send commands to @@ -2570,6 +2432,7 @@ declare module 'shared/services/web-view.service-model' { import { AddWebViewEvent, Layout } from 'shared/models/docking-framework.model'; import { PlatformEvent } from 'platform-bible-utils'; /** + * JSDOC SOURCE papiWebViewService * * Service exposing various functions related to using webViews * @@ -2717,6 +2580,7 @@ declare module 'shared/services/web-view-provider.service' { } const webViewProviderService: WebViewProviderService; /** + * JSDOC SOURCE papiWebViewProviderService * * Interface for registering webView providers */ @@ -2730,6 +2594,7 @@ declare module 'shared/services/internet.service' { fetch: typeof papiFetch; } /** + * JSDOC SOURCE internetService * * Service that provides a way to call `fetch` since the original function is not available */ @@ -2750,6 +2615,7 @@ declare module 'shared/services/data-provider.service' { } from 'papi-shared-types'; import IDataProvider, { IDisposableDataProvider } from 'shared/models/data-provider.interface'; /** + * JSDOC SOURCE DataProviderEngine * * Abstract class that provides a placeholder `notifyUpdate` for data provider engine classes. If a * data provider engine class extends this class, it doesn't have to specify its own `notifyUpdate` @@ -2924,6 +2790,7 @@ declare module 'shared/services/data-provider.service' { DataProviderEngine: typeof DataProviderEngine; } /** + * JSDOC SOURCE dataProviderService * * Service that allows extensions to send and receive data to/from other extensions */ @@ -2967,6 +2834,7 @@ declare module 'shared/models/project-metadata.model' { declare module 'shared/services/project-lookup.service-model' { import { ProjectMetadata } from 'shared/models/project-metadata.model'; /** + * JSDOC SOURCE projectLookupService * * Provides metadata for projects known by the platform */ @@ -3034,6 +2902,7 @@ declare module 'shared/services/project-data-provider.service' { get: typeof get; } /** + * JSDOC SOURCE papiBackendProjectDataProviderService * * Service that registers and gets project data providers */ @@ -3042,6 +2911,7 @@ declare module 'shared/services/project-data-provider.service' { get: typeof get; } /** + * JSDOC SOURCE papiFrontendProjectDataProviderService * * Service that gets project data providers */ @@ -3331,6 +3201,7 @@ declare module 'extension-host/services/extension-storage.service' { deleteUserData: typeof deleteUserData; } /** + * JSDOC SOURCE extensionStorageService * * This service provides extensions in the extension host the ability to read/write data based on * the extension identity and current user (as identified by the OS). This service will not work @@ -3520,6 +3391,7 @@ declare module 'shared/services/dialog.service-model' { import { DialogTabTypes, DialogTypes } from 'renderer/components/dialogs/dialog-definition.model'; import { DialogOptions } from 'shared/models/dialog-options.model'; /** + * JSDOC SOURCE dialogService * * Prompt the user for responses with dialogs */ @@ -3576,6 +3448,7 @@ declare module 'renderer/hooks/papi-hooks/use-dialog-callback.hook' { maximumOpenDialogs?: number; }; /** + * JSDOC SOURCE useDialogCallback * * Enables using `papi.dialogs.showDialog` in React more easily. Returns a callback to run that will * open a dialog with the provided `dialogType` and `options` then run the `resolveCallback` with @@ -3656,74 +3529,7 @@ declare module 'renderer/hooks/papi-hooks/use-dialog-callback.hook' { ) => void, rejectCallback: (error: unknown, dialogType: DialogTabType, options: DialogOptions) => void, ): (optionOverrides?: Partial) => Promise; - /** - * - * Enables using `papi.dialogs.showDialog` in React more easily. Returns a callback to run that will - * open a dialog with the provided `dialogType` and `options` then run the `resolveCallback` with - * the dialog response or `rejectCallback` if there is an error. By default, only one dialog can be - * open at a time. - * - * If you need to open multiple dialogs and track which dialog is which, you can set - * `options.shouldOpenMultipleDialogs` to `true` and add a counter to the `options` when calling the - * callback. Then `resolveCallback` will be resolved with that options object including your - * counter. - * - * @type `DialogTabType` The dialog type you are using. Should be inferred by parameters - * @param dialogType Dialog type you want to show on the screen - * - * Note: this parameter is internally assigned to a `ref`, so changing it will not cause any hooks - * to re-run with its new value. This means that updating this parameter will not cause a new - * callback to be returned. However, because of the nature of calling dialogs, this has no adverse - * effect on the functionality of this hook. Calling the callback will always use the latest - * `dialogType`. - * @param options Various options for configuring the dialog that shows and this hook. If an - * `options` parameter is also provided to the returned `showDialog` callback, those - * callback-provided `options` merge over these hook-provided `options` - * - * Note: this parameter is internally assigned to a `ref`, so changing it will not cause any hooks - * to re-run with its new value. This means that updating this parameter will not cause a new - * callback to be returned. However, because of the nature of calling dialogs, this has no adverse - * effect on the functionality of this hook. Calling the callback will always use the latest - * `options`. - * @param resolveCallback `(response, dialogType, options)` The function that will be called if the - * dialog request resolves properly - * - * - `response` - the resolved value of the dialog call. Either the user's response or `undefined` if - * the user cancels - * - `dialogType` - the value of `dialogType` at the time that this dialog was called - * - `options` the `options` provided to the dialog at the time that this dialog was called. This - * consists of the `options` provided to the returned `showDialog` callback merged over the - * `options` provided to the hook and additionally contains {@link UseDialogCallbackOptions} - * properties - * - * Note: this parameter is internally assigned to a `ref`, so changing it will not cause any hooks - * to re-run with its new value. This means that updating this parameter will not cause a new - * callback to be returned. However, because of the nature of calling dialogs, this has no adverse - * effect on the functionality of this hook. When the dialog resolves, it will always call the - * latest `resolveCallback`. - * @param rejectCallback `(error, dialogType, options)` The function that will be called if the - * dialog request throws an error - * - * - `error` - the error thrown while calling the dialog - * - `dialogType` - the value of `dialogType` at the time that this dialog was called - * - `options` the `options` provided to the dialog at the time that this dialog was called. This - * consists of the `options` provided to the returned `showDialog` callback merged over the - * `options` provided to the hook and additionally contains {@link UseDialogCallbackOptions} - * properties - * - * Note: this parameter is internally assigned to a `ref`, so changing it will not cause any hooks - * to re-run with its new value. This means that updating this parameter will not cause a new - * callback to be returned. However, because of the nature of calling dialogs, this has no adverse - * effect on the functionality of this hook. If the dialog throws an error, it will always call - * the latest `rejectCallback`. - * @returns `showDialog(options?)` - callback to run to show the dialog to prompt the user for a - * response - * - * - `optionsOverrides?` - `options` object you may specify that will merge over the `options` you - * provide to the hook before passing to the dialog. All properties are optional, so you may - * specify as many or as few properties here as you want to overwrite the properties in the - * `options` you provide to the hook - */ + /** JSDOC DESTINATION useDialogCallback */ function useDialogCallback< DialogTabType extends DialogTabTypes, DialogOptions extends DialogTypes[DialogTabType]['options'], @@ -3802,13 +3608,14 @@ declare module 'shared/services/settings.service' { subscribe: typeof subscribeToSetting; } /** + * JSDOC SOURCE settingsService * * Service that allows to get and set settings in local storage */ const settingsService: SettingsService; export default settingsService; } -declare module '@papi/core' { +declare module 'shared/services/papi-core.service' { /** Exporting empty object so people don't have to put 'type' in their import statements */ const core: {}; export default core; @@ -3854,15 +3661,12 @@ declare module 'shared/services/menu-data.service-model' { DataProviderSubscriberOptions, DataProviderUpdateInstructions, } from 'shared/models/data-provider.model'; - import { IDataProvider } from '@papi/core'; - /** - * - * This name is used to register the menu data data provider on the papi. You can use this name to - * find the data provider when accessing it using the useData hook - */ + import { IDataProvider } from 'shared/services/papi-core.service'; + /** JSDOC DESTINATION menuDataServiceProviderName */ export const menuDataServiceProviderName = 'platform.menuDataServiceDataProvider'; export const menuDataServiceObjectToProxy: Readonly<{ /** + * JSDOC SOURCE menuDataServiceProviderName * * This name is used to register the menu data data provider on the papi. You can use this name to * find the data provider when accessing it using the useData hook @@ -3879,11 +3683,13 @@ declare module 'shared/services/menu-data.service-model' { } } /** + * JSDOC SOURCE menuDataService * * Service that allows to get and store menu data */ export type IMenuDataService = { /** + * JSDOC SOURCE getMainMenu * * Get menu content for the main menu * @@ -3891,13 +3697,7 @@ declare module 'shared/services/menu-data.service-model' { * @returns MultiColumnMenu object of main menu content */ getMainMenu(mainMenuType: undefined): Promise; - /** - * - * Get menu content for the main menu - * - * @param mainMenuType Does not have to be defined - * @returns MultiColumnMenu object of main menu content - */ + /** JSDOC DESTINATION getMainMenu */ getMainMenu(): Promise; /** * This data cannot be changed. Trying to use this setter this will always throw @@ -3963,7 +3763,7 @@ declare module 'shared/services/menu-data.service' { const menuDataService: IMenuDataService; export default menuDataService; } -declare module '@papi/backend' { +declare module 'extension-host/services/papi-backend.service' { /** * Unified module for accessing API features in the extension host. * @@ -3984,167 +3784,67 @@ declare module '@papi/backend' { import { DialogService } from 'shared/services/dialog.service-model'; import { IMenuDataService } from 'shared/services/menu-data.service-model'; const papi: { - /** - * - * Abstract class that provides a placeholder `notifyUpdate` for data provider engine classes. If a - * data provider engine class extends this class, it doesn't have to specify its own `notifyUpdate` - * function in order to use `notifyUpdate`. - * - * @see IDataProviderEngine for more information on extending this class. - */ + /** JSDOC DESTINATION DataProviderEngine */ DataProviderEngine: typeof PapiDataProviderEngine; /** This is just an alias for internet.fetch */ fetch: typeof globalThis.fetch; - /** - * - * The command service allows you to exchange messages with other components in the platform. You - * can register a command that other services and extensions can send you. You can send commands to - * other services and extensions that have registered commands. - */ + /** JSDOC DESTINATION commandService */ commands: typeof commandService; - /** - * - * Service exposing various functions related to using webViews - * - * WebViews are iframes in the Platform.Bible UI into which extensions load frontend code, either - * HTML or React components. - */ + /** JSDOC DESTINATION papiWebViewService */ webViews: WebViewServiceType; - /** - * - * Interface for registering webView providers - */ + /** JSDOC DESTINATION papiWebViewProviderService */ webViewProviders: PapiWebViewProviderService; - /** - * - * Prompt the user for responses with dialogs - */ + /** JSDOC DESTINATION dialogService */ dialogs: DialogService; - /** - * - * Service that provides a way to send and receive network events - */ + /** JSDOC DESTINATION papiNetworkService */ network: PapiNetworkService; - /** - * - * All extensions and services should use this logger to provide a unified output of logs - */ + /** JSDOC DESTINATION logger */ logger: import('electron-log').MainLogger & { default: import('electron-log').MainLogger; }; - /** - * - * Service that provides a way to call `fetch` since the original function is not available - */ + /** JSDOC DESTINATION internetService */ internet: InternetService; - /** - * - * Service that allows extensions to send and receive data to/from other extensions - */ + /** JSDOC DESTINATION dataProviderService */ dataProviders: DataProviderService; - /** - * - * Service that registers and gets project data providers - */ + /** JSDOC DESTINATION papiBackendProjectDataProviderService */ projectDataProviders: PapiBackendProjectDataProviderService; - /** - * - * Provides metadata for projects known by the platform - */ + /** JSDOC DESTINATION projectLookupService */ projectLookup: ProjectLookupServiceType; - /** - * - * This service provides extensions in the extension host the ability to read/write data based on - * the extension identity and current user (as identified by the OS). This service will not work - * within the renderer. - */ + /** JSDOC DESTINATION extensionStorageService */ storage: ExtensionStorageService; - /** - * - * Service that allows to get and store menu data - */ + /** JSDOC DESTINATION menuDataService */ menuData: IMenuDataService; }; export default papi; - /** - * - * Abstract class that provides a placeholder `notifyUpdate` for data provider engine classes. If a - * data provider engine class extends this class, it doesn't have to specify its own `notifyUpdate` - * function in order to use `notifyUpdate`. - * - * @see IDataProviderEngine for more information on extending this class. - */ + /** JSDOC DESTINATION DataProviderEngine */ export const DataProviderEngine: typeof PapiDataProviderEngine; /** This is just an alias for internet.fetch */ export const fetch: typeof globalThis.fetch; - /** - * - * The command service allows you to exchange messages with other components in the platform. You - * can register a command that other services and extensions can send you. You can send commands to - * other services and extensions that have registered commands. - */ + /** JSDOC DESTINATION commandService */ export const commands: typeof commandService; - /** - * - * Service exposing various functions related to using webViews - * - * WebViews are iframes in the Platform.Bible UI into which extensions load frontend code, either - * HTML or React components. - */ + /** JSDOC DESTINATION papiWebViewService */ export const webViews: WebViewServiceType; - /** - * - * Interface for registering webView providers - */ + /** JSDOC DESTINATION papiWebViewProviderService */ export const webViewProviders: PapiWebViewProviderService; - /** - * - * Prompt the user for responses with dialogs - */ + /** JSDOC DESTINATION dialogService */ export const dialogs: DialogService; - /** - * - * Service that provides a way to send and receive network events - */ + /** JSDOC DESTINATION papiNetworkService */ export const network: PapiNetworkService; - /** - * - * All extensions and services should use this logger to provide a unified output of logs - */ + /** JSDOC DESTINATION logger */ export const logger: import('electron-log').MainLogger & { default: import('electron-log').MainLogger; }; - /** - * - * Service that provides a way to call `fetch` since the original function is not available - */ + /** JSDOC DESTINATION internetService */ export const internet: InternetService; - /** - * - * Service that allows extensions to send and receive data to/from other extensions - */ + /** JSDOC DESTINATION dataProviderService */ export const dataProviders: DataProviderService; - /** - * - * Service that registers and gets project data providers - */ + /** JSDOC DESTINATION papiBackendProjectDataProviderService */ export const projectDataProviders: PapiBackendProjectDataProviderService; - /** - * - * Provides metadata for projects known by the platform - */ + /** JSDOC DESTINATION projectLookupService */ export const projectLookup: ProjectLookupServiceType; - /** - * - * This service provides extensions in the extension host the ability to read/write data based on - * the extension identity and current user (as identified by the OS). This service will not work - * within the renderer. - */ + /** JSDOC DESTINATION extensionStorageService */ export const storage: ExtensionStorageService; - /** - * - * Service that allows to get and store menu data - */ + /** JSDOC DESTINATION menuDataService */ export const menuData: IMenuDataService; } declare module 'extension-host/extension-types/extension.interface' { @@ -4339,17 +4039,13 @@ declare module 'renderer/hooks/papi-hooks/use-data.hook' { dataProviderSource: DataProviderName | DataProviders[DataProviderName] | undefined, ): { [TDataType in keyof DataProviderTypes[DataProviderName]]: ( - // @ts-ignore TypeScript pretends it can't find `selector`, but it works just fine selector: DataProviderTypes[DataProviderName][TDataType]['selector'], - // @ts-ignore TypeScript pretends it can't find `getData`, but it works just fine defaultValue: DataProviderTypes[DataProviderName][TDataType]['getData'], subscriberOptions?: DataProviderSubscriberOptions, ) => [ - // @ts-ignore TypeScript pretends it can't find `getData`, but it works just fine DataProviderTypes[DataProviderName][TDataType]['getData'], ( | (( - // @ts-ignore TypeScript pretends it can't find `setData`, but it works just fine newData: DataProviderTypes[DataProviderName][TDataType]['setData'], ) => Promise>) | undefined @@ -4502,17 +4198,13 @@ declare module 'renderer/hooks/papi-hooks/use-project-data.hook' { projectDataProviderSource: string | ProjectDataProviders[ProjectType] | undefined, ): { [TDataType in keyof ProjectDataTypes[ProjectType]]: ( - // @ts-ignore TypeScript pretends it can't find `selector`, but it works just fine selector: ProjectDataTypes[ProjectType][TDataType]['selector'], - // @ts-ignore TypeScript pretends it can't find `getData`, but it works just fine defaultValue: ProjectDataTypes[ProjectType][TDataType]['getData'], subscriberOptions?: DataProviderSubscriberOptions, ) => [ - // @ts-ignore TypeScript pretends it can't find `getData`, but it works just fine ProjectDataTypes[ProjectType][TDataType]['getData'], ( | (( - // @ts-ignore TypeScript pretends it can't find `setData`, but it works just fine newData: ProjectDataTypes[ProjectType][TDataType]['setData'], ) => Promise>) | undefined @@ -4634,11 +4326,12 @@ declare module 'renderer/hooks/papi-hooks/index' { export { default as useDialogCallback } from 'renderer/hooks/papi-hooks/use-dialog-callback.hook'; export { default as useDataProviderMulti } from 'renderer/hooks/papi-hooks/use-data-provider-multi.hook'; } -declare module '@papi/frontend/react' { +declare module 'renderer/services/papi-frontend-react.service' { export * from 'renderer/hooks/papi-hooks/index'; } declare module 'renderer/services/renderer-xml-http-request.service' { - /** This wraps the browser's XMLHttpRequest implementation to + /** + * JSDOC SOURCE PapiRendererXMLHttpRequest This wraps the browser's XMLHttpRequest implementation to * provide better control over internet access. It is isomorphic with the standard XMLHttpRequest, * so it should act as a drop-in replacement. * @@ -4696,7 +4389,7 @@ declare module 'renderer/services/renderer-xml-http-request.service' { constructor(); } } -declare module '@papi/frontend' { +declare module 'renderer/services/papi-frontend.service' { /** * Unified module for accessing API features in the renderer. * @@ -4711,178 +4404,80 @@ declare module '@papi/frontend' { import { PapiFrontendProjectDataProviderService } from 'shared/services/project-data-provider.service'; import { SettingsService } from 'shared/services/settings.service'; import { DialogService } from 'shared/services/dialog.service-model'; - import * as papiReact from '@papi/frontend/react'; + import * as papiReact from 'renderer/services/papi-frontend-react.service'; import PapiRendererWebSocket from 'renderer/services/renderer-web-socket.service'; import { IMenuDataService } from 'shared/services/menu-data.service-model'; import PapiRendererXMLHttpRequest from 'renderer/services/renderer-xml-http-request.service'; const papi: { /** This is just an alias for internet.fetch */ fetch: typeof globalThis.fetch; - /** This wraps the browser's WebSocket implementation to provide - * better control over internet access. It is isomorphic with the standard WebSocket, so it should - * act as a drop-in replacement. - * - * Note that the Node WebSocket implementation is different and not wrapped here. - */ + /** JSDOC DESTINATION PapiRendererWebSocket */ WebSocket: typeof PapiRendererWebSocket; - /** This wraps the browser's XMLHttpRequest implementation to - * provide better control over internet access. It is isomorphic with the standard XMLHttpRequest, - * so it should act as a drop-in replacement. - * - * Note that Node doesn't have a native implementation, so this is only for the renderer. - */ + /** JSDOC DESTINATION PapiRendererXMLHttpRequest */ XMLHttpRequest: typeof PapiRendererXMLHttpRequest; - /** - * - * The command service allows you to exchange messages with other components in the platform. You - * can register a command that other services and extensions can send you. You can send commands to - * other services and extensions that have registered commands. - */ + /** JSDOC DESTINATION commandService */ commands: typeof commandService; - /** - * - * Service exposing various functions related to using webViews - * - * WebViews are iframes in the Platform.Bible UI into which extensions load frontend code, either - * HTML or React components. - */ + /** JSDOC DESTINATION papiWebViewService */ webViews: WebViewServiceType; - /** - * - * Prompt the user for responses with dialogs - */ + /** JSDOC DESTINATION dialogService */ dialogs: DialogService; - /** - * - * Service that provides a way to send and receive network events - */ + /** JSDOC DESTINATION papiNetworkService */ network: PapiNetworkService; - /** - * - * All extensions and services should use this logger to provide a unified output of logs - */ + /** JSDOC DESTINATION logger */ logger: import('electron-log').MainLogger & { default: import('electron-log').MainLogger; }; - /** - * - * Service that provides a way to call `fetch` since the original function is not available - */ + /** JSDOC DESTINATION internetService */ internet: InternetService; - /** - * - * Service that allows extensions to send and receive data to/from other extensions - */ + /** JSDOC DESTINATION dataProviderService */ dataProviders: DataProviderService; - /** - * - * Service that gets project data providers - */ + /** JSDOC DESTINATION papiFrontendProjectDataProviderService */ projectDataProviders: PapiFrontendProjectDataProviderService; - /** - * - * Provides metadata for projects known by the platform - */ + /** JSDOC DESTINATION projectLookupService */ projectLookup: ProjectLookupServiceType; /** + * JSDOC SOURCE papiReact * * React hooks that enable interacting with the `papi` in React components more easily. */ react: typeof papiReact; - /** - * - * Service that allows to get and set settings in local storage - */ + /** JSDOC DESTINATION settingsService */ settings: SettingsService; - /** - * - * Service that allows to get and store menu data - */ + /** JSDOC DESTINATION menuDataService */ menuData: IMenuDataService; }; export default papi; /** This is just an alias for internet.fetch */ export const fetch: typeof globalThis.fetch; - /** This wraps the browser's WebSocket implementation to provide - * better control over internet access. It is isomorphic with the standard WebSocket, so it should - * act as a drop-in replacement. - * - * Note that the Node WebSocket implementation is different and not wrapped here. - */ + /** JSDOC DESTINATION PapiRendererWebSocket */ export const WebSocket: typeof PapiRendererWebSocket; - /** This wraps the browser's XMLHttpRequest implementation to - * provide better control over internet access. It is isomorphic with the standard XMLHttpRequest, - * so it should act as a drop-in replacement. - * - * Note that Node doesn't have a native implementation, so this is only for the renderer. - */ + /** JSDOC DESTINATION PapiRendererXMLHttpRequest */ export const XMLHttpRequest: typeof PapiRendererXMLHttpRequest; - /** - * - * The command service allows you to exchange messages with other components in the platform. You - * can register a command that other services and extensions can send you. You can send commands to - * other services and extensions that have registered commands. - */ + /** JSDOC DESTINATION commandService */ export const commands: typeof commandService; - /** - * - * Service exposing various functions related to using webViews - * - * WebViews are iframes in the Platform.Bible UI into which extensions load frontend code, either - * HTML or React components. - */ + /** JSDOC DESTINATION papiWebViewService */ export const webViews: WebViewServiceType; - /** - * - * Prompt the user for responses with dialogs - */ + /** JSDOC DESTINATION dialogService */ export const dialogs: DialogService; - /** - * - * Service that provides a way to send and receive network events - */ + /** JSDOC DESTINATION papiNetworkService */ export const network: PapiNetworkService; - /** - * - * All extensions and services should use this logger to provide a unified output of logs - */ + /** JSDOC DESTINATION logger */ export const logger: import('electron-log').MainLogger & { default: import('electron-log').MainLogger; }; - /** - * - * Service that provides a way to call `fetch` since the original function is not available - */ + /** JSDOC DESTINATION internetService */ export const internet: InternetService; - /** - * - * Service that allows extensions to send and receive data to/from other extensions - */ + /** JSDOC DESTINATION dataProviderService */ export const dataProviders: DataProviderService; - /** - * - * Service that registers and gets project data providers - */ + /** JSDOC DESTINATION papiBackendProjectDataProviderService */ export const projectDataProviders: PapiFrontendProjectDataProviderService; - /** - * - * Provides metadata for projects known by the platform - */ + /** JSDOC DESTINATION projectLookupService */ export const projectLookup: ProjectLookupServiceType; - /** - * - * React hooks that enable interacting with the `papi` in React components more easily. - */ + /** JSDOC DESTINATION papiReact */ export const react: typeof papiReact; - /** - * - * Service that allows to get and set settings in local storage - */ + /** JSDOC DESTINATION settingsService */ export const settings: SettingsService; - /** - * - * Service that allows to get and store menu data - */ + /** JSDOC DESTINATION menuDataService */ export const menuData: IMenuDataService; export type Papi = typeof papi; } diff --git a/lib/platform-bible-react/dist/index.d.ts b/lib/platform-bible-react/dist/index.d.ts index cd821a74ca..82ce47c86d 100644 --- a/lib/platform-bible-react/dist/index.d.ts +++ b/lib/platform-bible-react/dist/index.d.ts @@ -825,5 +825,3 @@ export declare const usePromise: (promiseFactoryCallback: (() => Promise) export { MenuColumnInfo as MenuColumn, }; - -export {}; diff --git a/lib/platform-bible-utils/dist/index.cjs b/lib/platform-bible-utils/dist/index.cjs index 9e7838e077..8b8db2ceaf 100644 --- a/lib/platform-bible-utils/dist/index.cjs +++ b/lib/platform-bible-utils/dist/index.cjs @@ -1,2 +1,2 @@ -"use strict";var K=Object.defineProperty;var F=(t,e,r)=>e in t?K(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var p=(t,e,r)=>(F(t,typeof e!="symbol"?e+"":e,r),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class L{constructor(e,r=1e4){p(this,"variableName");p(this,"promiseToValue");p(this,"resolver");p(this,"rejecter");this.variableName=e,this.promiseToValue=new Promise((s,a)=>{this.resolver=s,this.rejecter=a}),r>0&&setTimeout(()=>{this.rejecter&&(this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`),this.complete())},r),Object.seal(this)}get promise(){return this.promiseToValue}get hasSettled(){return Object.isFrozen(this)}resolveToValue(e,r=!1){if(this.resolver)console.debug(`${this.variableName} is being resolved now`),this.resolver(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent resolution of ${this.variableName}`)}}rejectWithReason(e,r=!1){if(this.rejecter)console.debug(`${this.variableName} is being rejected now`),this.rejecter(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent rejection of ${this.variableName}`)}}complete(){this.resolver=void 0,this.rejecter=void 0,Object.freeze(this)}}function W(){return"00-0-4-1-000".replace(/[^-]/g,t=>((Math.random()+~~t)*65536>>t).toString(16).padStart(4,"0"))}function M(t){return typeof t=="string"||t instanceof String}function y(t){return JSON.parse(JSON.stringify(t))}function k(t,e=300){if(M(t))throw new Error("Tried to debounce a string! Could be XSS");let r;return(...s)=>{clearTimeout(r),r=setTimeout(()=>t(...s),e)}}function Z(t,e,r){const s=new Map;return t.forEach(a=>{const i=e(a),n=s.get(i),u=r?r(a,i):a;n?n.push(u):s.set(i,[u])}),s}function X(t){return typeof t=="object"&&t!==null&&"message"in t&&typeof t.message=="string"}function Q(t){if(X(t))return t;try{return new Error(JSON.stringify(t))}catch{return new Error(String(t))}}function Y(t){return Q(t).message}function T(t){return new Promise(e=>setTimeout(e,t))}function ee(t,e){const r=T(e).then(()=>{});return Promise.any([r,t()])}function te(t,e="obj"){const r=new Set;Object.getOwnPropertyNames(t).forEach(a=>{try{typeof t[a]=="function"&&r.add(a)}catch(i){console.debug(`Skipping ${a} on ${e} due to error: ${i}`)}});let s=Object.getPrototypeOf(t);for(;s&&Object.getPrototypeOf(s);)Object.getOwnPropertyNames(s).forEach(a=>{try{typeof t[a]=="function"&&r.add(a)}catch(i){console.debug(`Skipping ${a} on ${e}'s prototype due to error: ${i}`)}}),s=Object.getPrototypeOf(s);return r}function re(t,e={}){return new Proxy(e,{get(r,s){return s in r?r[s]:async(...a)=>(await t())[s](...a)}})}class se{constructor(e,r){p(this,"baseDocument");p(this,"contributions",new Map);p(this,"latestOutput");p(this,"options");this.baseDocument=e,this.options=r,this.updateBaseDocument(e)}updateBaseDocument(e){return this.validateStartingDocument(e),this.baseDocument=this.options.copyDocuments?y(e):e,this.rebuild()}addOrUpdateContribution(e,r){this.validateContribution(e,r);const s=this.contributions.get(e),a=this.options.copyDocuments&&r?y(r):r;this.contributions.set(e,a);try{return this.rebuild()}catch(i){throw s?this.contributions.set(e,s):this.contributions.delete(e),new Error(`Error when setting the document named ${e}: ${i}`)}}deleteContribution(e){const r=this.contributions.get(e);if(!r)throw new Error("{documentKey} does not exist");this.contributions.delete(e);try{return this.rebuild()}catch(s){throw this.contributions.set(e,r),new Error(`Error when deleting the document named ${e}: ${s}`)}}rebuild(){if(this.contributions.size===0){let r=y(this.baseDocument);return r=this.transformFinalOutput(r),this.validateOutput(r),this.latestOutput=r,this.latestOutput}let e=this.baseDocument;return this.contributions.forEach(r=>{e=R(e,r,this.options.ignoreDuplicateProperties),this.validateOutput(e)}),e=this.transformFinalOutput(e),this.validateOutput(e),this.latestOutput=e,this.latestOutput}}function ae(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||Array.isArray(r))&&(e=!1)}),e}function ie(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||!Array.isArray(r))&&(e=!1)}),e}function R(t,e,r){const s=y(t);return e&&Object.keys(e).forEach(a=>{if(Object.hasOwn(t,a)){if(ae(t[a],e[a]))s[a]=R(t[a],e[a],r);else if(ie(t[a],e[a]))s[a]=s[a].concat(e[a]);else if(!r)throw new Error(`Cannot merge objects: key "${a}" already exists in the target object`)}else s[a]=e[a]}),s}class ne{constructor(e="Anonymous"){p(this,"unsubscribers",new Set);this.name=e}add(...e){e.forEach(r=>{"dispose"in r?this.unsubscribers.add(r.dispose):this.unsubscribers.add(r)})}async runAllUnsubscribers(){const e=[...this.unsubscribers].map(s=>s()),r=await Promise.all(e);return this.unsubscribers.clear(),r.every((s,a)=>(s||console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${a} failed!`),s))}}class oe{constructor(){p(this,"subscribe",this.event);p(this,"subscriptions");p(this,"lazyEvent");p(this,"isDisposed",!1);p(this,"dispose",()=>this.disposeFn());p(this,"emit",e=>{this.emitFn(e)})}get event(){return this.assertNotDisposed(),this.lazyEvent||(this.lazyEvent=e=>{if(!e||typeof e!="function")throw new Error("Event handler callback must be a function!");return this.subscriptions||(this.subscriptions=[]),this.subscriptions.push(e),()=>{if(!this.subscriptions)return!1;const r=this.subscriptions.indexOf(e);return r<0?!1:(this.subscriptions.splice(r,1),!0)}}),this.lazyEvent}emitFn(e){var r;this.assertNotDisposed(),(r=this.subscriptions)==null||r.forEach(s=>s(e))}assertNotDisposed(){if(this.isDisposed)throw new Error("Emitter is disposed")}disposeFn(){return this.assertNotDisposed(),this.isDisposed=!0,this.subscriptions=void 0,this.lazyEvent=void 0,Promise.resolve(!0)}}const I=[{shortName:"ERR",fullNames:["ERROR"],chapters:-1},{shortName:"GEN",fullNames:["Genesis"],chapters:50},{shortName:"EXO",fullNames:["Exodus"],chapters:40},{shortName:"LEV",fullNames:["Leviticus"],chapters:27},{shortName:"NUM",fullNames:["Numbers"],chapters:36},{shortName:"DEU",fullNames:["Deuteronomy"],chapters:34},{shortName:"JOS",fullNames:["Joshua"],chapters:24},{shortName:"JDG",fullNames:["Judges"],chapters:21},{shortName:"RUT",fullNames:["Ruth"],chapters:4},{shortName:"1SA",fullNames:["1 Samuel"],chapters:31},{shortName:"2SA",fullNames:["2 Samuel"],chapters:24},{shortName:"1KI",fullNames:["1 Kings"],chapters:22},{shortName:"2KI",fullNames:["2 Kings"],chapters:25},{shortName:"1CH",fullNames:["1 Chronicles"],chapters:29},{shortName:"2CH",fullNames:["2 Chronicles"],chapters:36},{shortName:"EZR",fullNames:["Ezra"],chapters:10},{shortName:"NEH",fullNames:["Nehemiah"],chapters:13},{shortName:"EST",fullNames:["Esther"],chapters:10},{shortName:"JOB",fullNames:["Job"],chapters:42},{shortName:"PSA",fullNames:["Psalm","Psalms"],chapters:150},{shortName:"PRO",fullNames:["Proverbs"],chapters:31},{shortName:"ECC",fullNames:["Ecclesiastes"],chapters:12},{shortName:"SNG",fullNames:["Song of Solomon","Song of Songs"],chapters:8},{shortName:"ISA",fullNames:["Isaiah"],chapters:66},{shortName:"JER",fullNames:["Jeremiah"],chapters:52},{shortName:"LAM",fullNames:["Lamentations"],chapters:5},{shortName:"EZK",fullNames:["Ezekiel"],chapters:48},{shortName:"DAN",fullNames:["Daniel"],chapters:12},{shortName:"HOS",fullNames:["Hosea"],chapters:14},{shortName:"JOL",fullNames:["Joel"],chapters:3},{shortName:"AMO",fullNames:["Amos"],chapters:9},{shortName:"OBA",fullNames:["Obadiah"],chapters:1},{shortName:"JON",fullNames:["Jonah"],chapters:4},{shortName:"MIC",fullNames:["Micah"],chapters:7},{shortName:"NAM",fullNames:["Nahum"],chapters:3},{shortName:"HAB",fullNames:["Habakkuk"],chapters:3},{shortName:"ZEP",fullNames:["Zephaniah"],chapters:3},{shortName:"HAG",fullNames:["Haggai"],chapters:2},{shortName:"ZEC",fullNames:["Zechariah"],chapters:14},{shortName:"MAL",fullNames:["Malachi"],chapters:4},{shortName:"MAT",fullNames:["Matthew"],chapters:28},{shortName:"MRK",fullNames:["Mark"],chapters:16},{shortName:"LUK",fullNames:["Luke"],chapters:24},{shortName:"JHN",fullNames:["John"],chapters:21},{shortName:"ACT",fullNames:["Acts"],chapters:28},{shortName:"ROM",fullNames:["Romans"],chapters:16},{shortName:"1CO",fullNames:["1 Corinthians"],chapters:16},{shortName:"2CO",fullNames:["2 Corinthians"],chapters:13},{shortName:"GAL",fullNames:["Galatians"],chapters:6},{shortName:"EPH",fullNames:["Ephesians"],chapters:6},{shortName:"PHP",fullNames:["Philippians"],chapters:4},{shortName:"COL",fullNames:["Colossians"],chapters:4},{shortName:"1TH",fullNames:["1 Thessalonians"],chapters:5},{shortName:"2TH",fullNames:["2 Thessalonians"],chapters:3},{shortName:"1TI",fullNames:["1 Timothy"],chapters:6},{shortName:"2TI",fullNames:["2 Timothy"],chapters:4},{shortName:"TIT",fullNames:["Titus"],chapters:3},{shortName:"PHM",fullNames:["Philemon"],chapters:1},{shortName:"HEB",fullNames:["Hebrews"],chapters:13},{shortName:"JAS",fullNames:["James"],chapters:5},{shortName:"1PE",fullNames:["1 Peter"],chapters:5},{shortName:"2PE",fullNames:["2 Peter"],chapters:3},{shortName:"1JN",fullNames:["1 John"],chapters:5},{shortName:"2JN",fullNames:["2 John"],chapters:1},{shortName:"3JN",fullNames:["3 John"],chapters:1},{shortName:"JUD",fullNames:["Jude"],chapters:1},{shortName:"REV",fullNames:["Revelation"],chapters:22}],D=1,x=I.length-1,z=1,B=1,J=t=>{var e;return((e=I[t])==null?void 0:e.chapters)??-1},ue=(t,e)=>({bookNum:Math.max(D,Math.min(t.bookNum+e,x)),chapterNum:1,verseNum:1}),le=(t,e)=>({...t,chapterNum:Math.min(Math.max(z,t.chapterNum+e),J(t.bookNum)),verseNum:1}),ce=(t,e)=>({...t,verseNum:Math.max(B,t.verseNum+e)}),he=t=>(...e)=>t.map(s=>s(...e)).every(s=>s),fe=t=>async(...e)=>{const r=t.map(async s=>s(...e));return(await Promise.all(r)).every(s=>s)};var pe=Object.getOwnPropertyNames,me=Object.getOwnPropertySymbols,de=Object.prototype.hasOwnProperty;function O(t,e){return function(s,a,i){return t(s,a,i)&&e(s,a,i)}}function v(t){return function(r,s,a){if(!r||!s||typeof r!="object"||typeof s!="object")return t(r,s,a);var i=a.cache,n=i.get(r),u=i.get(s);if(n&&u)return n===s&&u===r;i.set(r,s),i.set(s,r);var c=t(r,s,a);return i.delete(r),i.delete(s),c}}function A(t){return pe(t).concat(me(t))}var G=Object.hasOwn||function(t,e){return de.call(t,e)};function b(t,e){return t||e?t===e:t===e||t!==t&&e!==e}var U="_owner",S=Object.getOwnPropertyDescriptor,$=Object.keys;function Ne(t,e,r){var s=t.length;if(e.length!==s)return!1;for(;s-- >0;)if(!r.equals(t[s],e[s],s,s,t,e,r))return!1;return!0}function be(t,e){return b(t.getTime(),e.getTime())}function q(t,e,r){if(t.size!==e.size)return!1;for(var s={},a=t.entries(),i=0,n,u;(n=a.next())&&!n.done;){for(var c=e.entries(),f=!1,o=0;(u=c.next())&&!u.done;){var l=n.value,h=l[0],d=l[1],m=u.value,w=m[0],H=m[1];!f&&!s[o]&&(f=r.equals(h,w,i,o,t,e,r)&&r.equals(d,H,h,w,t,e,r))&&(s[o]=!0),o++}if(!f)return!1;i++}return!0}function ge(t,e,r){var s=$(t),a=s.length;if($(e).length!==a)return!1;for(var i;a-- >0;)if(i=s[a],i===U&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!G(e,i)||!r.equals(t[i],e[i],i,i,t,e,r))return!1;return!0}function g(t,e,r){var s=A(t),a=s.length;if(A(e).length!==a)return!1;for(var i,n,u;a-- >0;)if(i=s[a],i===U&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!G(e,i)||!r.equals(t[i],e[i],i,i,t,e,r)||(n=S(t,i),u=S(e,i),(n||u)&&(!n||!u||n.configurable!==u.configurable||n.enumerable!==u.enumerable||n.writable!==u.writable)))return!1;return!0}function ye(t,e){return b(t.valueOf(),e.valueOf())}function ve(t,e){return t.source===e.source&&t.flags===e.flags}function j(t,e,r){if(t.size!==e.size)return!1;for(var s={},a=t.values(),i,n;(i=a.next())&&!i.done;){for(var u=e.values(),c=!1,f=0;(n=u.next())&&!n.done;)!c&&!s[f]&&(c=r.equals(i.value,n.value,i.value,n.value,t,e,r))&&(s[f]=!0),f++;if(!c)return!1}return!0}function Ee(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}var we="[object Arguments]",Oe="[object Boolean]",Ae="[object Date]",Se="[object Map]",$e="[object Number]",qe="[object Object]",je="[object RegExp]",Ce="[object Set]",Pe="[object String]",Me=Array.isArray,C=typeof ArrayBuffer=="function"&&ArrayBuffer.isView?ArrayBuffer.isView:null,P=Object.assign,Te=Object.prototype.toString.call.bind(Object.prototype.toString);function Re(t){var e=t.areArraysEqual,r=t.areDatesEqual,s=t.areMapsEqual,a=t.areObjectsEqual,i=t.arePrimitiveWrappersEqual,n=t.areRegExpsEqual,u=t.areSetsEqual,c=t.areTypedArraysEqual;return function(o,l,h){if(o===l)return!0;if(o==null||l==null||typeof o!="object"||typeof l!="object")return o!==o&&l!==l;var d=o.constructor;if(d!==l.constructor)return!1;if(d===Object)return a(o,l,h);if(Me(o))return e(o,l,h);if(C!=null&&C(o))return c(o,l,h);if(d===Date)return r(o,l,h);if(d===RegExp)return n(o,l,h);if(d===Map)return s(o,l,h);if(d===Set)return u(o,l,h);var m=Te(o);return m===Ae?r(o,l,h):m===je?n(o,l,h):m===Se?s(o,l,h):m===Ce?u(o,l,h):m===qe?typeof o.then!="function"&&typeof l.then!="function"&&a(o,l,h):m===we?a(o,l,h):m===Oe||m===$e||m===Pe?i(o,l,h):!1}}function Ie(t){var e=t.circular,r=t.createCustomConfig,s=t.strict,a={areArraysEqual:s?g:Ne,areDatesEqual:be,areMapsEqual:s?O(q,g):q,areObjectsEqual:s?g:ge,arePrimitiveWrappersEqual:ye,areRegExpsEqual:ve,areSetsEqual:s?O(j,g):j,areTypedArraysEqual:s?g:Ee};if(r&&(a=P({},a,r(a))),e){var i=v(a.areArraysEqual),n=v(a.areMapsEqual),u=v(a.areObjectsEqual),c=v(a.areSetsEqual);a=P({},a,{areArraysEqual:i,areMapsEqual:n,areObjectsEqual:u,areSetsEqual:c})}return a}function De(t){return function(e,r,s,a,i,n,u){return t(e,r,u)}}function xe(t){var e=t.circular,r=t.comparator,s=t.createState,a=t.equals,i=t.strict;if(s)return function(c,f){var o=s(),l=o.cache,h=l===void 0?e?new WeakMap:void 0:l,d=o.meta;return r(c,f,{cache:h,equals:a,meta:d,strict:i})};if(e)return function(c,f){return r(c,f,{cache:new WeakMap,equals:a,meta:void 0,strict:i})};var n={cache:void 0,equals:a,meta:void 0,strict:i};return function(c,f){return r(c,f,n)}}var ze=N();N({strict:!0});N({circular:!0});N({circular:!0,strict:!0});N({createInternalComparator:function(){return b}});N({strict:!0,createInternalComparator:function(){return b}});N({circular:!0,createInternalComparator:function(){return b}});N({circular:!0,createInternalComparator:function(){return b},strict:!0});function N(t){t===void 0&&(t={});var e=t.circular,r=e===void 0?!1:e,s=t.createInternalComparator,a=t.createState,i=t.strict,n=i===void 0?!1:i,u=Ie(t),c=Re(u),f=s?s(c):De(c);return xe({circular:r,comparator:c,createState:a,equals:f,strict:n})}function Be(t,e){return ze(t,e)}function E(t,e,r){return JSON.stringify(t,(a,i)=>{let n=i;return e&&(n=e(a,n)),n===void 0&&(n=null),n},r)}function _(t,e){function r(a){return Object.keys(a).forEach(i=>{a[i]===null?a[i]=void 0:typeof a[i]=="object"&&(a[i]=r(a[i]))}),a}const s=JSON.parse(t,e);if(s!==null)return typeof s=="object"?r(s):s}function Je(t){try{const e=E(t);return e===E(_(e))}catch{return!1}}const Ge=t=>t.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/"),V={title:"Platform.Bible menus",type:"object",properties:{mainMenu:{description:"Top level menu for the application",$ref:"#/$defs/multiColumnMenu"},defaultWebViewTopMenu:{description:"Default top menu for web views that don't specify their own",$ref:"#/$defs/multiColumnMenu"},defaultWebViewContextMenu:{description:"Default context menu for web views that don't specify their own",$ref:"#/$defs/singleColumnMenu"},webViewMenus:{description:"Menus that apply per web view in the application",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{$ref:"#/$defs/menusForOneWebView"}},additionalProperties:!1}},required:["mainMenu","defaultWebViewTopMenu","defaultWebViewContextMenu","webViewMenus"],additionalProperties:!1,$defs:{localizeKey:{description:"Identifier for a string that will be localized in a menu based on the user's UI language",type:"string",pattern:"^%[\\w\\-\\.]+%$"},referencedItem:{description:"Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)",type:"string",pattern:"^[\\w\\-]+\\.[\\w\\-]+$"},columnsWithHeaders:{description:"Group of columns that can be combined with other columns to form a multi-column menu",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single column with a header string",type:"object",properties:{label:{description:"Header text for this this column in the UI",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},order:{description:"Relative order of this column compared to other columns (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu groups to this column",type:"boolean"}},required:["label","order"],additionalProperties:!1}},properties:{isExtensible:{description:"Defines whether contributions are allowed to add columns to this multi-column menu",type:"boolean"}}},menuGroups:{description:"Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single group that contains menu items",type:"object",oneOf:[{properties:{column:{description:"Column where this group belongs, not required for single column menus",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["order"],additionalProperties:!1},{properties:{menuItem:{description:"Menu item that anchors the submenu where this group belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["menuItem","order"],additionalProperties:!1}]}},additionalProperties:!1},menuItem:{description:"Single item in a menu that can be clicked on to take an action or can be the parent of a submenu",type:"object",oneOf:[{properties:{id:{description:"ID for this menu item that holds a submenu",$ref:"#/$defs/referencedItem"}},required:["id"]},{properties:{command:{description:"Name of the PAPI command to run when this menu item is selected.",$ref:"#/$defs/referencedItem"},iconPathBefore:{description:"Path to the icon to display before the menu text",type:"string"},iconPathAfter:{description:"Path to the icon to display after the menu text",type:"string"}},required:["command"]}],properties:{label:{description:"Key that represents the text of this menu item to display",$ref:"#/$defs/localizeKey"},tooltip:{description:"Key that represents the text to display if a mouse pointer hovers over the menu item",$ref:"#/$defs/localizeKey"},searchTerms:{description:"Key that represents additional words the platform should reference when users are searching for menu items",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},group:{description:"Group to which this menu item belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this menu item compared to other menu items in the same group (sorted ascending)",type:"number"}},required:["label","group","order"],unevaluatedProperties:!1},groupsAndItems:{description:"Core schema for a column",type:"object",properties:{groups:{description:"Groups that belong in this menu",$ref:"#/$defs/menuGroups"},items:{description:"List of menu items that belong in this menu",type:"array",items:{$ref:"#/$defs/menuItem"},uniqueItems:!0}},required:["groups","items"]},singleColumnMenu:{description:"Menu that contains a column without a header",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"}],unevaluatedProperties:!1},multiColumnMenu:{description:"Menu that can contain multiple columns with headers",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"},{properties:{columns:{description:"Columns that belong in this menu",$ref:"#/$defs/columnsWithHeaders"}},required:["columns"]}],unevaluatedProperties:!1},menusForOneWebView:{description:"Set of menus that are associated with a single tab",type:"object",properties:{includeDefaults:{description:"Indicates whether the platform default menus should be included for this webview",type:"boolean"},topMenu:{description:"Menu that opens when you click on the top left corner of a tab",$ref:"#/$defs/multiColumnMenu"},contextMenu:{description:"Menu that opens when you right click on the main body/area of a tab",$ref:"#/$defs/singleColumnMenu"}},additionalProperties:!1}}};Object.freeze(V);exports.AsyncVariable=L;exports.DocumentCombinerEngine=se;exports.FIRST_SCR_BOOK_NUM=D;exports.FIRST_SCR_CHAPTER_NUM=z;exports.FIRST_SCR_VERSE_NUM=B;exports.LAST_SCR_BOOK_NUM=x;exports.PlatformEventEmitter=oe;exports.UnsubscriberAsyncList=ne;exports.aggregateUnsubscriberAsyncs=fe;exports.aggregateUnsubscribers=he;exports.createSyncProxyForAsyncObject=re;exports.debounce=k;exports.deepClone=y;exports.deepEqual=Be;exports.deserialize=_;exports.getAllObjectFunctionNames=te;exports.getChaptersForBook=J;exports.getErrorMessage=Y;exports.groupBy=Z;exports.htmlEncode=Ge;exports.isSerializable=Je;exports.isString=M;exports.menuDocumentSchema=V;exports.newGuid=W;exports.offsetBook=ue;exports.offsetChapter=le;exports.offsetVerse=ce;exports.serialize=E;exports.wait=T;exports.waitForDuration=ee; +"use strict";var ae=Object.defineProperty;var oe=(t,e,r)=>e in t?ae(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var p=(t,e,r)=>(oe(t,typeof e!="symbol"?e+"":e,r),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class ie{constructor(e,r=1e4){p(this,"variableName");p(this,"promiseToValue");p(this,"resolver");p(this,"rejecter");this.variableName=e,this.promiseToValue=new Promise((s,n)=>{this.resolver=s,this.rejecter=n}),r>0&&setTimeout(()=>{this.rejecter&&(this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`),this.complete())},r),Object.seal(this)}get promise(){return this.promiseToValue}get hasSettled(){return Object.isFrozen(this)}resolveToValue(e,r=!1){if(this.resolver)console.debug(`${this.variableName} is being resolved now`),this.resolver(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent resolution of ${this.variableName}`)}}rejectWithReason(e,r=!1){if(this.rejecter)console.debug(`${this.variableName} is being rejected now`),this.rejecter(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent rejection of ${this.variableName}`)}}complete(){this.resolver=void 0,this.rejecter=void 0,Object.freeze(this)}}function ue(){return"00-0-4-1-000".replace(/[^-]/g,t=>((Math.random()+~~t)*65536>>t).toString(16).padStart(4,"0"))}function B(t){return typeof t=="string"||t instanceof String}function E(t){return JSON.parse(JSON.stringify(t))}function le(t,e=300){if(B(t))throw new Error("Tried to debounce a string! Could be XSS");let r;return(...s)=>{clearTimeout(r),r=setTimeout(()=>t(...s),e)}}function ce(t,e,r){const s=new Map;return t.forEach(n=>{const a=e(n),o=s.get(a),i=r?r(n,a):n;o?o.push(i):s.set(a,[i])}),s}function fe(t){return typeof t=="object"&&t!==null&&"message"in t&&typeof t.message=="string"}function he(t){if(fe(t))return t;try{return new Error(JSON.stringify(t))}catch{return new Error(String(t))}}function pe(t){return he(t).message}function J(t){return new Promise(e=>setTimeout(e,t))}function me(t,e){const r=J(e).then(()=>{});return Promise.any([r,t()])}function de(t,e="obj"){const r=new Set;Object.getOwnPropertyNames(t).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(a){console.debug(`Skipping ${n} on ${e} due to error: ${a}`)}});let s=Object.getPrototypeOf(t);for(;s&&Object.getPrototypeOf(s);)Object.getOwnPropertyNames(s).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(a){console.debug(`Skipping ${n} on ${e}'s prototype due to error: ${a}`)}}),s=Object.getPrototypeOf(s);return r}function ge(t,e={}){return new Proxy(e,{get(r,s){return s in r?r[s]:async(...n)=>(await t())[s](...n)}})}class be{constructor(e,r){p(this,"baseDocument");p(this,"contributions",new Map);p(this,"latestOutput");p(this,"options");this.baseDocument=e,this.options=r,this.updateBaseDocument(e)}updateBaseDocument(e){return this.validateStartingDocument(e),this.baseDocument=this.options.copyDocuments?E(e):e,this.rebuild()}addOrUpdateContribution(e,r){this.validateContribution(e,r);const s=this.contributions.get(e),n=this.options.copyDocuments&&r?E(r):r;this.contributions.set(e,n);try{return this.rebuild()}catch(a){throw s?this.contributions.set(e,s):this.contributions.delete(e),new Error(`Error when setting the document named ${e}: ${a}`)}}deleteContribution(e){const r=this.contributions.get(e);if(!r)throw new Error("{documentKey} does not exist");this.contributions.delete(e);try{return this.rebuild()}catch(s){throw this.contributions.set(e,r),new Error(`Error when deleting the document named ${e}: ${s}`)}}rebuild(){if(this.contributions.size===0){let r=E(this.baseDocument);return r=this.transformFinalOutput(r),this.validateOutput(r),this.latestOutput=r,this.latestOutput}let e=this.baseDocument;return this.contributions.forEach(r=>{e=G(e,r,this.options.ignoreDuplicateProperties),this.validateOutput(e)}),e=this.transformFinalOutput(e),this.validateOutput(e),this.latestOutput=e,this.latestOutput}}function Ne(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||Array.isArray(r))&&(e=!1)}),e}function ve(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||!Array.isArray(r))&&(e=!1)}),e}function G(t,e,r){const s=E(t);return e&&Object.keys(e).forEach(n=>{if(Object.hasOwn(t,n)){if(Ne(t[n],e[n]))s[n]=G(t[n],e[n],r);else if(ve(t[n],e[n]))s[n]=s[n].concat(e[n]);else if(!r)throw new Error(`Cannot merge objects: key "${n}" already exists in the target object`)}else s[n]=e[n]}),s}class ye{constructor(e="Anonymous"){p(this,"unsubscribers",new Set);this.name=e}add(...e){e.forEach(r=>{"dispose"in r?this.unsubscribers.add(r.dispose):this.unsubscribers.add(r)})}async runAllUnsubscribers(){const e=[...this.unsubscribers].map(s=>s()),r=await Promise.all(e);return this.unsubscribers.clear(),r.every((s,n)=>(s||console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${n} failed!`),s))}}class Ee{constructor(){p(this,"subscribe",this.event);p(this,"subscriptions");p(this,"lazyEvent");p(this,"isDisposed",!1);p(this,"dispose",()=>this.disposeFn());p(this,"emit",e=>{this.emitFn(e)})}get event(){return this.assertNotDisposed(),this.lazyEvent||(this.lazyEvent=e=>{if(!e||typeof e!="function")throw new Error("Event handler callback must be a function!");return this.subscriptions||(this.subscriptions=[]),this.subscriptions.push(e),()=>{if(!this.subscriptions)return!1;const r=this.subscriptions.indexOf(e);return r<0?!1:(this.subscriptions.splice(r,1),!0)}}),this.lazyEvent}emitFn(e){var r;this.assertNotDisposed(),(r=this.subscriptions)==null||r.forEach(s=>s(e))}assertNotDisposed(){if(this.isDisposed)throw new Error("Emitter is disposed")}disposeFn(){return this.assertNotDisposed(),this.isDisposed=!0,this.subscriptions=void 0,this.lazyEvent=void 0,Promise.resolve(!0)}}const U=[{shortName:"ERR",fullNames:["ERROR"],chapters:-1},{shortName:"GEN",fullNames:["Genesis"],chapters:50},{shortName:"EXO",fullNames:["Exodus"],chapters:40},{shortName:"LEV",fullNames:["Leviticus"],chapters:27},{shortName:"NUM",fullNames:["Numbers"],chapters:36},{shortName:"DEU",fullNames:["Deuteronomy"],chapters:34},{shortName:"JOS",fullNames:["Joshua"],chapters:24},{shortName:"JDG",fullNames:["Judges"],chapters:21},{shortName:"RUT",fullNames:["Ruth"],chapters:4},{shortName:"1SA",fullNames:["1 Samuel"],chapters:31},{shortName:"2SA",fullNames:["2 Samuel"],chapters:24},{shortName:"1KI",fullNames:["1 Kings"],chapters:22},{shortName:"2KI",fullNames:["2 Kings"],chapters:25},{shortName:"1CH",fullNames:["1 Chronicles"],chapters:29},{shortName:"2CH",fullNames:["2 Chronicles"],chapters:36},{shortName:"EZR",fullNames:["Ezra"],chapters:10},{shortName:"NEH",fullNames:["Nehemiah"],chapters:13},{shortName:"EST",fullNames:["Esther"],chapters:10},{shortName:"JOB",fullNames:["Job"],chapters:42},{shortName:"PSA",fullNames:["Psalm","Psalms"],chapters:150},{shortName:"PRO",fullNames:["Proverbs"],chapters:31},{shortName:"ECC",fullNames:["Ecclesiastes"],chapters:12},{shortName:"SNG",fullNames:["Song of Solomon","Song of Songs"],chapters:8},{shortName:"ISA",fullNames:["Isaiah"],chapters:66},{shortName:"JER",fullNames:["Jeremiah"],chapters:52},{shortName:"LAM",fullNames:["Lamentations"],chapters:5},{shortName:"EZK",fullNames:["Ezekiel"],chapters:48},{shortName:"DAN",fullNames:["Daniel"],chapters:12},{shortName:"HOS",fullNames:["Hosea"],chapters:14},{shortName:"JOL",fullNames:["Joel"],chapters:3},{shortName:"AMO",fullNames:["Amos"],chapters:9},{shortName:"OBA",fullNames:["Obadiah"],chapters:1},{shortName:"JON",fullNames:["Jonah"],chapters:4},{shortName:"MIC",fullNames:["Micah"],chapters:7},{shortName:"NAM",fullNames:["Nahum"],chapters:3},{shortName:"HAB",fullNames:["Habakkuk"],chapters:3},{shortName:"ZEP",fullNames:["Zephaniah"],chapters:3},{shortName:"HAG",fullNames:["Haggai"],chapters:2},{shortName:"ZEC",fullNames:["Zechariah"],chapters:14},{shortName:"MAL",fullNames:["Malachi"],chapters:4},{shortName:"MAT",fullNames:["Matthew"],chapters:28},{shortName:"MRK",fullNames:["Mark"],chapters:16},{shortName:"LUK",fullNames:["Luke"],chapters:24},{shortName:"JHN",fullNames:["John"],chapters:21},{shortName:"ACT",fullNames:["Acts"],chapters:28},{shortName:"ROM",fullNames:["Romans"],chapters:16},{shortName:"1CO",fullNames:["1 Corinthians"],chapters:16},{shortName:"2CO",fullNames:["2 Corinthians"],chapters:13},{shortName:"GAL",fullNames:["Galatians"],chapters:6},{shortName:"EPH",fullNames:["Ephesians"],chapters:6},{shortName:"PHP",fullNames:["Philippians"],chapters:4},{shortName:"COL",fullNames:["Colossians"],chapters:4},{shortName:"1TH",fullNames:["1 Thessalonians"],chapters:5},{shortName:"2TH",fullNames:["2 Thessalonians"],chapters:3},{shortName:"1TI",fullNames:["1 Timothy"],chapters:6},{shortName:"2TI",fullNames:["2 Timothy"],chapters:4},{shortName:"TIT",fullNames:["Titus"],chapters:3},{shortName:"PHM",fullNames:["Philemon"],chapters:1},{shortName:"HEB",fullNames:["Hebrews"],chapters:13},{shortName:"JAS",fullNames:["James"],chapters:5},{shortName:"1PE",fullNames:["1 Peter"],chapters:5},{shortName:"2PE",fullNames:["2 Peter"],chapters:3},{shortName:"1JN",fullNames:["1 John"],chapters:5},{shortName:"2JN",fullNames:["2 John"],chapters:1},{shortName:"3JN",fullNames:["3 John"],chapters:1},{shortName:"JUD",fullNames:["Jude"],chapters:1},{shortName:"REV",fullNames:["Revelation"],chapters:22}],V=1,F=U.length-1,H=1,k=1,K=t=>{var e;return((e=U[t])==null?void 0:e.chapters)??-1},we=(t,e)=>({bookNum:Math.max(V,Math.min(t.bookNum+e,F)),chapterNum:1,verseNum:1}),Oe=(t,e)=>({...t,chapterNum:Math.min(Math.max(H,t.chapterNum+e),K(t.bookNum)),verseNum:1}),$e=(t,e)=>({...t,verseNum:Math.max(k,t.verseNum+e)}),Ae=t=>(...e)=>t.map(s=>s(...e)).every(s=>s),qe=t=>async(...e)=>{const r=t.map(async s=>s(...e));return(await Promise.all(r)).every(s=>s)};var M=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},b={},Se=()=>{const t="\\ud800-\\udfff",e="\\u0300-\\u036f",r="\\ufe20-\\ufe2f",s="\\u20d0-\\u20ff",n="\\u1ab0-\\u1aff",a="\\u1dc0-\\u1dff",o=e+r+s+n+a,i="\\ufe0e\\ufe0f",c="\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93",h=`[${t}]`,u=`[${o}]`,l="\\ud83c[\\udffb-\\udfff]",f=`(?:${u}|${l})`,d=`[^${t}]`,m="(?:\\uD83C[\\uDDE6-\\uDDFF]){2}",v="[\\ud800-\\udbff][\\udc00-\\udfff]",$="\\u200d",ee="(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)",te=`[${c}]`,j=`${f}?`,C=`[${i}]?`,re=`(?:${$}(?:${[d,m,v].join("|")})${C+j})*`,se=C+j+re,ne=`(?:${[`${d}${u}?`,u,m,v,h,te].join("|")})`;return new RegExp(`${ee}|${l}(?=${l})|${ne+se}`,"g")},je=M&&M.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(b,"__esModule",{value:!0});var O=je(Se);function A(t){if(typeof t!="string")throw new Error("A string is expected as input");return t.match(O.default())||[]}var Ce=b.toArray=A;function S(t){if(typeof t!="string")throw new Error("Input must be a string");var e=t.match(O.default());return e===null?0:e.length}var Me=b.length=S;function L(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");(typeof e!="number"||e<0)&&(e=0),typeof r=="number"&&r<0&&(r=0);var s=t.match(O.default());return s?s.slice(e,r).join(""):""}var Pe=b.substring=L;function Te(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");var s=S(t);if(typeof e!="number"&&(e=parseInt(e,10)),e>=s)return"";e<0&&(e+=s);var n;typeof r>"u"?n=s:(typeof r!="number"&&(r=parseInt(r,10)),n=r>=0?r+e:e);var a=t.match(O.default());return a?a.slice(e,n).join(""):""}b.substr=Te;function Re(t,e,r,s){if(e===void 0&&(e=16),r===void 0&&(r="#"),s===void 0&&(s="right"),typeof t!="string"||typeof e!="number")throw new Error("Invalid arguments specified");if(["left","right"].indexOf(s)===-1)throw new Error("Pad position should be either left or right");typeof r!="string"&&(r=String(r));var n=S(t);if(n>e)return L(t,0,e);if(n=s.length)return e===""?s.length:-1;if(e==="")return r;var n=A(e),a=!1,o;for(o=r;o{W(t,e,r,"left")},Ge=(t,e,r)=>{W(t,e,r,"right")},Ue=(t,e="NFC")=>{const r=e.toUpperCase();return r==="NONE"?t:t.normalize(r)};var Ve=Object.getOwnPropertyNames,Fe=Object.getOwnPropertySymbols,He=Object.prototype.hasOwnProperty;function P(t,e){return function(s,n,a){return t(s,n,a)&&e(s,n,a)}}function w(t){return function(r,s,n){if(!r||!s||typeof r!="object"||typeof s!="object")return t(r,s,n);var a=n.cache,o=a.get(r),i=a.get(s);if(o&&i)return o===s&&i===r;a.set(r,s),a.set(s,r);var c=t(r,s,n);return a.delete(r),a.delete(s),c}}function T(t){return Ve(t).concat(Fe(t))}var Z=Object.hasOwn||function(t,e){return He.call(t,e)};function N(t,e){return t||e?t===e:t===e||t!==t&&e!==e}var X="_owner",R=Object.getOwnPropertyDescriptor,D=Object.keys;function ke(t,e,r){var s=t.length;if(e.length!==s)return!1;for(;s-- >0;)if(!r.equals(t[s],e[s],s,s,t,e,r))return!1;return!0}function Ke(t,e){return N(t.getTime(),e.getTime())}function I(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.entries(),a=0,o,i;(o=n.next())&&!o.done;){for(var c=e.entries(),h=!1,u=0;(i=c.next())&&!i.done;){var l=o.value,f=l[0],d=l[1],m=i.value,v=m[0],$=m[1];!h&&!s[u]&&(h=r.equals(f,v,a,u,t,e,r)&&r.equals(d,$,f,v,t,e,r))&&(s[u]=!0),u++}if(!h)return!1;a++}return!0}function Le(t,e,r){var s=D(t),n=s.length;if(D(e).length!==n)return!1;for(var a;n-- >0;)if(a=s[n],a===X&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!Z(e,a)||!r.equals(t[a],e[a],a,a,t,e,r))return!1;return!0}function y(t,e,r){var s=T(t),n=s.length;if(T(e).length!==n)return!1;for(var a,o,i;n-- >0;)if(a=s[n],a===X&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!Z(e,a)||!r.equals(t[a],e[a],a,a,t,e,r)||(o=R(t,a),i=R(e,a),(o||i)&&(!o||!i||o.configurable!==i.configurable||o.enumerable!==i.enumerable||o.writable!==i.writable)))return!1;return!0}function We(t,e){return N(t.valueOf(),e.valueOf())}function Ze(t,e){return t.source===e.source&&t.flags===e.flags}function x(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.values(),a,o;(a=n.next())&&!a.done;){for(var i=e.values(),c=!1,h=0;(o=i.next())&&!o.done;)!c&&!s[h]&&(c=r.equals(a.value,o.value,a.value,o.value,t,e,r))&&(s[h]=!0),h++;if(!c)return!1}return!0}function Xe(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}var Qe="[object Arguments]",Ye="[object Boolean]",et="[object Date]",tt="[object Map]",rt="[object Number]",st="[object Object]",nt="[object RegExp]",at="[object Set]",ot="[object String]",it=Array.isArray,_=typeof ArrayBuffer=="function"&&ArrayBuffer.isView?ArrayBuffer.isView:null,z=Object.assign,ut=Object.prototype.toString.call.bind(Object.prototype.toString);function lt(t){var e=t.areArraysEqual,r=t.areDatesEqual,s=t.areMapsEqual,n=t.areObjectsEqual,a=t.arePrimitiveWrappersEqual,o=t.areRegExpsEqual,i=t.areSetsEqual,c=t.areTypedArraysEqual;return function(u,l,f){if(u===l)return!0;if(u==null||l==null||typeof u!="object"||typeof l!="object")return u!==u&&l!==l;var d=u.constructor;if(d!==l.constructor)return!1;if(d===Object)return n(u,l,f);if(it(u))return e(u,l,f);if(_!=null&&_(u))return c(u,l,f);if(d===Date)return r(u,l,f);if(d===RegExp)return o(u,l,f);if(d===Map)return s(u,l,f);if(d===Set)return i(u,l,f);var m=ut(u);return m===et?r(u,l,f):m===nt?o(u,l,f):m===tt?s(u,l,f):m===at?i(u,l,f):m===st?typeof u.then!="function"&&typeof l.then!="function"&&n(u,l,f):m===Qe?n(u,l,f):m===Ye||m===rt||m===ot?a(u,l,f):!1}}function ct(t){var e=t.circular,r=t.createCustomConfig,s=t.strict,n={areArraysEqual:s?y:ke,areDatesEqual:Ke,areMapsEqual:s?P(I,y):I,areObjectsEqual:s?y:Le,arePrimitiveWrappersEqual:We,areRegExpsEqual:Ze,areSetsEqual:s?P(x,y):x,areTypedArraysEqual:s?y:Xe};if(r&&(n=z({},n,r(n))),e){var a=w(n.areArraysEqual),o=w(n.areMapsEqual),i=w(n.areObjectsEqual),c=w(n.areSetsEqual);n=z({},n,{areArraysEqual:a,areMapsEqual:o,areObjectsEqual:i,areSetsEqual:c})}return n}function ft(t){return function(e,r,s,n,a,o,i){return t(e,r,i)}}function ht(t){var e=t.circular,r=t.comparator,s=t.createState,n=t.equals,a=t.strict;if(s)return function(c,h){var u=s(),l=u.cache,f=l===void 0?e?new WeakMap:void 0:l,d=u.meta;return r(c,h,{cache:f,equals:n,meta:d,strict:a})};if(e)return function(c,h){return r(c,h,{cache:new WeakMap,equals:n,meta:void 0,strict:a})};var o={cache:void 0,equals:n,meta:void 0,strict:a};return function(c,h){return r(c,h,o)}}var pt=g();g({strict:!0});g({circular:!0});g({circular:!0,strict:!0});g({createInternalComparator:function(){return N}});g({strict:!0,createInternalComparator:function(){return N}});g({circular:!0,createInternalComparator:function(){return N}});g({circular:!0,createInternalComparator:function(){return N},strict:!0});function g(t){t===void 0&&(t={});var e=t.circular,r=e===void 0?!1:e,s=t.createInternalComparator,n=t.createState,a=t.strict,o=a===void 0?!1:a,i=ct(t),c=lt(i),h=s?s(c):ft(c);return ht({circular:r,comparator:c,createState:n,equals:h,strict:o})}function mt(t,e){return pt(t,e)}function q(t,e,r){return JSON.stringify(t,(n,a)=>{let o=a;return e&&(o=e(n,o)),o===void 0&&(o=null),o},r)}function Q(t,e){function r(n){return Object.keys(n).forEach(a=>{n[a]===null?n[a]=void 0:typeof n[a]=="object"&&(n[a]=r(n[a]))}),n}const s=JSON.parse(t,e);if(s!==null)return typeof s=="object"?r(s):s}function dt(t){try{const e=q(t);return e===q(Q(e))}catch{return!1}}const gt=t=>t.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/"),Y={title:"Platform.Bible menus",type:"object",properties:{mainMenu:{description:"Top level menu for the application",$ref:"#/$defs/multiColumnMenu"},defaultWebViewTopMenu:{description:"Default top menu for web views that don't specify their own",$ref:"#/$defs/multiColumnMenu"},defaultWebViewContextMenu:{description:"Default context menu for web views that don't specify their own",$ref:"#/$defs/singleColumnMenu"},webViewMenus:{description:"Menus that apply per web view in the application",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{$ref:"#/$defs/menusForOneWebView"}},additionalProperties:!1}},required:["mainMenu","defaultWebViewTopMenu","defaultWebViewContextMenu","webViewMenus"],additionalProperties:!1,$defs:{localizeKey:{description:"Identifier for a string that will be localized in a menu based on the user's UI language",type:"string",pattern:"^%[\\w\\-\\.]+%$"},referencedItem:{description:"Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)",type:"string",pattern:"^[\\w\\-]+\\.[\\w\\-]+$"},columnsWithHeaders:{description:"Group of columns that can be combined with other columns to form a multi-column menu",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single column with a header string",type:"object",properties:{label:{description:"Header text for this this column in the UI",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},order:{description:"Relative order of this column compared to other columns (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu groups to this column",type:"boolean"}},required:["label","order"],additionalProperties:!1}},properties:{isExtensible:{description:"Defines whether contributions are allowed to add columns to this multi-column menu",type:"boolean"}}},menuGroups:{description:"Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single group that contains menu items",type:"object",oneOf:[{properties:{column:{description:"Column where this group belongs, not required for single column menus",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["order"],additionalProperties:!1},{properties:{menuItem:{description:"Menu item that anchors the submenu where this group belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["menuItem","order"],additionalProperties:!1}]}},additionalProperties:!1},menuItem:{description:"Single item in a menu that can be clicked on to take an action or can be the parent of a submenu",type:"object",oneOf:[{properties:{id:{description:"ID for this menu item that holds a submenu",$ref:"#/$defs/referencedItem"}},required:["id"]},{properties:{command:{description:"Name of the PAPI command to run when this menu item is selected.",$ref:"#/$defs/referencedItem"},iconPathBefore:{description:"Path to the icon to display before the menu text",type:"string"},iconPathAfter:{description:"Path to the icon to display after the menu text",type:"string"}},required:["command"]}],properties:{label:{description:"Key that represents the text of this menu item to display",$ref:"#/$defs/localizeKey"},tooltip:{description:"Key that represents the text to display if a mouse pointer hovers over the menu item",$ref:"#/$defs/localizeKey"},searchTerms:{description:"Key that represents additional words the platform should reference when users are searching for menu items",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},group:{description:"Group to which this menu item belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this menu item compared to other menu items in the same group (sorted ascending)",type:"number"}},required:["label","group","order"],unevaluatedProperties:!1},groupsAndItems:{description:"Core schema for a column",type:"object",properties:{groups:{description:"Groups that belong in this menu",$ref:"#/$defs/menuGroups"},items:{description:"List of menu items that belong in this menu",type:"array",items:{$ref:"#/$defs/menuItem"},uniqueItems:!0}},required:["groups","items"]},singleColumnMenu:{description:"Menu that contains a column without a header",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"}],unevaluatedProperties:!1},multiColumnMenu:{description:"Menu that can contain multiple columns with headers",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"},{properties:{columns:{description:"Columns that belong in this menu",$ref:"#/$defs/columnsWithHeaders"}},required:["columns"]}],unevaluatedProperties:!1},menusForOneWebView:{description:"Set of menus that are associated with a single tab",type:"object",properties:{includeDefaults:{description:"Indicates whether the platform default menus should be included for this webview",type:"boolean"},topMenu:{description:"Menu that opens when you click on the top left corner of a tab",$ref:"#/$defs/multiColumnMenu"},contextMenu:{description:"Menu that opens when you right click on the main body/area of a tab",$ref:"#/$defs/singleColumnMenu"}},additionalProperties:!1}}};Object.freeze(Y);exports.AsyncVariable=ie;exports.DocumentCombinerEngine=be;exports.FIRST_SCR_BOOK_NUM=V;exports.FIRST_SCR_CHAPTER_NUM=H;exports.FIRST_SCR_VERSE_NUM=k;exports.LAST_SCR_BOOK_NUM=F;exports.PlatformEventEmitter=Ee;exports.UnsubscriberAsyncList=ye;exports.aggregateUnsubscriberAsyncs=qe;exports.aggregateUnsubscribers=Ae;exports.createSyncProxyForAsyncObject=ge;exports.debounce=le;exports.deepClone=E;exports.deepEqual=mt;exports.deserialize=Q;exports.getAllObjectFunctionNames=de;exports.getChaptersForBook=K;exports.getErrorMessage=pe;exports.groupBy=ce;exports.htmlEncode=gt;exports.indexOf=xe;exports.isSerializable=dt;exports.isString=B;exports.length=ze;exports.menuDocumentSchema=Y;exports.newGuid=ue;exports.normalize=Ue;exports.offsetBook=we;exports.offsetChapter=Oe;exports.offsetVerse=$e;exports.padEnd=Ge;exports.padStart=Je;exports.serialize=q;exports.substring=_e;exports.toArray=Be;exports.wait=J;exports.waitForDuration=me; //# sourceMappingURL=index.cjs.map diff --git a/lib/platform-bible-utils/dist/index.cjs.map b/lib/platform-bible-utils/dist/index.cjs.map index 869957e9cf..e86370236d 100644 --- a/lib/platform-bible-utils/dist/index.cjs.map +++ b/lib/platform-bible-utils/dist/index.cjs.map @@ -1 +1 @@ -{"version":3,"file":"index.cjs","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","result","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","matchIndex","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","str","menuDocumentSchema"],"mappings":"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CACL,YAAa,CACX,YACE,2FACF,KAAM,SACN,QAAS,kBACX,EACA,eAAgB,CACd,YACE,oGACF,KAAM,SACN,QAAS,yBACX,EACA,mBAAoB,CAClB,YACE,uFACF,KAAM,SACN,kBAAmB,CACjB,0BAA2B,CACzB,YAAa,qCACb,KAAM,SACN,WAAY,CACV,MAAO,CACL,YAAa,6CACb,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YACE,6EACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,8EACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,QAAS,OAAO,EAC3B,qBAAsB,EACxB,CACF,EACA,WAAY,CACV,aAAc,CACZ,YACE,qFACF,KAAM,SACR,CACF,CACF,EACA,WAAY,CACV,YACE,uJACF,KAAM,SACN,kBAAmB,CACjB,0BAA2B,CACzB,YAAa,wCACb,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,OAAQ,CACN,YACE,wEACF,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,OAAO,EAClB,qBAAsB,EACxB,EACA,CACE,WAAY,CACV,SAAU,CACR,YAAa,8DACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,WAAY,OAAO,EAC9B,qBAAsB,EACxB,CACF,CACF,CACF,EACA,qBAAsB,EACxB,EACA,SAAU,CACR,YACE,mGACF,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,GAAI,CACF,YAAa,6CACb,KAAM,wBACR,CACF,EACA,SAAU,CAAC,IAAI,CACjB,EACA,CACE,WAAY,CACV,QAAS,CACP,YAAa,mEACb,KAAM,wBACR,EACA,eAAgB,CACd,YAAa,mDACb,KAAM,QACR,EACA,cAAe,CACb,YAAa,kDACb,KAAM,QACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,WAAY,CACV,MAAO,CACL,YAAa,4DACb,KAAM,qBACR,EACA,QAAS,CACP,YACE,uFACF,KAAM,qBACR,EACA,YAAa,CACX,YACE,6GACF,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YAAa,wCACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,qGACF,KAAM,QACR,CACF,EACA,SAAU,CAAC,QAAS,QAAS,OAAO,EACpC,sBAAuB,EACzB,EACA,eAAgB,CACd,YAAa,2BACb,KAAM,SACN,WAAY,CACV,OAAQ,CACN,YAAa,kCACb,KAAM,oBACR,EACA,MAAO,CACL,YAAa,8CACb,KAAM,QACN,MAAO,CAAE,KAAM,kBAAmB,EAClC,YAAa,EACf,CACF,EACA,SAAU,CAAC,SAAU,OAAO,CAC9B,EACA,iBAAkB,CAChB,YAAa,+CACb,KAAM,SACN,MAAO,CAAC,CAAE,KAAM,yBAA0B,EAC1C,sBAAuB,EACzB,EACA,gBAAiB,CACf,YAAa,sDACb,KAAM,SACN,MAAO,CACL,CAAE,KAAM,wBAAyB,EACjC,CACE,WAAY,CACV,QAAS,CACP,YAAa,mCACb,KAAM,4BACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,sBAAuB,EACzB,EACA,mBAAoB,CAClB,YAAa,qDACb,KAAM,SACN,WAAY,CACV,gBAAiB,CACf,YACE,mFACF,KAAM,SACR,EACA,QAAS,CACP,YAAa,iEACb,KAAM,yBACR,EACA,YAAa,CACX,YAAa,sEACb,KAAM,0BACR,CACF,EACA,qBAAsB,EACxB,CACF,CACF,EAEA,OAAO,OAAOA,CAAkB","x_google_ignoreList":[7]} \ No newline at end of file +{"version":3,"file":"index.cjs","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit,\n} from 'stringz';\n\nexport const indexOf = stringzIndexOf;\nexport const substring = stringzSubstring;\nexport const length = stringzLength;\nexport const toArray = stringzToArray;\n\nexport const padStart = (string: string, targetLength: number, padString?: string) => {\n limit(string, targetLength, padString, 'left');\n};\n\nexport const padEnd = (string: string, targetLength: number, padString?: string) => {\n limit(string, targetLength, padString, 'right');\n};\n\nexport const normalize = (string: string, form: 'NFC' | 'NFD' | 'none' = 'NFC') => {\n const upperCaseForm = form.toUpperCase();\n if(upperCaseForm==='NONE')\n {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","stringzIndexOf","stringzSubstring","stringzLength","stringzToArray","padStart","string","targetLength","padEnd","normalize","form","upperCaseForm","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","result","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","matchIndex","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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CX,YACE,2FACF,KAAM,SACN,QAAS,kBACX,EACA,eAAgB,CACd,YACE,oGACF,KAAM,SACN,QAAS,yBACX,EACA,mBAAoB,CAClB,YACE,uFACF,KAAM,SACN,kBAAmB,CACjB,0BAA2B,CACzB,YAAa,qCACb,KAAM,SACN,WAAY,CACV,MAAO,CACL,YAAa,6CACb,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YACE,6EACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,8EACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,QAAS,OAAO,EAC3B,qBAAsB,EACxB,CACF,EACA,WAAY,CACV,aAAc,CACZ,YACE,qFACF,KAAM,SACR,CACF,CACF,EACA,WAAY,CACV,YACE,uJACF,KAAM,SACN,kBAAmB,CACjB,0BAA2B,CACzB,YAAa,wCACb,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,OAAQ,CACN,YACE,wEACF,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,OAAO,EAClB,qBAAsB,EACxB,EACA,CACE,WAAY,CACV,SAAU,CACR,YAAa,8DACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,WAAY,OAAO,EAC9B,qBAAsB,EACxB,CACF,CACF,CACF,EACA,qBAAsB,EACxB,EACA,SAAU,CACR,YACE,mGACF,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,GAAI,CACF,YAAa,6CACb,KAAM,wBACR,CACF,EACA,SAAU,CAAC,IAAI,CACjB,EACA,CACE,WAAY,CACV,QAAS,CACP,YAAa,mEACb,KAAM,wBACR,EACA,eAAgB,CACd,YAAa,mDACb,KAAM,QACR,EACA,cAAe,CACb,YAAa,kDACb,KAAM,QACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,WAAY,CACV,MAAO,CACL,YAAa,4DACb,KAAM,qBACR,EACA,QAAS,CACP,YACE,uFACF,KAAM,qBACR,EACA,YAAa,CACX,YACE,6GACF,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YAAa,wCACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,qGACF,KAAM,QACR,CACF,EACA,SAAU,CAAC,QAAS,QAAS,OAAO,EACpC,sBAAuB,EACzB,EACA,eAAgB,CACd,YAAa,2BACb,KAAM,SACN,WAAY,CACV,OAAQ,CACN,YAAa,kCACb,KAAM,oBACR,EACA,MAAO,CACL,YAAa,8CACb,KAAM,QACN,MAAO,CAAE,KAAM,kBAAmB,EAClC,YAAa,EACf,CACF,EACA,SAAU,CAAC,SAAU,OAAO,CAC9B,EACA,iBAAkB,CAChB,YAAa,+CACb,KAAM,SACN,MAAO,CAAC,CAAE,KAAM,yBAA0B,EAC1C,sBAAuB,EACzB,EACA,gBAAiB,CACf,YAAa,sDACb,KAAM,SACN,MAAO,CACL,CAAE,KAAM,wBAAyB,EACjC,CACE,WAAY,CACV,QAAS,CACP,YAAa,mCACb,KAAM,4BACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,sBAAuB,EACzB,EACA,mBAAoB,CAClB,YAAa,qDACb,KAAM,SACN,WAAY,CACV,gBAAiB,CACf,YACE,mFACF,KAAM,SACR,EACA,QAAS,CACP,YAAa,iEACb,KAAM,yBACR,EACA,YAAa,CACX,YAAa,sEACb,KAAM,0BACR,CACF,EACA,qBAAsB,EACxB,CACF,CACF,EAEA,OAAO,OAAOA,CAAkB","x_google_ignoreList":[7,8,10]} \ No newline at end of file diff --git a/lib/platform-bible-utils/dist/index.d.ts b/lib/platform-bible-utils/dist/index.d.ts index d056f5ab1b..09c36b173b 100644 --- a/lib/platform-bible-utils/dist/index.d.ts +++ b/lib/platform-bible-utils/dist/index.d.ts @@ -1,5 +1,7 @@ // Generated by dts-bundle-generator v9.2.4 +import { indexOf as stringzIndexOf, length as stringzLength, substring as stringzSubstring, toArray as stringzToArray } from 'stringz'; + /** This class provides a convenient way for one task to wait on a variable that another task sets. */ export declare class AsyncVariable { private readonly variableName; @@ -372,6 +374,13 @@ export declare function getAllObjectFunctionNames(obj: { * @returns A synchronous proxy for the asynchronous object. */ export declare function createSyncProxyForAsyncObject(getObject: (args?: unknown[]) => Promise, objectToProxy?: Partial): T; +export declare const indexOf: typeof stringzIndexOf; +export declare const substring: typeof stringzSubstring; +declare const length$1: typeof stringzLength; +export declare const toArray: typeof stringzToArray; +export declare const padStart: (string: string, targetLength: number, padString?: string) => void; +export declare const padEnd: (string: string, targetLength: number, padString?: string) => void; +export declare const normalize: (string: string, form?: "NFC" | "NFD" | "none") => string; /** * Check that two objects are deeply equal, comparing members of each object and such * @@ -819,4 +828,6 @@ export declare const menuDocumentSchema: { }; }; -export {}; +export { + length$1 as length, +}; diff --git a/lib/platform-bible-utils/dist/index.js b/lib/platform-bible-utils/dist/index.js index 50b6f3ce39..ed94d687eb 100644 --- a/lib/platform-bible-utils/dist/index.js +++ b/lib/platform-bible-utils/dist/index.js @@ -1,7 +1,7 @@ -var x = Object.defineProperty; -var J = (t, e, r) => e in t ? x(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r; -var p = (t, e, r) => (J(t, typeof e != "symbol" ? e + "" : e, r), r); -class Oe { +var Z = Object.defineProperty; +var X = (t, e, r) => e in t ? Z(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r; +var p = (t, e, r) => (X(t, typeof e != "symbol" ? e + "" : e, r), r); +class Ke { /** * Creates an instance of the class * @@ -15,8 +15,8 @@ class Oe { p(this, "promiseToValue"); p(this, "resolver"); p(this, "rejecter"); - this.variableName = e, this.promiseToValue = new Promise((s, a) => { - this.resolver = s, this.rejecter = a; + this.variableName = e, this.promiseToValue = new Promise((s, n) => { + this.resolver = s, this.rejecter = n; }), r > 0 && setTimeout(() => { this.rejecter && (this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`), this.complete()); }, r), Object.seal(this); @@ -75,7 +75,7 @@ class Oe { this.resolver = void 0, this.rejecter = void 0, Object.freeze(this); } } -function $e() { +function Le() { return "00-0-4-1-000".replace( /[^-]/g, (t) => ( @@ -85,36 +85,36 @@ function $e() { ) ); } -function z(t) { +function Q(t) { return typeof t == "string" || t instanceof String; } -function y(t) { +function E(t) { return JSON.parse(JSON.stringify(t)); } -function qe(t, e = 300) { - if (z(t)) +function We(t, e = 300) { + if (Q(t)) throw new Error("Tried to debounce a string! Could be XSS"); let r; return (...s) => { clearTimeout(r), r = setTimeout(() => t(...s), e); }; } -function Ae(t, e, r) { +function Ze(t, e, r) { const s = /* @__PURE__ */ new Map(); - return t.forEach((a) => { - const i = e(a), n = s.get(i), u = r ? r(a, i) : a; - n ? n.push(u) : s.set(i, [u]); + return t.forEach((n) => { + const a = e(n), o = s.get(a), i = r ? r(n, a) : n; + o ? o.push(i) : s.set(a, [i]); }), s; } -function G(t) { +function Y(t) { return typeof t == "object" && // We're potentially dealing with objects we didn't create, so they might contain `null` // eslint-disable-next-line no-null/no-null t !== null && "message" in t && // Type assert `error` to check it's `message`. // eslint-disable-next-line no-type-assertion/no-type-assertion typeof t.message == "string"; } -function B(t) { - if (G(t)) +function ee(t) { + if (Y(t)) return t; try { return new Error(JSON.stringify(t)); @@ -122,45 +122,45 @@ function B(t) { return new Error(String(t)); } } -function je(t) { - return B(t).message; +function Xe(t) { + return ee(t).message; } -function V(t) { +function te(t) { return new Promise((e) => setTimeout(e, t)); } -function Se(t, e) { - const r = V(e).then(() => { +function Qe(t, e) { + const r = te(e).then(() => { }); return Promise.any([r, t()]); } -function Pe(t, e = "obj") { +function Ye(t, e = "obj") { const r = /* @__PURE__ */ new Set(); - Object.getOwnPropertyNames(t).forEach((a) => { + Object.getOwnPropertyNames(t).forEach((n) => { try { - typeof t[a] == "function" && r.add(a); - } catch (i) { - console.debug(`Skipping ${a} on ${e} due to error: ${i}`); + typeof t[n] == "function" && r.add(n); + } catch (a) { + console.debug(`Skipping ${n} on ${e} due to error: ${a}`); } }); let s = Object.getPrototypeOf(t); for (; s && Object.getPrototypeOf(s); ) - Object.getOwnPropertyNames(s).forEach((a) => { + Object.getOwnPropertyNames(s).forEach((n) => { try { - typeof t[a] == "function" && r.add(a); - } catch (i) { - console.debug(`Skipping ${a} on ${e}'s prototype due to error: ${i}`); + typeof t[n] == "function" && r.add(n); + } catch (a) { + console.debug(`Skipping ${n} on ${e}'s prototype due to error: ${a}`); } }), s = Object.getPrototypeOf(s); return r; } -function Me(t, e = {}) { +function et(t, e = {}) { return new Proxy(e, { get(r, s) { - return s in r ? r[s] : async (...a) => (await t())[s](...a); + return s in r ? r[s] : async (...n) => (await t())[s](...n); } }); } -class Ce { +class tt { /** * Create a DocumentCombinerEngine instance * @@ -181,7 +181,7 @@ class Ce { * @returns Recalculated output document given the new starting state and existing other documents */ updateBaseDocument(e) { - return this.validateStartingDocument(e), this.baseDocument = this.options.copyDocuments ? y(e) : e, this.rebuild(); + return this.validateStartingDocument(e), this.baseDocument = this.options.copyDocuments ? E(e) : e, this.rebuild(); } /** * Add or update one of the contribution documents for the composition process @@ -193,12 +193,12 @@ class Ce { */ addOrUpdateContribution(e, r) { this.validateContribution(e, r); - const s = this.contributions.get(e), a = this.options.copyDocuments && r ? y(r) : r; - this.contributions.set(e, a); + const s = this.contributions.get(e), n = this.options.copyDocuments && r ? E(r) : r; + this.contributions.set(e, n); try { return this.rebuild(); - } catch (i) { - throw s ? this.contributions.set(e, s) : this.contributions.delete(e), new Error(`Error when setting the document named ${e}: ${i}`); + } catch (a) { + throw s ? this.contributions.set(e, s) : this.contributions.delete(e), new Error(`Error when setting the document named ${e}: ${a}`); } } /** @@ -226,12 +226,12 @@ class Ce { */ rebuild() { if (this.contributions.size === 0) { - let r = y(this.baseDocument); + let r = E(this.baseDocument); return r = this.transformFinalOutput(r), this.validateOutput(r), this.latestOutput = r, this.latestOutput; } let e = this.baseDocument; return this.contributions.forEach((r) => { - e = C( + e = _( e, r, this.options.ignoreDuplicateProperties @@ -239,40 +239,40 @@ class Ce { }), e = this.transformFinalOutput(e), this.validateOutput(e), this.latestOutput = e, this.latestOutput; } } -function H(...t) { +function re(...t) { let e = !0; return t.forEach((r) => { (!r || typeof r != "object" || Array.isArray(r)) && (e = !1); }), e; } -function U(...t) { +function se(...t) { let e = !0; return t.forEach((r) => { (!r || typeof r != "object" || !Array.isArray(r)) && (e = !1); }), e; } -function C(t, e, r) { - const s = y(t); - return e && Object.keys(e).forEach((a) => { - if (Object.hasOwn(t, a)) { - if (H(t[a], e[a])) - s[a] = C( +function _(t, e, r) { + const s = E(t); + return e && Object.keys(e).forEach((n) => { + if (Object.hasOwn(t, n)) { + if (re(t[n], e[n])) + s[n] = _( // We know these are objects from the `if` check /* eslint-disable no-type-assertion/no-type-assertion */ - t[a], - e[a], + t[n], + e[n], r /* eslint-enable no-type-assertion/no-type-assertion */ ); - else if (U(t[a], e[a])) - s[a] = s[a].concat(e[a]); + else if (se(t[n], e[n])) + s[n] = s[n].concat(e[n]); else if (!r) - throw new Error(`Cannot merge objects: key "${a}" already exists in the target object`); + throw new Error(`Cannot merge objects: key "${n}" already exists in the target object`); } else - s[a] = e[a]; + s[n] = e[n]; }), s; } -class Te { +class rt { constructor(e = "Anonymous") { p(this, "unsubscribers", /* @__PURE__ */ new Set()); this.name = e; @@ -294,10 +294,10 @@ class Te { */ async runAllUnsubscribers() { const e = [...this.unsubscribers].map((s) => s()), r = await Promise.all(e); - return this.unsubscribers.clear(), r.every((s, a) => (s || console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${a} failed!`), s)); + return this.unsubscribers.clear(), r.every((s, n) => (s || console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${n} failed!`), s)); } } -class Ie { +class st { constructor() { /** * Subscribes a function to run when this event is emitted. @@ -366,7 +366,7 @@ class Ie { return this.assertNotDisposed(), this.isDisposed = !0, this.subscriptions = void 0, this.lazyEvent = void 0, Promise.resolve(!0); } } -const T = [ +const G = [ { shortName: "ERR", fullNames: ["ERROR"], chapters: -1 }, { shortName: "GEN", fullNames: ["Genesis"], chapters: 50 }, { shortName: "EXO", fullNames: ["Exodus"], chapters: 40 }, @@ -434,56 +434,145 @@ const T = [ { shortName: "3JN", fullNames: ["3 John"], chapters: 1 }, { shortName: "JUD", fullNames: ["Jude"], chapters: 1 }, { shortName: "REV", fullNames: ["Revelation"], chapters: 22 } -], K = 1, W = T.length - 1, _ = 1, L = 1, k = (t) => { +], ne = 1, ae = G.length - 1, oe = 1, ie = 1, ue = (t) => { var e; - return ((e = T[t]) == null ? void 0 : e.chapters) ?? -1; -}, Re = (t, e) => ({ - bookNum: Math.max(K, Math.min(t.bookNum + e, W)), + return ((e = G[t]) == null ? void 0 : e.chapters) ?? -1; +}, nt = (t, e) => ({ + bookNum: Math.max(ne, Math.min(t.bookNum + e, ae)), chapterNum: 1, verseNum: 1 -}), De = (t, e) => ({ +}), at = (t, e) => ({ ...t, chapterNum: Math.min( - Math.max(_, t.chapterNum + e), - k(t.bookNum) + Math.max(oe, t.chapterNum + e), + ue(t.bookNum) ), verseNum: 1 -}), xe = (t, e) => ({ +}), ot = (t, e) => ({ ...t, - verseNum: Math.max(L, t.verseNum + e) -}), Je = (t) => (...e) => t.map((s) => s(...e)).every((s) => s), ze = (t) => async (...e) => { + verseNum: Math.max(ie, t.verseNum + e) +}), it = (t) => (...e) => t.map((s) => s(...e)).every((s) => s), ut = (t) => async (...e) => { const r = t.map(async (s) => s(...e)); return (await Promise.all(r)).every((s) => s); }; -var F = Object.getOwnPropertyNames, Z = Object.getOwnPropertySymbols, X = Object.prototype.hasOwnProperty; -function w(t, e) { - return function(s, a, i) { - return t(s, a, i) && e(s, a, i); +var M = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}, b = {}, le = () => { + const t = "\\ud800-\\udfff", e = "\\u0300-\\u036f", r = "\\ufe20-\\ufe2f", s = "\\u20d0-\\u20ff", n = "\\u1ab0-\\u1aff", a = "\\u1dc0-\\u1dff", o = e + r + s + n + a, i = "\\ufe0e\\ufe0f", c = "\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93", h = `[${t}]`, u = `[${o}]`, l = "\\ud83c[\\udffb-\\udfff]", f = `(?:${u}|${l})`, d = `[^${t}]`, m = "(?:\\uD83C[\\uDDE6-\\uDDFF]){2}", v = "[\\ud800-\\udbff][\\udc00-\\udfff]", $ = "\\u200d", F = "(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)", k = `[${c}]`, j = `${f}?`, C = `[${i}]?`, K = `(?:${$}(?:${[d, m, v].join("|")})${C + j})*`, L = C + j + K, W = `(?:${[`${d}${u}?`, u, m, v, h, k].join("|")})`; + return new RegExp(`${F}|${l}(?=${l})|${W + L}`, "g"); +}, ce = M && M.__importDefault || function(t) { + return t && t.__esModule ? t : { default: t }; +}; +Object.defineProperty(b, "__esModule", { value: !0 }); +var O = ce(le); +function A(t) { + if (typeof t != "string") + throw new Error("A string is expected as input"); + return t.match(O.default()) || []; +} +var fe = b.toArray = A; +function q(t) { + if (typeof t != "string") + throw new Error("Input must be a string"); + var e = t.match(O.default()); + return e === null ? 0 : e.length; +} +var he = b.length = q; +function B(t, e, r) { + if (e === void 0 && (e = 0), typeof t != "string") + throw new Error("Input must be a string"); + (typeof e != "number" || e < 0) && (e = 0), typeof r == "number" && r < 0 && (r = 0); + var s = t.match(O.default()); + return s ? s.slice(e, r).join("") : ""; +} +var pe = b.substring = B; +function me(t, e, r) { + if (e === void 0 && (e = 0), typeof t != "string") + throw new Error("Input must be a string"); + var s = q(t); + if (typeof e != "number" && (e = parseInt(e, 10)), e >= s) + return ""; + e < 0 && (e += s); + var n; + typeof r > "u" ? n = s : (typeof r != "number" && (r = parseInt(r, 10)), n = r >= 0 ? r + e : e); + var a = t.match(O.default()); + return a ? a.slice(e, n).join("") : ""; +} +b.substr = me; +function de(t, e, r, s) { + if (e === void 0 && (e = 16), r === void 0 && (r = "#"), s === void 0 && (s = "right"), typeof t != "string" || typeof e != "number") + throw new Error("Invalid arguments specified"); + if (["left", "right"].indexOf(s) === -1) + throw new Error("Pad position should be either left or right"); + typeof r != "string" && (r = String(r)); + var n = q(t); + if (n > e) + return B(t, 0, e); + if (n < e) { + var a = r.repeat(e - n); + return s === "left" ? a + t : t + a; + } + return t; +} +var V = b.limit = de; +function ge(t, e, r) { + if (r === void 0 && (r = 0), typeof t != "string") + throw new Error("Input must be a string"); + if (t === "") + return e === "" ? 0 : -1; + r = Number(r), r = isNaN(r) ? 0 : r, e = String(e); + var s = A(t); + if (r >= s.length) + return e === "" ? s.length : -1; + if (e === "") + return r; + var n = A(e), a = !1, o; + for (o = r; o < s.length; o += 1) { + for (var i = 0; i < n.length && n[i] === s[o + i]; ) + i += 1; + if (i === n.length && n[i - 1] === s[o + i - 1]) { + a = !0; + break; + } + } + return a ? o : -1; +} +var be = b.indexOf = ge; +const lt = be, ct = pe, ft = he, ht = fe, pt = (t, e, r) => { + V(t, e, r, "left"); +}, mt = (t, e, r) => { + V(t, e, r, "right"); +}, dt = (t, e = "NFC") => { + const r = e.toUpperCase(); + return r === "NONE" ? t : t.normalize(r); +}; +var Ne = Object.getOwnPropertyNames, ve = Object.getOwnPropertySymbols, ye = Object.prototype.hasOwnProperty; +function P(t, e) { + return function(s, n, a) { + return t(s, n, a) && e(s, n, a); }; } -function v(t) { - return function(r, s, a) { +function w(t) { + return function(r, s, n) { if (!r || !s || typeof r != "object" || typeof s != "object") - return t(r, s, a); - var i = a.cache, n = i.get(r), u = i.get(s); - if (n && u) - return n === s && u === r; - i.set(r, s), i.set(s, r); - var c = t(r, s, a); - return i.delete(r), i.delete(s), c; + return t(r, s, n); + var a = n.cache, o = a.get(r), i = a.get(s); + if (o && i) + return o === s && i === r; + a.set(r, s), a.set(s, r); + var c = t(r, s, n); + return a.delete(r), a.delete(s), c; }; } -function O(t) { - return F(t).concat(Z(t)); +function S(t) { + return Ne(t).concat(ve(t)); } -var I = Object.hasOwn || function(t, e) { - return X.call(t, e); +var H = Object.hasOwn || function(t, e) { + return ye.call(t, e); }; -function b(t, e) { +function N(t, e) { return t || e ? t === e : t === e || t !== t && e !== e; } -var R = "_owner", $ = Object.getOwnPropertyDescriptor, q = Object.keys; -function Q(t, e, r) { +var U = "_owner", T = Object.getOwnPropertyDescriptor, D = Object.keys; +function we(t, e, r) { var s = t.length; if (e.length !== s) return !1; @@ -492,59 +581,59 @@ function Q(t, e, r) { return !1; return !0; } -function Y(t, e) { - return b(t.getTime(), e.getTime()); +function Ee(t, e) { + return N(t.getTime(), e.getTime()); } -function A(t, e, r) { +function R(t, e, r) { if (t.size !== e.size) return !1; - for (var s = {}, a = t.entries(), i = 0, n, u; (n = a.next()) && !n.done; ) { - for (var c = e.entries(), f = !1, o = 0; (u = c.next()) && !u.done; ) { - var l = n.value, h = l[0], d = l[1], m = u.value, E = m[0], D = m[1]; - !f && !s[o] && (f = r.equals(h, E, i, o, t, e, r) && r.equals(d, D, h, E, t, e, r)) && (s[o] = !0), o++; + for (var s = {}, n = t.entries(), a = 0, o, i; (o = n.next()) && !o.done; ) { + for (var c = e.entries(), h = !1, u = 0; (i = c.next()) && !i.done; ) { + var l = o.value, f = l[0], d = l[1], m = i.value, v = m[0], $ = m[1]; + !h && !s[u] && (h = r.equals(f, v, a, u, t, e, r) && r.equals(d, $, f, v, t, e, r)) && (s[u] = !0), u++; } - if (!f) + if (!h) return !1; - i++; + a++; } return !0; } -function ee(t, e, r) { - var s = q(t), a = s.length; - if (q(e).length !== a) +function Oe(t, e, r) { + var s = D(t), n = s.length; + if (D(e).length !== n) return !1; - for (var i; a-- > 0; ) - if (i = s[a], i === R && (t.$$typeof || e.$$typeof) && t.$$typeof !== e.$$typeof || !I(e, i) || !r.equals(t[i], e[i], i, i, t, e, r)) + for (var a; n-- > 0; ) + if (a = s[n], a === U && (t.$$typeof || e.$$typeof) && t.$$typeof !== e.$$typeof || !H(e, a) || !r.equals(t[a], e[a], a, a, t, e, r)) return !1; return !0; } -function g(t, e, r) { - var s = O(t), a = s.length; - if (O(e).length !== a) +function y(t, e, r) { + var s = S(t), n = s.length; + if (S(e).length !== n) return !1; - for (var i, n, u; a-- > 0; ) - if (i = s[a], i === R && (t.$$typeof || e.$$typeof) && t.$$typeof !== e.$$typeof || !I(e, i) || !r.equals(t[i], e[i], i, i, t, e, r) || (n = $(t, i), u = $(e, i), (n || u) && (!n || !u || n.configurable !== u.configurable || n.enumerable !== u.enumerable || n.writable !== u.writable))) + for (var a, o, i; n-- > 0; ) + if (a = s[n], a === U && (t.$$typeof || e.$$typeof) && t.$$typeof !== e.$$typeof || !H(e, a) || !r.equals(t[a], e[a], a, a, t, e, r) || (o = T(t, a), i = T(e, a), (o || i) && (!o || !i || o.configurable !== i.configurable || o.enumerable !== i.enumerable || o.writable !== i.writable))) return !1; return !0; } -function te(t, e) { - return b(t.valueOf(), e.valueOf()); +function $e(t, e) { + return N(t.valueOf(), e.valueOf()); } -function re(t, e) { +function Ae(t, e) { return t.source === e.source && t.flags === e.flags; } -function j(t, e, r) { +function x(t, e, r) { if (t.size !== e.size) return !1; - for (var s = {}, a = t.values(), i, n; (i = a.next()) && !i.done; ) { - for (var u = e.values(), c = !1, f = 0; (n = u.next()) && !n.done; ) - !c && !s[f] && (c = r.equals(i.value, n.value, i.value, n.value, t, e, r)) && (s[f] = !0), f++; + for (var s = {}, n = t.values(), a, o; (a = n.next()) && !a.done; ) { + for (var i = e.values(), c = !1, h = 0; (o = i.next()) && !o.done; ) + !c && !s[h] && (c = r.equals(a.value, o.value, a.value, o.value, t, e, r)) && (s[h] = !0), h++; if (!c) return !1; } return !0; } -function se(t, e) { +function qe(t, e) { var r = t.length; if (e.length !== r) return !1; @@ -553,157 +642,157 @@ function se(t, e) { return !1; return !0; } -var ae = "[object Arguments]", ie = "[object Boolean]", ne = "[object Date]", oe = "[object Map]", ue = "[object Number]", le = "[object Object]", ce = "[object RegExp]", he = "[object Set]", fe = "[object String]", pe = Array.isArray, S = typeof ArrayBuffer == "function" && ArrayBuffer.isView ? ArrayBuffer.isView : null, P = Object.assign, me = Object.prototype.toString.call.bind(Object.prototype.toString); -function de(t) { - var e = t.areArraysEqual, r = t.areDatesEqual, s = t.areMapsEqual, a = t.areObjectsEqual, i = t.arePrimitiveWrappersEqual, n = t.areRegExpsEqual, u = t.areSetsEqual, c = t.areTypedArraysEqual; - return function(o, l, h) { - if (o === l) +var je = "[object Arguments]", Ce = "[object Boolean]", Me = "[object Date]", Pe = "[object Map]", Se = "[object Number]", Te = "[object Object]", De = "[object RegExp]", Re = "[object Set]", xe = "[object String]", Ie = Array.isArray, I = typeof ArrayBuffer == "function" && ArrayBuffer.isView ? ArrayBuffer.isView : null, z = Object.assign, ze = Object.prototype.toString.call.bind(Object.prototype.toString); +function Je(t) { + var e = t.areArraysEqual, r = t.areDatesEqual, s = t.areMapsEqual, n = t.areObjectsEqual, a = t.arePrimitiveWrappersEqual, o = t.areRegExpsEqual, i = t.areSetsEqual, c = t.areTypedArraysEqual; + return function(u, l, f) { + if (u === l) return !0; - if (o == null || l == null || typeof o != "object" || typeof l != "object") - return o !== o && l !== l; - var d = o.constructor; + if (u == null || l == null || typeof u != "object" || typeof l != "object") + return u !== u && l !== l; + var d = u.constructor; if (d !== l.constructor) return !1; if (d === Object) - return a(o, l, h); - if (pe(o)) - return e(o, l, h); - if (S != null && S(o)) - return c(o, l, h); + return n(u, l, f); + if (Ie(u)) + return e(u, l, f); + if (I != null && I(u)) + return c(u, l, f); if (d === Date) - return r(o, l, h); + return r(u, l, f); if (d === RegExp) - return n(o, l, h); + return o(u, l, f); if (d === Map) - return s(o, l, h); + return s(u, l, f); if (d === Set) - return u(o, l, h); - var m = me(o); - return m === ne ? r(o, l, h) : m === ce ? n(o, l, h) : m === oe ? s(o, l, h) : m === he ? u(o, l, h) : m === le ? typeof o.then != "function" && typeof l.then != "function" && a(o, l, h) : m === ae ? a(o, l, h) : m === ie || m === ue || m === fe ? i(o, l, h) : !1; + return i(u, l, f); + var m = ze(u); + return m === Me ? r(u, l, f) : m === De ? o(u, l, f) : m === Pe ? s(u, l, f) : m === Re ? i(u, l, f) : m === Te ? typeof u.then != "function" && typeof l.then != "function" && n(u, l, f) : m === je ? n(u, l, f) : m === Ce || m === Se || m === xe ? a(u, l, f) : !1; }; } -function Ne(t) { - var e = t.circular, r = t.createCustomConfig, s = t.strict, a = { - areArraysEqual: s ? g : Q, - areDatesEqual: Y, - areMapsEqual: s ? w(A, g) : A, - areObjectsEqual: s ? g : ee, - arePrimitiveWrappersEqual: te, - areRegExpsEqual: re, - areSetsEqual: s ? w(j, g) : j, - areTypedArraysEqual: s ? g : se +function _e(t) { + var e = t.circular, r = t.createCustomConfig, s = t.strict, n = { + areArraysEqual: s ? y : we, + areDatesEqual: Ee, + areMapsEqual: s ? P(R, y) : R, + areObjectsEqual: s ? y : Oe, + arePrimitiveWrappersEqual: $e, + areRegExpsEqual: Ae, + areSetsEqual: s ? P(x, y) : x, + areTypedArraysEqual: s ? y : qe }; - if (r && (a = P({}, a, r(a))), e) { - var i = v(a.areArraysEqual), n = v(a.areMapsEqual), u = v(a.areObjectsEqual), c = v(a.areSetsEqual); - a = P({}, a, { - areArraysEqual: i, - areMapsEqual: n, - areObjectsEqual: u, + if (r && (n = z({}, n, r(n))), e) { + var a = w(n.areArraysEqual), o = w(n.areMapsEqual), i = w(n.areObjectsEqual), c = w(n.areSetsEqual); + n = z({}, n, { + areArraysEqual: a, + areMapsEqual: o, + areObjectsEqual: i, areSetsEqual: c }); } - return a; + return n; } -function be(t) { - return function(e, r, s, a, i, n, u) { - return t(e, r, u); +function Ge(t) { + return function(e, r, s, n, a, o, i) { + return t(e, r, i); }; } -function ge(t) { - var e = t.circular, r = t.comparator, s = t.createState, a = t.equals, i = t.strict; +function Be(t) { + var e = t.circular, r = t.comparator, s = t.createState, n = t.equals, a = t.strict; if (s) - return function(c, f) { - var o = s(), l = o.cache, h = l === void 0 ? e ? /* @__PURE__ */ new WeakMap() : void 0 : l, d = o.meta; - return r(c, f, { - cache: h, - equals: a, + return function(c, h) { + var u = s(), l = u.cache, f = l === void 0 ? e ? /* @__PURE__ */ new WeakMap() : void 0 : l, d = u.meta; + return r(c, h, { + cache: f, + equals: n, meta: d, - strict: i + strict: a }); }; if (e) - return function(c, f) { - return r(c, f, { + return function(c, h) { + return r(c, h, { cache: /* @__PURE__ */ new WeakMap(), - equals: a, + equals: n, meta: void 0, - strict: i + strict: a }); }; - var n = { + var o = { cache: void 0, - equals: a, + equals: n, meta: void 0, - strict: i + strict: a }; - return function(c, f) { - return r(c, f, n); + return function(c, h) { + return r(c, h, o); }; } -var ve = N(); -N({ strict: !0 }); -N({ circular: !0 }); -N({ +var Ve = g(); +g({ strict: !0 }); +g({ circular: !0 }); +g({ circular: !0, strict: !0 }); -N({ +g({ createInternalComparator: function() { - return b; + return N; } }); -N({ +g({ strict: !0, createInternalComparator: function() { - return b; + return N; } }); -N({ +g({ circular: !0, createInternalComparator: function() { - return b; + return N; } }); -N({ +g({ circular: !0, createInternalComparator: function() { - return b; + return N; }, strict: !0 }); -function N(t) { +function g(t) { t === void 0 && (t = {}); - var e = t.circular, r = e === void 0 ? !1 : e, s = t.createInternalComparator, a = t.createState, i = t.strict, n = i === void 0 ? !1 : i, u = Ne(t), c = de(u), f = s ? s(c) : be(c); - return ge({ circular: r, comparator: c, createState: a, equals: f, strict: n }); + var e = t.circular, r = e === void 0 ? !1 : e, s = t.createInternalComparator, n = t.createState, a = t.strict, o = a === void 0 ? !1 : a, i = _e(t), c = Je(i), h = s ? s(c) : Ge(c); + return Be({ circular: r, comparator: c, createState: n, equals: h, strict: o }); } -function Ge(t, e) { - return ve(t, e); +function gt(t, e) { + return Ve(t, e); } -function M(t, e, r) { - return JSON.stringify(t, (a, i) => { - let n = i; - return e && (n = e(a, n)), n === void 0 && (n = null), n; +function J(t, e, r) { + return JSON.stringify(t, (n, a) => { + let o = a; + return e && (o = e(n, o)), o === void 0 && (o = null), o; }, r); } -function ye(t, e) { - function r(a) { - return Object.keys(a).forEach((i) => { - a[i] === null ? a[i] = void 0 : typeof a[i] == "object" && (a[i] = r(a[i])); - }), a; +function He(t, e) { + function r(n) { + return Object.keys(n).forEach((a) => { + n[a] === null ? n[a] = void 0 : typeof n[a] == "object" && (n[a] = r(n[a])); + }), n; } const s = JSON.parse(t, e); if (s !== null) return typeof s == "object" ? r(s) : s; } -function Be(t) { +function bt(t) { try { - const e = M(t); - return e === M(ye(e)); + const e = J(t); + return e === J(He(e)); } catch { return !1; } } -const Ve = (t) => t.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'").replace(/\//g, "/"), Ee = { +const Nt = (t) => t.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'").replace(/\//g, "/"), Ue = { title: "Platform.Bible menus", type: "object", properties: { @@ -949,37 +1038,44 @@ const Ve = (t) => t.replace(/&/g, "&").replace(//g, " } } }; -Object.freeze(Ee); +Object.freeze(Ue); export { - Oe as AsyncVariable, - Ce as DocumentCombinerEngine, - K as FIRST_SCR_BOOK_NUM, - _ as FIRST_SCR_CHAPTER_NUM, - L as FIRST_SCR_VERSE_NUM, - W as LAST_SCR_BOOK_NUM, - Ie as PlatformEventEmitter, - Te as UnsubscriberAsyncList, - ze as aggregateUnsubscriberAsyncs, - Je as aggregateUnsubscribers, - Me as createSyncProxyForAsyncObject, - qe as debounce, - y as deepClone, - Ge as deepEqual, - ye as deserialize, - Pe as getAllObjectFunctionNames, - k as getChaptersForBook, - je as getErrorMessage, - Ae as groupBy, - Ve as htmlEncode, - Be as isSerializable, - z as isString, - Ee as menuDocumentSchema, - $e as newGuid, - Re as offsetBook, - De as offsetChapter, - xe as offsetVerse, - M as serialize, - V as wait, - Se as waitForDuration + Ke as AsyncVariable, + tt as DocumentCombinerEngine, + ne as FIRST_SCR_BOOK_NUM, + oe as FIRST_SCR_CHAPTER_NUM, + ie as FIRST_SCR_VERSE_NUM, + ae as LAST_SCR_BOOK_NUM, + st as PlatformEventEmitter, + rt as UnsubscriberAsyncList, + ut as aggregateUnsubscriberAsyncs, + it as aggregateUnsubscribers, + et as createSyncProxyForAsyncObject, + We as debounce, + E as deepClone, + gt as deepEqual, + He as deserialize, + Ye as getAllObjectFunctionNames, + ue as getChaptersForBook, + Xe as getErrorMessage, + Ze as groupBy, + Nt as htmlEncode, + lt as indexOf, + bt as isSerializable, + Q as isString, + ft as length, + Ue as menuDocumentSchema, + Le as newGuid, + dt as normalize, + nt as offsetBook, + at as offsetChapter, + ot as offsetVerse, + mt as padEnd, + pt as padStart, + J as serialize, + ct as substring, + ht as toArray, + te as wait, + Qe as waitForDuration }; //# sourceMappingURL=index.js.map diff --git a/lib/platform-bible-utils/dist/index.js.map b/lib/platform-bible-utils/dist/index.js.map index 53994c5004..e1d138faf0 100644 --- a/lib/platform-bible-utils/dist/index.js.map +++ b/lib/platform-bible-utils/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","result","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","matchIndex","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","str","menuDocumentSchema"],"mappings":";;;AACA,MAAqBA,GAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcpC,YAAYC,GAAsBC,IAAqC,KAAO;AAb7D,IAAAC,EAAA;AACA,IAAAA,EAAA;AACT,IAAAA,EAAA;AACA,IAAAA,EAAA;AAWN,SAAK,eAAeF,GACpB,KAAK,iBAAiB,IAAI,QAAW,CAACG,GAASC,MAAW;AACxD,WAAK,WAAWD,GAChB,KAAK,WAAWC;AAAA,IAAA,CACjB,GACGH,IAA6B,KAC/B,WAAW,MAAM;AACf,MAAI,KAAK,aACP,KAAK,SAAS,oCAAoC,KAAK,YAAY,YAAY,GAC/E,KAAK,SAAS;AAAA,OAEfA,CAA0B,GAE/B,OAAO,KAAK,IAAI;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,UAAsB;AACxB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,aAAsB;AACjB,WAAA,OAAO,SAAS,IAAI;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,eAAeI,GAAUC,IAAiC,IAAa;AACrE,QAAI,KAAK;AACP,cAAQ,MAAM,GAAG,KAAK,YAAY,wBAAwB,GAC1D,KAAK,SAASD,CAAK,GACnB,KAAK,SAAS;AAAA,SACT;AACD,UAAAC;AAAuB,cAAM,MAAM,GAAG,KAAK,YAAY,sBAAsB;AACjF,cAAQ,MAAM,qCAAqC,KAAK,YAAY,EAAE;AAAA,IACxE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,iBAAiBC,GAAgBD,IAAiC,IAAa;AAC7E,QAAI,KAAK;AACP,cAAQ,MAAM,GAAG,KAAK,YAAY,wBAAwB,GAC1D,KAAK,SAASC,CAAM,GACpB,KAAK,SAAS;AAAA,SACT;AACD,UAAAD;AAAuB,cAAM,MAAM,GAAG,KAAK,YAAY,sBAAsB;AACjF,cAAQ,MAAM,oCAAoC,KAAK,YAAY,EAAE;AAAA,IACvE;AAAA,EACF;AAAA;AAAA,EAGQ,WAAiB;AACvB,SAAK,WAAW,QAChB,KAAK,WAAW,QAChB,OAAO,OAAO,IAAI;AAAA,EACpB;AACF;AC1FO,SAASE,KAAkB;AAChC,SAAO,eAAe;AAAA,IAAQ;AAAA,IAAS,CAACC;AAAA;AAAA;AAAA,QAGnC,KAAK,WAAW,CAAC,CAACA,KAAK,SAAYA,GAAG,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAAA;AAAA,EAAA;AAEzE;AASO,SAASC,EAASC,GAAyB;AACzC,SAAA,OAAOA,KAAM,YAAYA,aAAa;AAC/C;AASO,SAASC,EAAaC,GAAW;AAGtC,SAAO,KAAK,MAAM,KAAK,UAAUA,CAAG,CAAC;AACvC;AAYgB,SAAAC,GAA6CC,GAAOC,IAAQ,KAAQ;AAClF,MAAIN,EAASK,CAAE;AAAS,UAAA,IAAI,MAAM,0CAA0C;AACxE,MAAAE;AAGJ,SAAQ,IAAIC,MAAS;AACnB,iBAAaD,CAAO,GACpBA,IAAU,WAAW,MAAMF,EAAG,GAAGG,CAAI,GAAGF,CAAK;AAAA,EAAA;AAEjD;AAiBgB,SAAAG,GACdC,GACAC,GACAC,GACsB;AAChB,QAAAC,wBAAU;AACV,SAAAH,EAAA,QAAQ,CAACI,MAAS;AAChB,UAAAC,IAAMJ,EAAYG,CAAI,GACtBE,IAAQH,EAAI,IAAIE,CAAG,GACnBpB,IAAQiB,IAAgBA,EAAcE,GAAMC,CAAG,IAAID;AACrD,IAAAE,IAAOA,EAAM,KAAKrB,CAAK,IACtBkB,EAAI,IAAIE,GAAK,CAACpB,CAAK,CAAC;AAAA,EAAA,CAC1B,GACMkB;AACT;AAQA,SAASI,EAAmBC,GAA2C;AACrE,SACE,OAAOA,KAAU;AAAA;AAAA,EAGjBA,MAAU,QACV,aAAaA;AAAA;AAAA,EAGb,OAAQA,EAAkC,WAAY;AAE1D;AAUA,SAASC,EAAmBC,GAAuC;AACjE,MAAIH,EAAmBG,CAAU;AAAU,WAAAA;AAEvC,MAAA;AACF,WAAO,IAAI,MAAM,KAAK,UAAUA,CAAU,CAAC;AAAA,EAAA,QACrC;AAGN,WAAO,IAAI,MAAM,OAAOA,CAAU,CAAC;AAAA,EACrC;AACF;AAaO,SAASC,GAAgBH,GAAgB;AACvC,SAAAC,EAAmBD,CAAK,EAAE;AACnC;AAGO,SAASI,EAAKC,GAAY;AAE/B,SAAO,IAAI,QAAc,CAAC9B,MAAY,WAAWA,GAAS8B,CAAE,CAAC;AAC/D;AAUgB,SAAAC,GAAyBnB,GAA4BoB,GAAyB;AAC5F,QAAMlB,IAAUe,EAAKG,CAAe,EAAE,KAAK,MAAA;AAAA,GAAe;AAC1D,SAAO,QAAQ,IAAI,CAAClB,GAASF,EAAA,CAAI,CAAC;AACpC;AAagB,SAAAqB,GACdvB,GACAwB,IAAgB,OACH;AACP,QAAAC,wBAA0B;AAGhC,SAAO,oBAAoBzB,CAAG,EAAE,QAAQ,CAAC0B,MAAa;AAChD,QAAA;AACE,MAAA,OAAO1B,EAAI0B,CAAQ,KAAM,cAAYD,EAAoB,IAAIC,CAAQ;AAAA,aAClEX,GAAO;AACd,cAAQ,MAAM,YAAYW,CAAQ,OAAOF,CAAK,kBAAkBT,CAAK,EAAE;AAAA,IACzE;AAAA,EAAA,CACD;AAIG,MAAAY,IAAkB,OAAO,eAAe3B,CAAG;AAC/C,SAAO2B,KAAmB,OAAO,eAAeA,CAAe;AAC7D,WAAO,oBAAoBA,CAAe,EAAE,QAAQ,CAACD,MAAa;AAC5D,UAAA;AACE,QAAA,OAAO1B,EAAI0B,CAAQ,KAAM,cAAYD,EAAoB,IAAIC,CAAQ;AAAA,eAClEX,GAAO;AACd,gBAAQ,MAAM,YAAYW,CAAQ,OAAOF,CAAK,8BAA8BT,CAAK,EAAE;AAAA,MACrF;AAAA,IAAA,CACD,GACiBY,IAAA,OAAO,eAAeA,CAAe;AAGlD,SAAAF;AACT;AAcO,SAASG,GACdC,GACAC,IAA4B,IACzB;AAII,SAAA,IAAI,MAAMA,GAAoB;AAAA,IACnC,IAAIC,GAAQC,GAAM;AAGhB,aAAIA,KAAQD,IAAeA,EAAOC,CAAI,IAC/B,UAAU3B,OAIP,MAAMwB,EAAU,GAAGG,CAAI,EAAE,GAAG3B,CAAI;AAAA,IAE5C;AAAA,EAAA,CACD;AACH;ACpNA,MAA8B4B,GAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYzC,YAAYC,GAAgCC,GAAkC;AAX9E,IAAA9C,EAAA;AACS,IAAAA,EAAA,2CAAoB;AAC7B,IAAAA,EAAA;AACS,IAAAA,EAAA;AAUjB,SAAK,eAAe6C,GACpB,KAAK,UAAUC,GACf,KAAK,mBAAmBD,CAAY;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,mBAAmBA,GAA8D;AAC/E,gBAAK,yBAAyBA,CAAY,GAC1C,KAAK,eAAe,KAAK,QAAQ,gBAAgBnC,EAAUmC,CAAY,IAAIA,GACpE,KAAK;EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,wBACEE,GACAC,GAC8B;AACzB,SAAA,qBAAqBD,GAAcC,CAAQ;AAChD,UAAMC,IAA0B,KAAK,cAAc,IAAIF,CAAY,GAC7DG,IAAgB,KAAK,QAAQ,iBAAmBF,IAAWtC,EAAUsC,CAAQ,IAAIA;AAClF,SAAA,cAAc,IAAID,GAAcG,CAAa;AAC9C,QAAA;AACF,aAAO,KAAK;aACLxB,GAAO;AAEV,YAAAuB,IAA8B,KAAA,cAAc,IAAIF,GAAcE,CAAuB,IAC/E,KAAA,cAAc,OAAOF,CAAY,GACrC,IAAI,MAAM,yCAAyCA,CAAY,KAAKrB,CAAK,EAAE;AAAA,IACnF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,mBAAmBqB,GAA0C;AAC3D,UAAMC,IAAW,KAAK,cAAc,IAAID,CAAY;AACpD,QAAI,CAACC;AAAgB,YAAA,IAAI,MAAM,8BAA8B;AACxD,SAAA,cAAc,OAAOD,CAAY;AAClC,QAAA;AACF,aAAO,KAAK;aACLrB,GAAO;AAET,iBAAA,cAAc,IAAIqB,GAAcC,CAAQ,GACvC,IAAI,MAAM,0CAA0CD,CAAY,KAAKrB,CAAK,EAAE;AAAA,IACpF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,UAAwC;AAElC,QAAA,KAAK,cAAc,SAAS,GAAG;AAC7B,UAAAyB,IAAkBzC,EAAU,KAAK,YAAY;AAC/B,aAAAyC,IAAA,KAAK,qBAAqBA,CAAe,GAC3D,KAAK,eAAeA,CAAe,GACnC,KAAK,eAAeA,GACb,KAAK;AAAA,IACd;AAGA,QAAIC,IAAkB,KAAK;AACtB,gBAAA,cAAc,QAAQ,CAACC,MAAmC;AAC3C,MAAAD,IAAAE;AAAA,QAChBF;AAAA,QACAC;AAAA,QACA,KAAK,QAAQ;AAAA,MAAA,GAEf,KAAK,eAAeD,CAAe;AAAA,IAAA,CACpC,GACiBA,IAAA,KAAK,qBAAqBA,CAAe,GAC3D,KAAK,eAAeA,CAAe,GACnC,KAAK,eAAeA,GACb,KAAK;AAAA,EACd;AAiCF;AAUA,SAASG,KAAsBC,GAA4B;AACzD,MAAIC,IAAW;AACR,SAAAD,EAAA,QAAQ,CAACrD,MAAmB;AACjC,KAAI,CAACA,KAAS,OAAOA,KAAU,YAAY,MAAM,QAAQA,CAAK,OAAcsD,IAAA;AAAA,EAAA,CAC7E,GACMA;AACT;AAQA,SAASC,KAAmBF,GAA4B;AACtD,MAAIC,IAAW;AACR,SAAAD,EAAA,QAAQ,CAACrD,MAAmB;AAC7B,KAAA,CAACA,KAAS,OAAOA,KAAU,YAAY,CAAC,MAAM,QAAQA,CAAK,OAAcsD,IAAA;AAAA,EAAA,CAC9E,GACMA;AACT;AAUA,SAASH,EACPK,GACAC,GACAC,GACkB;AACZ,QAAAC,IAASpD,EAAUiD,CAAa;AACtC,SAAKC,KAEL,OAAO,KAAKA,CAAQ,EAAE,QAAQ,CAACrC,MAAyB;AACtD,QAAI,OAAO,OAAOoC,GAAepC,CAAG;AAClC,UAAIgC,EAAmBI,EAAcpC,CAAG,GAAGqC,EAASrC,CAAG,CAAC;AACtD,QAAAuC,EAAOvC,CAAG,IAAI+B;AAAA;AAAA;AAAA,UAGZK,EAAcpC,CAAG;AAAA,UACjBqC,EAASrC,CAAG;AAAA,UACZsC;AAAA;AAAA,QAAA;AAAA,eAGOH,EAAgBC,EAAcpC,CAAG,GAAGqC,EAASrC,CAAG,CAAC;AAGnD,QAAAuC,EAAAvC,CAAG,IAAKuC,EAAOvC,CAAG,EAAqB,OAAOqC,EAASrC,CAAG,CAAmB;AAAA,eAC3E,CAACsC;AACV,cAAM,IAAI,MAAM,8BAA8BtC,CAAG,uCAAuC;AAAA;AAEnF,MAAAuC,EAAAvC,CAAG,IAAIqC,EAASrC,CAAG;AAAA,EAC5B,CACD,GAEMuC;AACT;ACrOA,MAAqBC,GAAsB;AAAA,EAGzC,YAAoBC,IAAO,aAAa;AAF/B,IAAAhE,EAAA,2CAAoB;AAET,SAAA,OAAAgE;AAAA,EAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOzC,OAAOC,GAA+D;AACtD,IAAAA,EAAA,QAAQ,CAACC,MAAiB;AACtC,MAAI,aAAaA,IAAmB,KAAA,cAAc,IAAIA,EAAa,OAAO,IAChE,KAAA,cAAc,IAAIA,CAAY;AAAA,IAAA,CACzC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,sBAAwC;AACtC,UAAAC,IAAS,CAAC,GAAG,KAAK,aAAa,EAAE,IAAI,CAACD,MAAiBA,EAAA,CAAc,GACrEE,IAAU,MAAM,QAAQ,IAAID,CAAM;AACxC,gBAAK,cAAc,SACZC,EAAQ,MAAM,CAACC,GAAuBC,OACtCD,KACH,QAAQ,MAAM,yBAAyB,KAAK,IAAI,2BAA2BC,CAAK,UAAU,GAErFD,EACR;AAAA,EACH;AACF;ACzBA,MAAqBE,GAA2C;AAAA,EAAhE;AASE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAAvE,EAAA,mBAAY,KAAK;AAGT;AAAA,IAAAA,EAAA;AAEA;AAAA,IAAAA,EAAA;AAEA;AAAA,IAAAA,EAAA,oBAAa;AAyCrB;AAAA,IAAAA,EAAA,iBAAU,MACD,KAAK;AAQd;AAAA;AAAA;AAAA;AAAA;AAAA,IAAAA,EAAA,cAAO,CAACwE,MAAa;AAEnB,WAAK,OAAOA,CAAK;AAAA,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA1CnB,IAAI,QAA0B;AAC5B,gBAAK,kBAAkB,GAElB,KAAK,cACH,KAAA,YAAY,CAACC,MAAa;AACzB,UAAA,CAACA,KAAY,OAAOA,KAAa;AAC7B,cAAA,IAAI,MAAM,4CAA4C;AAG9D,aAAK,KAAK,kBAAe,KAAK,gBAAgB,KAEzC,KAAA,cAAc,KAAKA,CAAQ,GAEzB,MAAM;AACX,YAAI,CAAC,KAAK;AAAsB,iBAAA;AAEhC,cAAMC,IAAgB,KAAK,cAAc,QAAQD,CAAQ;AAEzD,eAAIC,IAAgB,IAAU,MAGzB,KAAA,cAAc,OAAOA,GAAe,CAAC,GAEnC;AAAA,MAAA;AAAA,IACT,IAGG,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBU,OAAOF,GAAU;AJtF7B,QAAAG;AIuFI,SAAK,kBAAkB,IAEvBA,IAAA,KAAK,kBAAL,QAAAA,EAAoB,QAAQ,CAACF,MAAaA,EAASD,CAAK;AAAA,EAC1D;AAAA;AAAA,EAGU,oBAAoB;AAC5B,QAAI,KAAK;AAAkB,YAAA,IAAI,MAAM,qBAAqB;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMU,YAAY;AACpB,gBAAK,kBAAkB,GAEvB,KAAK,aAAa,IAClB,KAAK,gBAAgB,QACrB,KAAK,YAAY,QACV,QAAQ,QAAQ,EAAI;AAAA,EAC7B;AACF;AC5GA,MAAMI,IAA0B;AAAA,EAC9B,EAAE,WAAW,OAAO,WAAW,CAAC,OAAO,GAAG,UAAU,GAAG;AAAA,EACvD,EAAE,WAAW,OAAO,WAAW,CAAC,SAAS,GAAG,UAAU,GAAG;AAAA,EACzD,EAAE,WAAW,OAAO,WAAW,CAAC,QAAQ,GAAG,UAAU,GAAG;AAAA,EACxD,EAAE,WAAW,OAAO,WAAW,CAAC,WAAW,GAAG,UAAU,GAAG;AAAA,EAC3D,EAAE,WAAW,OAAO,WAAW,CAAC,SAAS,GAAG,UAAU,GAAG;AAAA,EACzD,EAAE,WAAW,OAAO,WAAW,CAAC,aAAa,GAAG,UAAU,GAAG;AAAA,EAC7D,EAAE,WAAW,OAAO,WAAW,CAAC,QAAQ,GAAG,UAAU,GAAG;AAAA,EACxD,EAAE,WAAW,OAAO,WAAW,CAAC,QAAQ,GAAG,UAAU,GAAG;AAAA,EACxD,EAAE,WAAW,OAAO,WAAW,CAAC,MAAM,GAAG,UAAU,EAAE;AAAA,EACrD,EAAE,WAAW,OAAO,WAAW,CAAC,UAAU,GAAG,UAAU,GAAG;AAAA,EAC1D,EAAE,WAAW,OAAO,WAAW,CAAC,UAAU,GAAG,UAAU,GAAG;AAAA,EAC1D,EAAE,WAAW,OAAO,WAAW,CAAC,SAAS,GAAG,UAAU,GAAG;AAAA,EACzD,EAAE,WAAW,OAAO,WAAW,CAAC,SAAS,GAAG,UAAU,GAAG;AAAA,EACzD,EAAE,WAAW,OAAO,WAAW,CAAC,cAAc,GAAG,UAAU,GAAG;AAAA,EAC9D,EAAE,WAAW,OAAO,WAAW,CAAC,cAAc,GAAG,UAAU,GAAG;AAAA,EAC9D,EAAE,WAAW,OAAO,WAAW,CAAC,MAAM,GAAG,UAAU,GAAG;AAAA,EACtD,EAAE,WAAW,OAAO,WAAW,CAAC,UAAU,GAAG,UAAU,GAAG;AAAA,EAC1D,EAAE,WAAW,OAAO,WAAW,CAAC,QAAQ,GAAG,UAAU,GAAG;AAAA,EACxD,EAAE,WAAW,OAAO,WAAW,CAAC,KAAK,GAAG,UAAU,GAAG;AAAA,EACrD,EAAE,WAAW,OAAO,WAAW,CAAC,SAAS,QAAQ,GAAG,UAAU,IAAI;AAAA,EAClE,EAAE,WAAW,OAAO,WAAW,CAAC,UAAU,GAAG,UAAU,GAAG;AAAA,EAC1D,EAAE,WAAW,OAAO,WAAW,CAAC,cAAc,GAAG,UAAU,GAAG;AAAA,EAC9D,EAAE,WAAW,OAAO,WAAW,CAAC,mBAAmB,eAAe,GAAG,UAAU,EAAE;AAAA,EACjF,EAAE,WAAW,OAAO,WAAW,CAAC,QAAQ,GAAG,UAAU,GAAG;AAAA,EACxD,EAAE,WAAW,OAAO,WAAW,CAAC,UAAU,GAAG,UAAU,GAAG;AAAA,EAC1D,EAAE,WAAW,OAAO,WAAW,CAAC,cAAc,GAAG,UAAU,EAAE;AAAA,EAC7D,EAAE,WAAW,OAAO,WAAW,CAAC,SAAS,GAAG,UAAU,GAAG;AAAA,EACzD,EAAE,WAAW,OAAO,WAAW,CAAC,QAAQ,GAAG,UAAU,GAAG;AAAA,EACxD,EAAE,WAAW,OAAO,WAAW,CAAC,OAAO,GAAG,UAAU,GAAG;AAAA,EACvD,EAAE,WAAW,OAAO,WAAW,CAAC,MAAM,GAAG,UAAU,EAAE;AAAA,EACrD,EAAE,WAAW,OAAO,WAAW,CAAC,MAAM,GAAG,UAAU,EAAE;AAAA,EACrD,EAAE,WAAW,OAAO,WAAW,CAAC,SAAS,GAAG,UAAU,EAAE;AAAA,EACxD,EAAE,WAAW,OAAO,WAAW,CAAC,OAAO,GAAG,UAAU,EAAE;AAAA,EACtD,EAAE,WAAW,OAAO,WAAW,CAAC,OAAO,GAAG,UAAU,EAAE;AAAA,EACtD,EAAE,WAAW,OAAO,WAAW,CAAC,OAAO,GAAG,UAAU,EAAE;AAAA,EACtD,EAAE,WAAW,OAAO,WAAW,CAAC,UAAU,GAAG,UAAU,EAAE;AAAA,EACzD,EAAE,WAAW,OAAO,WAAW,CAAC,WAAW,GAAG,UAAU,EAAE;AAAA,EAC1D,EAAE,WAAW,OAAO,WAAW,CAAC,QAAQ,GAAG,UAAU,EAAE;AAAA,EACvD,EAAE,WAAW,OAAO,WAAW,CAAC,WAAW,GAAG,UAAU,GAAG;AAAA,EAC3D,EAAE,WAAW,OAAO,WAAW,CAAC,SAAS,GAAG,UAAU,EAAE;AAAA,EACxD,EAAE,WAAW,OAAO,WAAW,CAAC,SAAS,GAAG,UAAU,GAAG;AAAA,EACzD,EAAE,WAAW,OAAO,WAAW,CAAC,MAAM,GAAG,UAAU,GAAG;AAAA,EACtD,EAAE,WAAW,OAAO,WAAW,CAAC,MAAM,GAAG,UAAU,GAAG;AAAA,EACtD,EAAE,WAAW,OAAO,WAAW,CAAC,MAAM,GAAG,UAAU,GAAG;AAAA,EACtD,EAAE,WAAW,OAAO,WAAW,CAAC,MAAM,GAAG,UAAU,GAAG;AAAA,EACtD,EAAE,WAAW,OAAO,WAAW,CAAC,QAAQ,GAAG,UAAU,GAAG;AAAA,EACxD,EAAE,WAAW,OAAO,WAAW,CAAC,eAAe,GAAG,UAAU,GAAG;AAAA,EAC/D,EAAE,WAAW,OAAO,WAAW,CAAC,eAAe,GAAG,UAAU,GAAG;AAAA,EAC/D,EAAE,WAAW,OAAO,WAAW,CAAC,WAAW,GAAG,UAAU,EAAE;AAAA,EAC1D,EAAE,WAAW,OAAO,WAAW,CAAC,WAAW,GAAG,UAAU,EAAE;AAAA,EAC1D,EAAE,WAAW,OAAO,WAAW,CAAC,aAAa,GAAG,UAAU,EAAE;AAAA,EAC5D,EAAE,WAAW,OAAO,WAAW,CAAC,YAAY,GAAG,UAAU,EAAE;AAAA,EAC3D,EAAE,WAAW,OAAO,WAAW,CAAC,iBAAiB,GAAG,UAAU,EAAE;AAAA,EAChE,EAAE,WAAW,OAAO,WAAW,CAAC,iBAAiB,GAAG,UAAU,EAAE;AAAA,EAChE,EAAE,WAAW,OAAO,WAAW,CAAC,WAAW,GAAG,UAAU,EAAE;AAAA,EAC1D,EAAE,WAAW,OAAO,WAAW,CAAC,WAAW,GAAG,UAAU,EAAE;AAAA,EAC1D,EAAE,WAAW,OAAO,WAAW,CAAC,OAAO,GAAG,UAAU,EAAE;AAAA,EACtD,EAAE,WAAW,OAAO,WAAW,CAAC,UAAU,GAAG,UAAU,EAAE;AAAA,EACzD,EAAE,WAAW,OAAO,WAAW,CAAC,SAAS,GAAG,UAAU,GAAG;AAAA,EACzD,EAAE,WAAW,OAAO,WAAW,CAAC,OAAO,GAAG,UAAU,EAAE;AAAA,EACtD,EAAE,WAAW,OAAO,WAAW,CAAC,SAAS,GAAG,UAAU,EAAE;AAAA,EACxD,EAAE,WAAW,OAAO,WAAW,CAAC,SAAS,GAAG,UAAU,EAAE;AAAA,EACxD,EAAE,WAAW,OAAO,WAAW,CAAC,QAAQ,GAAG,UAAU,EAAE;AAAA,EACvD,EAAE,WAAW,OAAO,WAAW,CAAC,QAAQ,GAAG,UAAU,EAAE;AAAA,EACvD,EAAE,WAAW,OAAO,WAAW,CAAC,QAAQ,GAAG,UAAU,EAAE;AAAA,EACvD,EAAE,WAAW,OAAO,WAAW,CAAC,MAAM,GAAG,UAAU,EAAE;AAAA,EACrD,EAAE,WAAW,OAAO,WAAW,CAAC,YAAY,GAAG,UAAU,GAAG;AAC9D,GAEaC,IAAqB,GACrBC,IAAoBF,EAAY,SAAS,GACzCG,IAAwB,GACxBC,IAAsB,GAEtBC,IAAqB,CAACC,MAA4B;AL5E/D,MAAAP;AK6ES,WAAAA,IAAAC,EAAYM,CAAO,MAAnB,gBAAAP,EAAsB,aAAY;AAC3C,GAEaQ,KAAa,CAACC,GAA4BC,OAAwC;AAAA,EAC7F,SAAS,KAAK,IAAIR,GAAoB,KAAK,IAAIO,EAAO,UAAUC,GAAQP,CAAiB,CAAC;AAAA,EAC1F,YAAY;AAAA,EACZ,UAAU;AACZ,IAEaQ,KAAgB,CAACF,GAA4BC,OAAwC;AAAA,EAChG,GAAGD;AAAA,EACH,YAAY,KAAK;AAAA,IACf,KAAK,IAAIL,GAAuBK,EAAO,aAAaC,CAAM;AAAA,IAC1DJ,EAAmBG,EAAO,OAAO;AAAA,EACnC;AAAA,EACA,UAAU;AACZ,IAEaG,KAAc,CAACH,GAA4BC,OAAwC;AAAA,EAC9F,GAAGD;AAAA,EACH,UAAU,KAAK,IAAIJ,GAAqBI,EAAO,WAAWC,CAAM;AAClE,IC1FaG,KAAyB,CAACvB,MAC9B,IAAIjD,MAEMiD,EAAc,IAAI,CAACC,MAAiBA,EAAa,GAAGlD,CAAI,CAAC,EAG1D,MAAM,CAACyE,MAAYA,CAAO,GAgB/BC,KAA8B,CACzCzB,MAEO,UAAUjD,MAAS;AAElB,QAAA2E,IAAgB1B,EAAc,IAAI,OAAOC,MAAiBA,EAAa,GAAGlD,CAAI,CAAC;AAG7E,UAAA,MAAM,QAAQ,IAAI2E,CAAa,GAAG,MAAM,CAACF,MAAYA,CAAO;AAAA;ACvCxE,IAAIG,IAAsB,OAAO,qBAAqBC,IAAwB,OAAO,uBACjFC,IAAiB,OAAO,UAAU;AAItC,SAASC,EAAmBC,GAAaC,GAAa;AAClD,SAAO,SAAiBC,GAAGC,GAAGC,GAAO;AACjC,WAAOJ,EAAYE,GAAGC,GAAGC,CAAK,KAAKH,EAAYC,GAAGC,GAAGC,CAAK;AAAA,EAClE;AACA;AAMA,SAASC,EAAiBC,GAAe;AACrC,SAAO,SAAoBJ,GAAGC,GAAGC,GAAO;AACpC,QAAI,CAACF,KAAK,CAACC,KAAK,OAAOD,KAAM,YAAY,OAAOC,KAAM;AAClD,aAAOG,EAAcJ,GAAGC,GAAGC,CAAK;AAEpC,QAAIG,IAAQH,EAAM,OACdI,IAAUD,EAAM,IAAIL,CAAC,GACrBO,IAAUF,EAAM,IAAIJ,CAAC;AACzB,QAAIK,KAAWC;AACX,aAAOD,MAAYL,KAAKM,MAAYP;AAExC,IAAAK,EAAM,IAAIL,GAAGC,CAAC,GACdI,EAAM,IAAIJ,GAAGD,CAAC;AACd,QAAIQ,IAASJ,EAAcJ,GAAGC,GAAGC,CAAK;AACtC,WAAAG,EAAM,OAAOL,CAAC,GACdK,EAAM,OAAOJ,CAAC,GACPO;AAAA,EACf;AACA;AAKA,SAASC,EAAoBC,GAAQ;AACjC,SAAOhB,EAAoBgB,CAAM,EAAE,OAAOf,EAAsBe,CAAM,CAAC;AAC3E;AAIA,IAAIC,IAAS,OAAO,UACf,SAAUD,GAAQvE,GAAU;AACzB,SAAOyD,EAAe,KAAKc,GAAQvE,CAAQ;AACnD;AAIA,SAASyE,EAAmBZ,GAAGC,GAAG;AAC9B,SAAOD,KAAKC,IAAID,MAAMC,IAAID,MAAMC,KAAMD,MAAMA,KAAKC,MAAMA;AAC3D;AAEA,IAAIY,IAAQ,UACRC,IAA2B,OAAO,0BAA0BC,IAAO,OAAO;AAI9E,SAASC,EAAehB,GAAGC,GAAGC,GAAO;AACjC,MAAI9B,IAAQ4B,EAAE;AACd,MAAIC,EAAE,WAAW7B;AACb,WAAO;AAEX,SAAOA,MAAU;AACb,QAAI,CAAC8B,EAAM,OAAOF,EAAE5B,CAAK,GAAG6B,EAAE7B,CAAK,GAAGA,GAAOA,GAAO4B,GAAGC,GAAGC,CAAK;AAC3D,aAAO;AAGf,SAAO;AACX;AAIA,SAASe,EAAcjB,GAAGC,GAAG;AACzB,SAAOW,EAAmBZ,EAAE,QAAS,GAAEC,EAAE,QAAO,CAAE;AACtD;AAIA,SAASiB,EAAalB,GAAGC,GAAGC,GAAO;AAC/B,MAAIF,EAAE,SAASC,EAAE;AACb,WAAO;AAOX,WALIkB,IAAiB,CAAA,GACjBC,IAAYpB,EAAE,WACd5B,IAAQ,GACRiD,GACAC,IACID,IAAUD,EAAU,WACpB,CAAAC,EAAQ,QADqB;AAOjC,aAHIE,IAAYtB,EAAE,WACduB,IAAW,IACXC,IAAa,IACTH,IAAUC,EAAU,WACpB,CAAAD,EAAQ,QADqB;AAIjC,UAAI7C,IAAK4C,EAAQ,OAAOK,IAAOjD,EAAG,CAAC,GAAGkD,IAASlD,EAAG,CAAC,GAC/CmD,IAAKN,EAAQ,OAAOO,IAAOD,EAAG,CAAC,GAAGE,IAASF,EAAG,CAAC;AACnD,MAAI,CAACJ,KACD,CAACL,EAAeM,CAAU,MACzBD,IACGtB,EAAM,OAAOwB,GAAMG,GAAMzD,GAAOqD,GAAYzB,GAAGC,GAAGC,CAAK,KACnDA,EAAM,OAAOyB,GAAQG,GAAQJ,GAAMG,GAAM7B,GAAGC,GAAGC,CAAK,OAC5DiB,EAAeM,CAAU,IAAI,KAEjCA;AAAA,IACH;AACD,QAAI,CAACD;AACD,aAAO;AAEX,IAAApD;AAAA,EACH;AACD,SAAO;AACX;AAIA,SAAS2D,GAAgB/B,GAAGC,GAAGC,GAAO;AAClC,MAAI8B,IAAajB,EAAKf,CAAC,GACnB5B,IAAQ4D,EAAW;AACvB,MAAIjB,EAAKd,CAAC,EAAE,WAAW7B;AACnB,WAAO;AAOX,WALIjC,GAKGiC,MAAU;AAOb,QANAjC,IAAW6F,EAAW5D,CAAK,GACvBjC,MAAa0E,MACZb,EAAE,YAAYC,EAAE,aACjBD,EAAE,aAAaC,EAAE,YAGjB,CAACU,EAAOV,GAAG9D,CAAQ,KACnB,CAAC+D,EAAM,OAAOF,EAAE7D,CAAQ,GAAG8D,EAAE9D,CAAQ,GAAGA,GAAUA,GAAU6D,GAAGC,GAAGC,CAAK;AACvE,aAAO;AAGf,SAAO;AACX;AAIA,SAAS+B,EAAsBjC,GAAGC,GAAGC,GAAO;AACxC,MAAI8B,IAAavB,EAAoBT,CAAC,GAClC5B,IAAQ4D,EAAW;AACvB,MAAIvB,EAAoBR,CAAC,EAAE,WAAW7B;AAClC,WAAO;AASX,WAPIjC,GACA+F,GACAC,GAKG/D,MAAU;AAeb,QAdAjC,IAAW6F,EAAW5D,CAAK,GACvBjC,MAAa0E,MACZb,EAAE,YAAYC,EAAE,aACjBD,EAAE,aAAaC,EAAE,YAGjB,CAACU,EAAOV,GAAG9D,CAAQ,KAGnB,CAAC+D,EAAM,OAAOF,EAAE7D,CAAQ,GAAG8D,EAAE9D,CAAQ,GAAGA,GAAUA,GAAU6D,GAAGC,GAAGC,CAAK,MAG3EgC,IAAcpB,EAAyBd,GAAG7D,CAAQ,GAClDgG,IAAcrB,EAAyBb,GAAG9D,CAAQ,IAC7C+F,KAAeC,OACf,CAACD,KACE,CAACC,KACDD,EAAY,iBAAiBC,EAAY,gBACzCD,EAAY,eAAeC,EAAY,cACvCD,EAAY,aAAaC,EAAY;AACzC,aAAO;AAGf,SAAO;AACX;AAIA,SAASC,GAA0BpC,GAAGC,GAAG;AACrC,SAAOW,EAAmBZ,EAAE,QAAS,GAAEC,EAAE,QAAO,CAAE;AACtD;AAIA,SAASoC,GAAgBrC,GAAGC,GAAG;AAC3B,SAAOD,EAAE,WAAWC,EAAE,UAAUD,EAAE,UAAUC,EAAE;AAClD;AAIA,SAASqC,EAAatC,GAAGC,GAAGC,GAAO;AAC/B,MAAIF,EAAE,SAASC,EAAE;AACb,WAAO;AAMX,WAJIkB,IAAiB,CAAA,GACjBC,IAAYpB,EAAE,UACdqB,GACAC,IACID,IAAUD,EAAU,WACpB,CAAAC,EAAQ,QADqB;AAOjC,aAHIE,IAAYtB,EAAE,UACduB,IAAW,IACXC,IAAa,IACTH,IAAUC,EAAU,WACpB,CAAAD,EAAQ;AAGZ,MAAI,CAACE,KACD,CAACL,EAAeM,CAAU,MACzBD,IAAWtB,EAAM,OAAOmB,EAAQ,OAAOC,EAAQ,OAAOD,EAAQ,OAAOC,EAAQ,OAAOtB,GAAGC,GAAGC,CAAK,OAChGiB,EAAeM,CAAU,IAAI,KAEjCA;AAEJ,QAAI,CAACD;AACD,aAAO;AAAA,EAEd;AACD,SAAO;AACX;AAIA,SAASe,GAAoBvC,GAAGC,GAAG;AAC/B,MAAI7B,IAAQ4B,EAAE;AACd,MAAIC,EAAE,WAAW7B;AACb,WAAO;AAEX,SAAOA,MAAU;AACb,QAAI4B,EAAE5B,CAAK,MAAM6B,EAAE7B,CAAK;AACpB,aAAO;AAGf,SAAO;AACX;AAEA,IAAIoE,KAAgB,sBAChBC,KAAc,oBACdC,KAAW,iBACXC,KAAU,gBACVC,KAAa,mBACbC,KAAa,mBACbC,KAAc,mBACdC,KAAU,gBACVC,KAAa,mBACbC,KAAU,MAAM,SAChBC,IAAe,OAAO,eAAgB,cAAc,YAAY,SAC9D,YAAY,SACZ,MACFC,IAAS,OAAO,QAChBC,KAAS,OAAO,UAAU,SAAS,KAAK,KAAK,OAAO,UAAU,QAAQ;AAI1E,SAASC,GAAyB5E,GAAI;AAClC,MAAIuC,IAAiBvC,EAAG,gBAAgBwC,IAAgBxC,EAAG,eAAeyC,IAAezC,EAAG,cAAcsD,IAAkBtD,EAAG,iBAAiB2D,IAA4B3D,EAAG,2BAA2B4D,IAAkB5D,EAAG,iBAAiB6D,IAAe7D,EAAG,cAAc8D,IAAsB9D,EAAG;AAIzS,SAAO,SAAoBuB,GAAGC,GAAGC,GAAO;AAEpC,QAAIF,MAAMC;AACN,aAAO;AAMX,QAAID,KAAK,QACLC,KAAK,QACL,OAAOD,KAAM,YACb,OAAOC,KAAM;AACb,aAAOD,MAAMA,KAAKC,MAAMA;AAE5B,QAAIqD,IAActD,EAAE;AAWpB,QAAIsD,MAAgBrD,EAAE;AAClB,aAAO;AAKX,QAAIqD,MAAgB;AAChB,aAAOvB,EAAgB/B,GAAGC,GAAGC,CAAK;AAItC,QAAI+C,GAAQjD,CAAC;AACT,aAAOgB,EAAehB,GAAGC,GAAGC,CAAK;AAIrC,QAAIgD,KAAgB,QAAQA,EAAalD,CAAC;AACtC,aAAOuC,EAAoBvC,GAAGC,GAAGC,CAAK;AAO1C,QAAIoD,MAAgB;AAChB,aAAOrC,EAAcjB,GAAGC,GAAGC,CAAK;AAEpC,QAAIoD,MAAgB;AAChB,aAAOjB,EAAgBrC,GAAGC,GAAGC,CAAK;AAEtC,QAAIoD,MAAgB;AAChB,aAAOpC,EAAalB,GAAGC,GAAGC,CAAK;AAEnC,QAAIoD,MAAgB;AAChB,aAAOhB,EAAatC,GAAGC,GAAGC,CAAK;AAInC,QAAIqD,IAAMH,GAAOpD,CAAC;AAClB,WAAIuD,MAAQb,KACDzB,EAAcjB,GAAGC,GAAGC,CAAK,IAEhCqD,MAAQT,KACDT,EAAgBrC,GAAGC,GAAGC,CAAK,IAElCqD,MAAQZ,KACDzB,EAAalB,GAAGC,GAAGC,CAAK,IAE/BqD,MAAQR,KACDT,EAAatC,GAAGC,GAAGC,CAAK,IAE/BqD,MAAQV,KAIA,OAAO7C,EAAE,QAAS,cACtB,OAAOC,EAAE,QAAS,cAClB8B,EAAgB/B,GAAGC,GAAGC,CAAK,IAG/BqD,MAAQf,KACDT,EAAgB/B,GAAGC,GAAGC,CAAK,IAKlCqD,MAAQd,MAAec,MAAQX,MAAcW,MAAQP,KAC9CZ,EAA0BpC,GAAGC,GAAGC,CAAK,IAazC;AAAA,EACf;AACA;AAIA,SAASsD,GAA+B/E,GAAI;AACxC,MAAIgF,IAAWhF,EAAG,UAAUiF,IAAqBjF,EAAG,oBAAoBkF,IAASlF,EAAG,QAChFmF,IAAS;AAAA,IACT,gBAAgBD,IACV1B,IACAjB;AAAA,IACN,eAAeC;AAAA,IACf,cAAc0C,IACR9D,EAAmBqB,GAAce,CAAqB,IACtDf;AAAA,IACN,iBAAiByC,IACX1B,IACAF;AAAA,IACN,2BAA2BK;AAAA,IAC3B,iBAAiBC;AAAA,IACjB,cAAcsB,IACR9D,EAAmByC,GAAcL,CAAqB,IACtDK;AAAA,IACN,qBAAqBqB,IACf1B,IACAM;AAAA,EACd;AAII,MAHImB,MACAE,IAAST,EAAO,CAAE,GAAES,GAAQF,EAAmBE,CAAM,CAAC,IAEtDH,GAAU;AACV,QAAII,IAAmB1D,EAAiByD,EAAO,cAAc,GACzDE,IAAiB3D,EAAiByD,EAAO,YAAY,GACrDG,IAAoB5D,EAAiByD,EAAO,eAAe,GAC3DI,IAAiB7D,EAAiByD,EAAO,YAAY;AACzD,IAAAA,IAAST,EAAO,CAAE,GAAES,GAAQ;AAAA,MACxB,gBAAgBC;AAAA,MAChB,cAAcC;AAAA,MACd,iBAAiBC;AAAA,MACjB,cAAcC;AAAA,IAC1B,CAAS;AAAA,EACJ;AACD,SAAOJ;AACX;AAKA,SAASK,GAAiCC,GAAS;AAC/C,SAAO,SAAUlE,GAAGC,GAAGkE,GAAcC,GAAcC,GAAUC,GAAUpE,GAAO;AAC1E,WAAOgE,EAAQlE,GAAGC,GAAGC,CAAK;AAAA,EAClC;AACA;AAIA,SAASqE,GAAc9F,GAAI;AACvB,MAAIgF,IAAWhF,EAAG,UAAU+F,IAAa/F,EAAG,YAAYgG,IAAchG,EAAG,aAAaiG,IAASjG,EAAG,QAAQkF,IAASlF,EAAG;AACtH,MAAIgG;AACA,WAAO,SAAiBzE,GAAGC,GAAG;AAC1B,UAAIxB,IAAKgG,KAAe7C,IAAKnD,EAAG,OAAO4B,IAAQuB,MAAO,SAAS6B,IAAW,oBAAI,YAAY,SAAY7B,GAAI+C,IAAOlG,EAAG;AACpH,aAAO+F,EAAWxE,GAAGC,GAAG;AAAA,QACpB,OAAOI;AAAA,QACP,QAAQqE;AAAA,QACR,MAAMC;AAAA,QACN,QAAQhB;AAAA,MACxB,CAAa;AAAA,IACb;AAEI,MAAIF;AACA,WAAO,SAAiBzD,GAAGC,GAAG;AAC1B,aAAOuE,EAAWxE,GAAGC,GAAG;AAAA,QACpB,OAAO,oBAAI,QAAS;AAAA,QACpB,QAAQyE;AAAA,QACR,MAAM;AAAA,QACN,QAAQf;AAAA,MACxB,CAAa;AAAA,IACb;AAEI,MAAIzD,IAAQ;AAAA,IACR,OAAO;AAAA,IACP,QAAQwE;AAAA,IACR,MAAM;AAAA,IACN,QAAQf;AAAA,EAChB;AACI,SAAO,SAAiB3D,GAAGC,GAAG;AAC1B,WAAOuE,EAAWxE,GAAGC,GAAGC,CAAK;AAAA,EACrC;AACA;AAKA,IAAI0E,KAAYC,EAAiB;AAIXA,EAAkB,EAAE,QAAQ,IAAM;AAIhCA,EAAkB,EAAE,UAAU,IAAM;AAK9BA,EAAkB;AAAA,EAC5C,UAAU;AAAA,EACV,QAAQ;AACZ,CAAC;AAIkBA,EAAkB;AAAA,EACjC,0BAA0B,WAAY;AAAE,WAAOjE;AAAA,EAAqB;AACxE,CAAC;AAIwBiE,EAAkB;AAAA,EACvC,QAAQ;AAAA,EACR,0BAA0B,WAAY;AAAE,WAAOjE;AAAA,EAAqB;AACxE,CAAC;AAI0BiE,EAAkB;AAAA,EACzC,UAAU;AAAA,EACV,0BAA0B,WAAY;AAAE,WAAOjE;AAAA,EAAqB;AACxE,CAAC;AAKgCiE,EAAkB;AAAA,EAC/C,UAAU;AAAA,EACV,0BAA0B,WAAY;AAAE,WAAOjE;AAAA,EAAqB;AAAA,EACpE,QAAQ;AACZ,CAAC;AASD,SAASiE,EAAkBjI,GAAS;AAChC,EAAIA,MAAY,WAAUA,IAAU,CAAE;AACtC,MAAI6B,IAAK7B,EAAQ,UAAU6G,IAAWhF,MAAO,SAAS,KAAQA,GAAIqG,IAAiClI,EAAQ,0BAA0B6H,IAAc7H,EAAQ,aAAagF,IAAKhF,EAAQ,QAAQ+G,IAAS/B,MAAO,SAAS,KAAQA,GAC1NgC,IAASJ,GAA+B5G,CAAO,GAC/C4H,IAAanB,GAAyBO,CAAM,GAC5Cc,IAASI,IACPA,EAA+BN,CAAU,IACzCP,GAAiCO,CAAU;AACjD,SAAOD,GAAc,EAAE,UAAUd,GAAU,YAAYe,GAAY,aAAaC,GAAa,QAAQC,GAAQ,QAAQf,EAAQ,CAAA;AACjI;AC9fwB,SAAAiB,GAAU5E,GAAYC,GAAY;AACjD,SAAA8E,GAAY/E,GAAGC,CAAC;AACzB;ACbgB,SAAA+E,EACd/K,GACAgL,GACAC,GACQ;AASR,SAAO,KAAK,UAAUjL,GARI,CAACkL,GAAqBC,MAA2B;AACzE,QAAIC,IAAWD;AACX,WAAAH,MAAqBI,IAAAJ,EAASE,GAAaE,CAAQ,IAGnDA,MAAa,WAAsBA,IAAA,OAChCA;AAAA,EAAA,GAEuCH,CAAK;AACvD;AAkBgB,SAAAI,GACdrL,GACAsL,GAGK;AAGL,WAASC,EAAY/K,GAAyE;AAC5F,kBAAO,KAAKA,CAAG,EAAE,QAAQ,CAACY,MAAyB;AAG7C,MAAAZ,EAAIY,CAAG,MAAM,OAAMZ,EAAIY,CAAG,IAAI,SAEzB,OAAOZ,EAAIY,CAAG,KAAM,aAG3BZ,EAAIY,CAAG,IAAImK,EAAY/K,EAAIY,CAAG,CAAqC;AAAA,IAAA,CACtE,GACMZ;AAAA,EACT;AAEA,QAAMgL,IAAe,KAAK,MAAMxL,GAAOsL,CAAO;AAG9C,MAAIE,MAAiB;AACrB,WAAI,OAAOA,KAAiB,WAAiBD,EAAYC,CAAY,IAC9DA;AACT;AAuBO,SAASC,GAAezL,GAAyB;AAClD,MAAA;AACI,UAAA0L,IAAkBX,EAAU/K,CAAK;AACvC,WAAO0L,MAAoBX,EAAUM,GAAYK,CAAe,CAAC;AAAA,UACvD;AACH,WAAA;AAAA,EACT;AACF;AAQa,MAAAC,KAAa,CAACC,MACzBA,EACG,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,OAAO,QAAQ,GCSfC,KAAqB;AAAA,EAChC,OAAO;AAAA,EACP,MAAM;AAAA,EACN,YAAY;AAAA,IACV,UAAU;AAAA,MACR,aAAa;AAAA,MACb,MAAM;AAAA,IACR;AAAA,IACA,uBAAuB;AAAA,MACrB,aAAa;AAAA,MACb,MAAM;AAAA,IACR;AAAA,IACA,2BAA2B;AAAA,MACzB,aAAa;AAAA,MACb,MAAM;AAAA,IACR;AAAA,IACA,cAAc;AAAA,MACZ,aAAa;AAAA,MACb,MAAM;AAAA,MACN,mBAAmB;AAAA,QACjB,2BAA2B;AAAA,UACzB,MAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA,sBAAsB;AAAA,IACxB;AAAA,EACF;AAAA,EACA,UAAU,CAAC,YAAY,yBAAyB,6BAA6B,cAAc;AAAA,EAC3F,sBAAsB;AAAA,EACtB,OAAO;AAAA,IACL,aAAa;AAAA,MACX,aACE;AAAA,MACF,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA,gBAAgB;AAAA,MACd,aACE;AAAA,MACF,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA,oBAAoB;AAAA,MAClB,aACE;AAAA,MACF,MAAM;AAAA,MACN,mBAAmB;AAAA,QACjB,2BAA2B;AAAA,UACzB,aAAa;AAAA,UACb,MAAM;AAAA,UACN,YAAY;AAAA,YACV,OAAO;AAAA,cACL,aAAa;AAAA,cACb,MAAM;AAAA,YACR;AAAA,YACA,eAAe;AAAA,cACb,aACE;AAAA,cACF,MAAM;AAAA,YACR;AAAA,YACA,OAAO;AAAA,cACL,aACE;AAAA,cACF,MAAM;AAAA,YACR;AAAA,YACA,cAAc;AAAA,cACZ,aACE;AAAA,cACF,MAAM;AAAA,YACR;AAAA,UACF;AAAA,UACA,UAAU,CAAC,SAAS,OAAO;AAAA,UAC3B,sBAAsB;AAAA,QACxB;AAAA,MACF;AAAA,MACA,YAAY;AAAA,QACV,cAAc;AAAA,UACZ,aACE;AAAA,UACF,MAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,IACA,YAAY;AAAA,MACV,aACE;AAAA,MACF,MAAM;AAAA,MACN,mBAAmB;AAAA,QACjB,2BAA2B;AAAA,UACzB,aAAa;AAAA,UACb,MAAM;AAAA,UACN,OAAO;AAAA,YACL;AAAA,cACE,YAAY;AAAA,gBACV,QAAQ;AAAA,kBACN,aACE;AAAA,kBACF,MAAM;AAAA,gBACR;AAAA,gBACA,OAAO;AAAA,kBACL,aACE;AAAA,kBACF,MAAM;AAAA,gBACR;AAAA,gBACA,cAAc;AAAA,kBACZ,aACE;AAAA,kBACF,MAAM;AAAA,gBACR;AAAA,cACF;AAAA,cACA,UAAU,CAAC,OAAO;AAAA,cAClB,sBAAsB;AAAA,YACxB;AAAA,YACA;AAAA,cACE,YAAY;AAAA,gBACV,UAAU;AAAA,kBACR,aAAa;AAAA,kBACb,MAAM;AAAA,gBACR;AAAA,gBACA,OAAO;AAAA,kBACL,aACE;AAAA,kBACF,MAAM;AAAA,gBACR;AAAA,gBACA,cAAc;AAAA,kBACZ,aACE;AAAA,kBACF,MAAM;AAAA,gBACR;AAAA,cACF;AAAA,cACA,UAAU,CAAC,YAAY,OAAO;AAAA,cAC9B,sBAAsB;AAAA,YACxB;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MACA,sBAAsB;AAAA,IACxB;AAAA,IACA,UAAU;AAAA,MACR,aACE;AAAA,MACF,MAAM;AAAA,MACN,OAAO;AAAA,QACL;AAAA,UACE,YAAY;AAAA,YACV,IAAI;AAAA,cACF,aAAa;AAAA,cACb,MAAM;AAAA,YACR;AAAA,UACF;AAAA,UACA,UAAU,CAAC,IAAI;AAAA,QACjB;AAAA,QACA;AAAA,UACE,YAAY;AAAA,YACV,SAAS;AAAA,cACP,aAAa;AAAA,cACb,MAAM;AAAA,YACR;AAAA,YACA,gBAAgB;AAAA,cACd,aAAa;AAAA,cACb,MAAM;AAAA,YACR;AAAA,YACA,eAAe;AAAA,cACb,aAAa;AAAA,cACb,MAAM;AAAA,YACR;AAAA,UACF;AAAA,UACA,UAAU,CAAC,SAAS;AAAA,QACtB;AAAA,MACF;AAAA,MACA,YAAY;AAAA,QACV,OAAO;AAAA,UACL,aAAa;AAAA,UACb,MAAM;AAAA,QACR;AAAA,QACA,SAAS;AAAA,UACP,aACE;AAAA,UACF,MAAM;AAAA,QACR;AAAA,QACA,aAAa;AAAA,UACX,aACE;AAAA,UACF,MAAM;AAAA,QACR;AAAA,QACA,eAAe;AAAA,UACb,aACE;AAAA,UACF,MAAM;AAAA,QACR;AAAA,QACA,OAAO;AAAA,UACL,aAAa;AAAA,UACb,MAAM;AAAA,QACR;AAAA,QACA,OAAO;AAAA,UACL,aACE;AAAA,UACF,MAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA,UAAU,CAAC,SAAS,SAAS,OAAO;AAAA,MACpC,uBAAuB;AAAA,IACzB;AAAA,IACA,gBAAgB;AAAA,MACd,aAAa;AAAA,MACb,MAAM;AAAA,MACN,YAAY;AAAA,QACV,QAAQ;AAAA,UACN,aAAa;AAAA,UACb,MAAM;AAAA,QACR;AAAA,QACA,OAAO;AAAA,UACL,aAAa;AAAA,UACb,MAAM;AAAA,UACN,OAAO,EAAE,MAAM,mBAAmB;AAAA,UAClC,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,UAAU,OAAO;AAAA,IAC9B;AAAA,IACA,kBAAkB;AAAA,MAChB,aAAa;AAAA,MACb,MAAM;AAAA,MACN,OAAO,CAAC,EAAE,MAAM,0BAA0B;AAAA,MAC1C,uBAAuB;AAAA,IACzB;AAAA,IACA,iBAAiB;AAAA,MACf,aAAa;AAAA,MACb,MAAM;AAAA,MACN,OAAO;AAAA,QACL,EAAE,MAAM,yBAAyB;AAAA,QACjC;AAAA,UACE,YAAY;AAAA,YACV,SAAS;AAAA,cACP,aAAa;AAAA,cACb,MAAM;AAAA,YACR;AAAA,UACF;AAAA,UACA,UAAU,CAAC,SAAS;AAAA,QACtB;AAAA,MACF;AAAA,MACA,uBAAuB;AAAA,IACzB;AAAA,IACA,oBAAoB;AAAA,MAClB,aAAa;AAAA,MACb,MAAM;AAAA,MACN,YAAY;AAAA,QACV,iBAAiB;AAAA,UACf,aACE;AAAA,UACF,MAAM;AAAA,QACR;AAAA,QACA,SAAS;AAAA,UACP,aAAa;AAAA,UACb,MAAM;AAAA,QACR;AAAA,QACA,aAAa;AAAA,UACX,aAAa;AAAA,UACb,MAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA,sBAAsB;AAAA,IACxB;AAAA,EACF;AACF;AAEA,OAAO,OAAOA,EAAkB;","x_google_ignoreList":[7]} \ No newline at end of file +{"version":3,"file":"index.js","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit,\n} from 'stringz';\n\nexport const indexOf = stringzIndexOf;\nexport const substring = stringzSubstring;\nexport const length = stringzLength;\nexport const toArray = stringzToArray;\n\nexport const padStart = (string: string, targetLength: number, padString?: string) => {\n limit(string, targetLength, padString, 'left');\n};\n\nexport const padEnd = (string: string, targetLength: number, padString?: string) => {\n limit(string, targetLength, padString, 'right');\n};\n\nexport const normalize = (string: string, form: 'NFC' | 'NFD' | 'none' = 'NFC') => {\n const upperCaseForm = form.toUpperCase();\n if(upperCaseForm==='NONE')\n {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","stringzIndexOf","stringzSubstring","stringzLength","stringzToArray","padStart","string","targetLength","padEnd","normalize","form","upperCaseForm","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","result","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","matchIndex","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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","x_google_ignoreList":[7,8,10]} \ No newline at end of file diff --git a/lib/platform-bible-utils/package-lock.json b/lib/platform-bible-utils/package-lock.json index 8a1328b5b0..a369e871c9 100644 --- a/lib/platform-bible-utils/package-lock.json +++ b/lib/platform-bible-utils/package-lock.json @@ -19,6 +19,7 @@ "jest": "^29.7.0", "prettier": "^3.2.4", "prettier-plugin-jsdoc": "^1.3.0", + "stringz": "^2.1.0", "ts-node": "^10.9.2", "tslib": "^2.6.2", "typescript": "^5.3.3", @@ -5638,6 +5639,15 @@ "node": ">=8" } }, + "node_modules/stringz": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/stringz/-/stringz-2.1.0.tgz", + "integrity": "sha512-KlywLT+MZ+v0IRepfMxRtnSvDCMc3nR1qqCs3m/qIbSOWkNZYT8XHQA31rS3TnKp0c5xjZu3M4GY/2aRKSi/6A==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", diff --git a/lib/platform-bible-utils/package.json b/lib/platform-bible-utils/package.json index 24de104028..11e2250303 100644 --- a/lib/platform-bible-utils/package.json +++ b/lib/platform-bible-utils/package.json @@ -51,6 +51,7 @@ "jest": "^29.7.0", "prettier": "^3.2.4", "prettier-plugin-jsdoc": "^1.3.0", + "stringz": "^2.1.0", "ts-node": "^10.9.2", "tslib": "^2.6.2", "typescript": "^5.3.3", diff --git a/lib/platform-bible-utils/src/index.ts b/lib/platform-bible-utils/src/index.ts index 187f395a62..7572d14944 100644 --- a/lib/platform-bible-utils/src/index.ts +++ b/lib/platform-bible-utils/src/index.ts @@ -30,6 +30,7 @@ export { getAllObjectFunctionNames, createSyncProxyForAsyncObject, } from './util'; +export { indexOf, substring, length, toArray, padStart, padEnd, normalize } from './string-util'; export { default as deepEqual } from './equality-checking'; export { serialize, deserialize, isSerializable, htmlEncode } from './serialization'; diff --git a/lib/platform-bible-utils/src/string-util.ts b/lib/platform-bible-utils/src/string-util.ts new file mode 100644 index 0000000000..5a4e0ba088 --- /dev/null +++ b/lib/platform-bible-utils/src/string-util.ts @@ -0,0 +1,28 @@ +import { + indexOf as stringzIndexOf, + substring as stringzSubstring, + length as stringzLength, + toArray as stringzToArray, + limit, +} from 'stringz'; + +export const indexOf = stringzIndexOf; +export const substring = stringzSubstring; +export const length = stringzLength; +export const toArray = stringzToArray; + +export const padStart = (string: string, targetLength: number, padString?: string) => { + limit(string, targetLength, padString, 'left'); +}; + +export const padEnd = (string: string, targetLength: number, padString?: string) => { + limit(string, targetLength, padString, 'right'); +}; + +export const normalize = (string: string, form: 'NFC' | 'NFD' | 'none' = 'NFC') => { + const upperCaseForm = form.toUpperCase(); + if (upperCaseForm === 'NONE') { + return string; + } + return string.normalize(upperCaseForm); +}; diff --git a/src/extension-host/extension-host.ts b/src/extension-host/extension-host.ts index 357c32c8c9..80aa2683b1 100644 --- a/src/extension-host/extension-host.ts +++ b/src/extension-host/extension-host.ts @@ -7,7 +7,7 @@ import logger from '@shared/services/logger.service'; import networkObjectService from '@shared/services/network-object.service'; import dataProviderService from '@shared/services/data-provider.service'; import extensionAssetService from '@shared/services/extension-asset.service'; -import { getErrorMessage } from 'platform-bible-utils'; +import { getErrorMessage, substring } from 'platform-bible-utils'; import { CommandNames } from 'papi-shared-types'; import { startProjectLookupService } from '@extension-host/services/project-lookup.service-host'; import { registerCommand } from '@shared/services/command.service'; @@ -80,7 +80,7 @@ networkService getVerse: async () => { try { const exampleData = await (await papiFetch('https://www.example.com')).text(); - const results = `testExtensionHost got data: ${exampleData.substring(0, 100)}`; + const results = `testExtensionHost got data: ${substring(exampleData, 0, 100)}`; logger.debug(results); return results; } catch (e) { diff --git a/src/main/services/extension-asset-protocol.service.ts b/src/main/services/extension-asset-protocol.service.ts index 614dcff608..7f58a89ca3 100644 --- a/src/main/services/extension-asset-protocol.service.ts +++ b/src/main/services/extension-asset-protocol.service.ts @@ -1,6 +1,7 @@ import { protocol } from 'electron'; import { StatusCodes } from 'http-status-codes'; import extensionAssetService from '@shared/services/extension-asset.service'; +import { indexOf, substring } from 'platform-bible-utils'; /** Here some of the most common MIME types that we expect to handle */ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types @@ -31,7 +32,7 @@ const knownMimeTypes = { function getMimeTypeForFileName(fileName: string): string { const dotIndex = fileName.lastIndexOf('.'); if (dotIndex > 0) { - const fileType: string = fileName.substring(dotIndex); + const fileType: string = substring(fileName, dotIndex); // Assert key type confirmed in check. // eslint-disable-next-line no-type-assertion/no-type-assertion if (fileType in knownMimeTypes) return knownMimeTypes[fileType as keyof typeof knownMimeTypes]; @@ -67,16 +68,16 @@ const initialize = () => { // 2) Use request headers to pass along the extension name so extension code doesn't have to embed its name in URLs. // Remove "papi-extension://" from the front of the URL - const uri: string = request.url.substring(`${protocolName}://`.length); + const uri: string = substring(request.url, `${protocolName}://`.length); // There have to be at least 2 parts to the URI divided by a slash if (!uri.includes('/')) { return errorResponse(request.url, StatusCodes.BAD_REQUEST); } - const slash = uri.indexOf('/'); - let extension = uri.substring(0, slash); - let asset = uri.substring(slash + 1); + const slash = indexOf(uri, '/'); + let extension = substring(uri, 0, slash); + let asset = substring(uri, slash + 1); if (!extension || !asset) { return errorResponse(request.url, StatusCodes.BAD_REQUEST); } diff --git a/src/renderer/services/web-view.service-host.ts b/src/renderer/services/web-view.service-host.ts index e0eb013763..4b053b1dd7 100644 --- a/src/renderer/services/web-view.service-host.ts +++ b/src/renderer/services/web-view.service-host.ts @@ -12,6 +12,8 @@ import { serialize, isString, newGuid, + indexOf, + substring, } from 'platform-bible-utils'; import { newNonce } from '@shared/utils/util'; import { createNetworkEventEmitter } from '@shared/services/network.service'; @@ -1039,16 +1041,16 @@ export const getWebView = async ( ">`; // Add a script at the start of the head to give access to papi - const headStart = webViewContent.indexOf('', headStart); + const headStart = indexOf(webViewContent, '', headStart); // Inject the CSP and import scripts into the html if it is not a URL iframe if (contentType !== WebViewContentType.URL) - webViewContent = `${webViewContent.substring(0, headEnd + 1)} + webViewContent = `${substring(webViewContent, 0, headEnd + 1)} ${contentSecurityPolicy} ${webViewContent.substring(headEnd + 1)}`; + ${substring(webViewContent, headEnd + 1)}`; const updatedWebView: WebViewTabProps = { ...webView, diff --git a/src/shared/models/data-provider.model.ts b/src/shared/models/data-provider.model.ts index 5eeb2f520c..da09dcd401 100644 --- a/src/shared/models/data-provider.model.ts +++ b/src/shared/models/data-provider.model.ts @@ -1,4 +1,4 @@ -import { UnsubscriberAsync, PlatformEventHandler } from 'platform-bible-utils'; +import { UnsubscriberAsync, PlatformEventHandler, substring } from 'platform-bible-utils'; import { NetworkableObject } from '@shared/models/network-object.model'; /** Various options to adjust how the data provider subscriber emits updates */ @@ -235,7 +235,7 @@ export function getDataProviderDataTypeFromFunctionName< // Assert the expected return type. // eslint-disable-next-line no-type-assertion/no-type-assertion - return fnName.substring(fnPrefix.length) as DataTypeNames; + return substring(fnName, fnPrefix.length) as DataTypeNames; } export default DataProviderInternal; diff --git a/src/shared/services/network.service.ts b/src/shared/services/network.service.ts index aa15d2692b..e512ec206a 100644 --- a/src/shared/services/network.service.ts +++ b/src/shared/services/network.service.ts @@ -20,6 +20,7 @@ import { wait, PlatformEventEmitter, PlatformEvent, + indexOf, } from 'platform-bible-utils'; import { ComplexRequest, @@ -140,7 +141,7 @@ type RoutedRequestHandler = function validateCommandFormatting(commandName: string) { if (!commandName) throw new Error(`Invalid command name ${commandName}: must be a non-empty string`); - const periodIndex = commandName.indexOf('.'); + const periodIndex = indexOf(commandName, '.'); if (periodIndex < 0) throw new Error(`Invalid command name ${commandName}: must have at least one period`); if (periodIndex === 0) diff --git a/src/shared/utils/util.ts b/src/shared/utils/util.ts index ed7663eb40..33f793c9fe 100644 --- a/src/shared/utils/util.ts +++ b/src/shared/utils/util.ts @@ -1,5 +1,5 @@ import { ProcessType } from '@shared/global-this.model'; -import { UnsubscriberAsync, isString } from 'platform-bible-utils'; +import { UnsubscriberAsync, indexOf, isString, substring } from 'platform-bible-utils'; const NONCE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; const NONCE_CHARS_LENGTH = NONCE_CHARS.length; @@ -174,13 +174,13 @@ export function serializeRequestType(category: string, directive: string): Seria export function deserializeRequestType(requestType: SerializedRequestType): RequestType { if (!requestType) throw new Error('deserializeRequestType: must be a non-empty string'); - const colonIndex = requestType.indexOf(REQUEST_TYPE_SEPARATOR); + const colonIndex = indexOf(requestType, REQUEST_TYPE_SEPARATOR); if (colonIndex <= 0 || colonIndex >= requestType.length - 1) throw new Error( `deserializeRequestType: Must have two parts divided by a ${REQUEST_TYPE_SEPARATOR} (${requestType})`, ); - const category = requestType.substring(0, colonIndex); - const directive = requestType.substring(colonIndex + 1); + const category = substring(requestType, 0, colonIndex); + const directive = substring(requestType, colonIndex + 1); return { category, directive }; } From a79d4c3956ca69dffa0b28740c6dae34835b8474 Mon Sep 17 00:00:00 2001 From: Jolie Rabideau Date: Wed, 14 Feb 2024 11:04:11 -0500 Subject: [PATCH 02/22] function declarations, create test file --- .../src/string-util.test.ts | 0 lib/platform-bible-utils/src/string-util.ts | 139 ++++++++++++++++-- 2 files changed, 129 insertions(+), 10 deletions(-) create mode 100644 lib/platform-bible-utils/src/string-util.test.ts diff --git a/lib/platform-bible-utils/src/string-util.test.ts b/lib/platform-bible-utils/src/string-util.test.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lib/platform-bible-utils/src/string-util.ts b/lib/platform-bible-utils/src/string-util.ts index 5a4e0ba088..b4c8571e92 100644 --- a/lib/platform-bible-utils/src/string-util.ts +++ b/lib/platform-bible-utils/src/string-util.ts @@ -6,23 +6,142 @@ import { limit, } from 'stringz'; -export const indexOf = stringzIndexOf; -export const substring = stringzSubstring; -export const length = stringzLength; -export const toArray = stringzToArray; +// Note in each JSDOC that we are dealing with Unicode code points instead of UTF-16 character codes -export const padStart = (string: string, targetLength: number, padString?: string) => { +export function indexOf( + string: string, + searchString: string, + position?: number | undefined, +): number { + return stringzIndexOf(string, searchString, position); +} + +export function substring( + string: string, + begin?: number | undefined, + end?: number | undefined, +): string { + return stringzSubstring(string, begin, end); +} + +export function length(string: string): number { + return stringzLength(string); +} + +export function toArray(string: string): string[] { + return stringzToArray(string); +} + +export function padStart(string: string, targetLength: number, padString?: string) { limit(string, targetLength, padString, 'left'); -}; +} -export const padEnd = (string: string, targetLength: number, padString?: string) => { +export function padEnd(string: string, targetLength: number, padString?: string) { limit(string, targetLength, padString, 'right'); -}; +} -export const normalize = (string: string, form: 'NFC' | 'NFD' | 'none' = 'NFC') => { +export function normalize(string: string, form: 'NFC' | 'NFD' | 'none' = 'NFC') { const upperCaseForm = form.toUpperCase(); if (upperCaseForm === 'NONE') { return string; } return string.normalize(upperCaseForm); -}; +} + +/** + * @param string String to index + * @param index Position of the string character to be returned + * @returns New string consisting of single UTF-16 code unit located at the specified offset + */ +export function at(string: string, index: number) { + return ''; +} + +/** + * Always indexes string as a sequence of UTF-16 code units, so it may return lone surrogates + * + * @param string String to index + * @param index Zero-based index of character to be returned + * @returns New string consisting of single UTF-16 code unit at given index + */ +export function charAt(string: string, index: number) { + return ''; +} + +/** + * @param string String to index + * @param index Zero-based index of character to be returned + * @returns Non-negative integer that is the Unicode code point value of the character starting at + * the given index + */ +export function codePointAt(string: string, index: number) { + return 0; +} + +/** + * Determines whether a string ends with the characters of this string + * + * @param string String to search through + * @param searchString Characters to search for at the end of the string + * @param endPosition [length(string)] End position where searchString is expected to be found + * @returns True if it ends with searchString, false if it does not + */ +export function endsWith( + string: string, + searchString: string, + endPosition: number = length(string), +) { + return true; +} + +/** + * Case-sensitive search to determine if searchString is found in string + * + * @param string String to search through + * @param searchString String to search for, cannot be regex + * @param position [0] position within the string to start searching for searchString + * @returns True if search string is found, false if it is not + */ +export function includes(string: string, searchString: string, position: number = 0) { + return true; +} + +/** + * @param string String to index + * @param searchString + * @param position + * @returns + */ +export function lastIndexOf( + string: string, + searchString: string, + position: number = +Infinity, +): number { + return 0; +} + +/** + * @param indexStart The index of the first character to include in the returned substring. + * @param indexEnd The index of the first character to exclude from the returned substring + * @returns A new string containing the extracted section of the string. + */ +export function slice(indexStart: number, indexEnd?: number): string { + return ''; +} + +// Fix separator type +export function split(separator: string, limit: number): string { + return ''; +} + +/** + * @param string String to search through + * @param searchString The characters to be searched for at the start of this string. + * @param position [0] The start position at which searchString is expected to be found (the index + * of searchString's first character). + * @returns True if the given characters are found at the beginning of the string, including when + * searchString is an empty string; otherwise, false. + */ +export function startsWith(string: string, searchString: string, position: number = 0): boolean { + return true; +} From 07e5b16172cf5c18a0c4bc7545132b0f7688337b Mon Sep 17 00:00:00 2001 From: Jolie Rabideau Date: Wed, 14 Feb 2024 12:24:10 -0500 Subject: [PATCH 03/22] implementing functions, starting unit tests --- .../src/string-util.test.ts | 14 ++ lib/platform-bible-utils/src/string-util.ts | 138 ++++++++++++++---- 2 files changed, 120 insertions(+), 32 deletions(-) diff --git a/lib/platform-bible-utils/src/string-util.test.ts b/lib/platform-bible-utils/src/string-util.test.ts index e69de29bb2..1d633d9b42 100644 --- a/lib/platform-bible-utils/src/string-util.test.ts +++ b/lib/platform-bible-utils/src/string-util.test.ts @@ -0,0 +1,14 @@ +import { indexOf } from './string-util'; + +const STRING_TO_TEST = + 'This is a really long string to test our functions with. It is really long.'; + +test('indexOf without position', () => { + const result = indexOf(STRING_TO_TEST, 'really'); + expect(result).toEqual(10); +}); + +test('indexOf with position', () => { + const result = indexOf(STRING_TO_TEST, 'really', 20); + expect(result).toEqual(63); +}); diff --git a/lib/platform-bible-utils/src/string-util.ts b/lib/platform-bible-utils/src/string-util.ts index b4c8571e92..7952c24372 100644 --- a/lib/platform-bible-utils/src/string-util.ts +++ b/lib/platform-bible-utils/src/string-util.ts @@ -4,10 +4,20 @@ import { length as stringzLength, toArray as stringzToArray, limit, + substr, } from 'stringz'; -// Note in each JSDOC that we are dealing with Unicode code points instead of UTF-16 character codes +// TODO: Note in each JSDOC that we are dealing with Unicode code points instead of UTF-16 character codes +// TODO: Overloads +/** + * Returns the index of the first occurrence of a given string + * + * @param string String to index + * @param searchString String to search for + * @param position The starting position + * @returns Index of the first occurrence of a given string + */ export function indexOf( string: string, searchString: string, @@ -16,6 +26,14 @@ export function indexOf( return stringzIndexOf(string, searchString, position); } +/** + * Returns a substring by providing start and end position + * + * @param string String from which substring will be extracted + * @param begin Starting position + * @param end Ending position + * @returns Substring of the starting string + */ export function substring( string: string, begin?: number | undefined, @@ -24,23 +42,55 @@ export function substring( return stringzSubstring(string, begin, end); } +/** + * Returns the length of a string + * + * @param string String from which size will be calculated + * @returns Number that is length of the starting string + */ export function length(string: string): number { return stringzLength(string); } +/** + * Converts a string to an array of string characters + * + * @param string String to turn into array + * @returns An array of characters from the starting string + */ export function toArray(string: string): string[] { return stringzToArray(string); } -export function padStart(string: string, targetLength: number, padString?: string) { - limit(string, targetLength, padString, 'left'); +/** + * Pads this string with another string (multiple times, if needed) until the resulting string + * reaches the given length. The padding is applied from the start of this string. + * + * @param string String to add padding too + * @param targetLength The length of the resulting string once the starting string has been padded + * @param padString The string to pad the current string with + * @returns String with appropriate padding at the start + */ +export function padStart(string: string, targetLength: number, padString?: string): string { + return limit(string, targetLength, padString, 'left'); } -export function padEnd(string: string, targetLength: number, padString?: string) { - limit(string, targetLength, padString, 'right'); +/** + * Pads this string with another string (multiple times, if needed) until the resulting string + * reaches the given length. The padding is applied from the end of this string. + * + * @param string String to add padding too + * @param targetLength The length of the resulting string once the starting string has been padded + * @param padString The string to pad the current string with + * @returns String with appropriate padding at the end + */ +export function padEnd(string: string, targetLength: number, padString?: string): string { + return limit(string, targetLength, padString, 'right'); } -export function normalize(string: string, form: 'NFC' | 'NFD' | 'none' = 'NFC') { +// TODO: Want to override, but getting an error that it isn't compatible +// export function normalize(string: string, form?: string): string; +export function normalize(string: string, form: 'NFC' | 'NFD' | 'none' = 'NFC'): string { const upperCaseForm = form.toUpperCase(); if (upperCaseForm === 'NONE') { return string; @@ -49,33 +99,36 @@ export function normalize(string: string, form: 'NFC' | 'NFD' | 'none' = 'NFC') } /** + * Always indexes string as a sequence of Unicode code points + * * @param string String to index * @param index Position of the string character to be returned - * @returns New string consisting of single UTF-16 code unit located at the specified offset + * @returns New string consisting of the Unicode code point located at the specified offset */ -export function at(string: string, index: number) { - return ''; +export function at(string: string, index: number): string { + return substr(string, index, 1); } +// TODO: Is this all we need to do here? /** - * Always indexes string as a sequence of UTF-16 code units, so it may return lone surrogates + * Always indexes string as a sequence of Unicode code points * * @param string String to index - * @param index Zero-based index of character to be returned - * @returns New string consisting of single UTF-16 code unit at given index + * @param index Position of the string character to be returned + * @returns New string consisting of the Unicode code point located at the specified offset */ -export function charAt(string: string, index: number) { - return ''; +export function charAt(string: string, index: number): string { + return at(string, index); } +// TODO: Is this all we need to do here? /** * @param string String to index - * @param index Zero-based index of character to be returned - * @returns Non-negative integer that is the Unicode code point value of the character starting at - * the given index + * @param index Position of the string character to be returned + * @returns New string consisting of the Unicode code point located at the specified offset */ export function codePointAt(string: string, index: number) { - return 0; + return at(string, index); } /** @@ -90,7 +143,10 @@ export function endsWith( string: string, searchString: string, endPosition: number = length(string), -) { +): boolean { + const lastIndexOfSearchString = lastIndexOf(string, searchString); + if (lastIndexOfSearchString === -1) return false; + if (lastIndexOfSearchString + length(searchString) !== endPosition) return false; return true; } @@ -102,22 +158,39 @@ export function endsWith( * @param position [0] position within the string to start searching for searchString * @returns True if search string is found, false if it is not */ -export function includes(string: string, searchString: string, position: number = 0) { +export function includes(string: string, searchString: string, position: number = 0): boolean { + const partialString = substring(string, position); + const indexOfSearchString = indexOf(partialString, searchString); + if (indexOfSearchString === -1) return false; return true; } /** * @param string String to index - * @param searchString + * @param searchString Substring to search for. * @param position - * @returns + * @returns The index of the last occurrence of searchString found, or -1 if not found. */ export function lastIndexOf( string: string, searchString: string, position: number = +Infinity, ): number { - return 0; + let validatedPosition = position; + + if (validatedPosition < 0) { + validatedPosition = 0; + } else if (validatedPosition >= length(string)) { + validatedPosition = length(string) - 1; + } + + for (let index = validatedPosition; index >= 0; index--) { + if (substr(string, index, length(searchString)) === searchString) { + return index; + } + } + + return -1; } /** @@ -125,15 +198,16 @@ export function lastIndexOf( * @param indexEnd The index of the first character to exclude from the returned substring * @returns A new string containing the extracted section of the string. */ -export function slice(indexStart: number, indexEnd?: number): string { - return ''; +export function slice(string: string, indexStart: number, indexEnd?: number): string { + return substring(string, indexStart, indexEnd); } -// Fix separator type -export function split(separator: string, limit: number): string { - return ''; -} +// TODO: Fix separator type, implement +// export function split(separator: string, limit: number): string { +// return ''; +// } +// TODO: Implement /** * @param string String to search through * @param searchString The characters to be searched for at the start of this string. @@ -142,6 +216,6 @@ export function split(separator: string, limit: number): string { * @returns True if the given characters are found at the beginning of the string, including when * searchString is an empty string; otherwise, false. */ -export function startsWith(string: string, searchString: string, position: number = 0): boolean { - return true; -} +// export function startsWith(string: string, searchString: string, position: number = 0): boolean { +// return true; +// } From 4339da67c76737a30d3a3863fcdc998654359fd5 Mon Sep 17 00:00:00 2001 From: Jolie Rabideau Date: Wed, 14 Feb 2024 21:57:07 -0500 Subject: [PATCH 04/22] implement unit tests and startsWith --- lib/platform-bible-utils/src/index.ts | 17 +- .../src/string-util.test.ts | 186 +++++++++++++++++- lib/platform-bible-utils/src/string-util.ts | 17 +- 3 files changed, 202 insertions(+), 18 deletions(-) diff --git a/lib/platform-bible-utils/src/index.ts b/lib/platform-bible-utils/src/index.ts index 7572d14944..e6c94f4935 100644 --- a/lib/platform-bible-utils/src/index.ts +++ b/lib/platform-bible-utils/src/index.ts @@ -30,7 +30,22 @@ export { getAllObjectFunctionNames, createSyncProxyForAsyncObject, } from './util'; -export { indexOf, substring, length, toArray, padStart, padEnd, normalize } from './string-util'; +export { + indexOf, + substring, + length, + toArray, + padStart, + padEnd, + normalize, + at, + charAt, + codePointAt, + endsWith, + includes, + lastIndexOf, + slice, +} from './string-util'; export { default as deepEqual } from './equality-checking'; export { serialize, deserialize, isSerializable, htmlEncode } from './serialization'; diff --git a/lib/platform-bible-utils/src/string-util.test.ts b/lib/platform-bible-utils/src/string-util.test.ts index 1d633d9b42..15cc06ddf7 100644 --- a/lib/platform-bible-utils/src/string-util.test.ts +++ b/lib/platform-bible-utils/src/string-util.test.ts @@ -1,14 +1,182 @@ -import { indexOf } from './string-util'; +import { + indexOf, + substring, + length, + toArray, + padStart, + padEnd, + normalize, + at, + charAt, + codePointAt, + endsWith, + includes, + lastIndexOf, + startsWith, +} from './string-util'; -const STRING_TO_TEST = - 'This is a really long string to test our functions with. It is really long.'; +const TEST_STRING = 'This is a really really cool string'; +const POS_FIRST_REALLY = 10; +const POS_SECOND_REALLY = 17; +const TEST_STRING_LENGTH = 35; -test('indexOf without position', () => { - const result = indexOf(STRING_TO_TEST, 'really'); - expect(result).toEqual(10); +const TO_ARRAY_TEST_STRING = 'Hello'; +const TO_ARRAY_TEST_ARRAY = ['H', 'e', 'l', 'l', 'o']; +const TO_ARRAY_TEST_STRING_LENGTH = 5; + +describe('indexOf', () => { + test('indexOf without position', () => { + const result = indexOf(TEST_STRING, 'really'); + expect(result).toEqual(POS_FIRST_REALLY); + }); + + test('indexOf with position', () => { + const result = indexOf(TEST_STRING, 'really', 12); + expect(result).toEqual(POS_SECOND_REALLY); + }); +}); + +describe('substring', () => { + test('substring with begin', () => { + const result = substring(TEST_STRING, POS_FIRST_REALLY); + expect(result).toEqual('really really cool string'); + }); + + test('substring with end', () => { + const result = substring(TEST_STRING, undefined, POS_FIRST_REALLY); + expect(result).toEqual('This is a '); + }); + + test('substring with begin and end', () => { + const result = substring(TEST_STRING, POS_FIRST_REALLY, POS_SECOND_REALLY); + expect(result).toEqual('really '); + }); +}); + +describe('length', () => { + test('length is correct', () => { + const result = length(TEST_STRING); + expect(result).toEqual(TEST_STRING_LENGTH); + }); +}); + +describe('toArray', () => { + test('toArray returns correct array', () => { + const result = toArray(TO_ARRAY_TEST_STRING); + expect(result).toEqual(TO_ARRAY_TEST_ARRAY); + }); +}); + +describe('padStart', () => { + test('padStart without padString', () => { + const result = padStart(TO_ARRAY_TEST_STRING, TO_ARRAY_TEST_STRING_LENGTH + 10, undefined); + expect(result).toEqual(`##########${TO_ARRAY_TEST_STRING}`); + }); + + // It expects 10 'ha' but it should only give 5 'ha' because that would be length 10 + // ('padStart with padString', () => { + // const result = padStart(TEST_STRING, TEST_STRING_LENGTH + 10, 'ha'); + // expect(result).toEqual(`hahahahaha${TEST_STRING}`); + // }); +}); + +describe('padEnd', () => { + test('padEnd without padString', () => { + const result = padEnd(TEST_STRING, TEST_STRING_LENGTH + 10, undefined); + expect(result).toEqual(`${TEST_STRING}##########`); + }); + + // It expects 10 'ha' but it should only give 5 'ha' because that would be length 10 + // ('padEnd with padString', () => { + // const result = padEnd(TEST_STRING, TEST_STRING_LENGTH + 10, 'ha'); + // expect(result).toEqual(`${TEST_STRING}hahahahaha`); + // }); +}); + +describe('normalize', () => { + test('normalize without form', () => { + const result = normalize(TEST_STRING); + expect(result).toEqual(TEST_STRING); + }); + + test('normalize with form', () => { + const result = normalize(TEST_STRING, 'NFC'); + expect(result).toEqual(TEST_STRING); + }); +}); + +describe('at', () => { + test('at', () => { + const result = at(TEST_STRING, 1); + expect(result).toEqual('h'); + }); +}); + +describe('charAt', () => { + test('charAt', () => { + const result = charAt(TEST_STRING, 1); + expect(result).toEqual('h'); + }); +}); + +describe('codePointAt', () => { + test('codePointAt', () => { + const result = codePointAt(TEST_STRING, 1); + expect(result).toEqual('h'); + }); +}); + +describe('endsWith', () => { + test('endsWith without position', () => { + const result = endsWith(TEST_STRING, 'string'); + expect(result).toEqual(true); + }); + + // Should test what the end is, not what it isn't + test('endsWith with position', () => { + const result = endsWith(TEST_STRING, 'string', 8); + expect(result).toEqual(false); + }); }); -test('indexOf with position', () => { - const result = indexOf(STRING_TO_TEST, 'really', 20); - expect(result).toEqual(63); +describe('includes', () => { + test('includes without position', () => { + const result = includes(TEST_STRING, 'really'); + expect(result).toEqual(true); + }); + + test('includes with position', () => { + const result = includes(TEST_STRING, 'really', 22); + expect(result).toEqual(false); + }); +}); + +describe('lastIndexOf', () => { + test('lastIndexOf without position', () => { + const result = lastIndexOf(TEST_STRING, 'really'); + expect(result).toEqual(POS_SECOND_REALLY); + }); + + // Expecting -1 but returning 17 + // position should set the "start" of the string to 20, there is no 'really' from 20 to the end of the test string + // ('lastIndexOf with position', () => { + // const result = lastIndexOf(TEST_STRING, 'really', 20); + // expect(result).toEqual(-1); + // }); }); + +describe('startsWith', () => { + test('startsWith without position', () => { + const result = startsWith(TEST_STRING, 'This'); + expect(result).toEqual(true); + }); + + // Should test what the end is, not what it isn't + test('startsWith with position', () => { + const result = startsWith(TEST_STRING, 'This', 5); + expect(result).toEqual(false); + }); +}); + +// slice +// split diff --git a/lib/platform-bible-utils/src/string-util.ts b/lib/platform-bible-utils/src/string-util.ts index 7952c24372..3cda347cdd 100644 --- a/lib/platform-bible-utils/src/string-util.ts +++ b/lib/platform-bible-utils/src/string-util.ts @@ -13,10 +13,10 @@ import { /** * Returns the index of the first occurrence of a given string * - * @param string String to index - * @param searchString String to search for - * @param position The starting position - * @returns Index of the first occurrence of a given string + * @param {string} string + * @param {string} [searchString] The string to search + * @param {number} [position] Starting position + * @returns {number} Index of the first occurrence of a given string */ export function indexOf( string: string, @@ -207,7 +207,6 @@ export function slice(string: string, indexStart: number, indexEnd?: number): st // return ''; // } -// TODO: Implement /** * @param string String to search through * @param searchString The characters to be searched for at the start of this string. @@ -216,6 +215,8 @@ export function slice(string: string, indexStart: number, indexEnd?: number): st * @returns True if the given characters are found at the beginning of the string, including when * searchString is an empty string; otherwise, false. */ -// export function startsWith(string: string, searchString: string, position: number = 0): boolean { -// return true; -// } +export function startsWith(string: string, searchString: string, position: number = 0): boolean { + const indexOfSearchString = indexOf(string, searchString, position); + if (indexOfSearchString !== 0) return false; + return true; +} From f3795365e71bd84a8251719f1d95b7ae87930f8a Mon Sep 17 00:00:00 2001 From: Jolie Rabideau Date: Thu, 15 Feb 2024 12:08:26 -0500 Subject: [PATCH 05/22] finish JSDOCs, implement remaining functions, work on unit tests, alphabetize --- cspell.json | 1 + .../src/string-util.test.ts | 191 ++++----- lib/platform-bible-utils/src/string-util.ts | 381 ++++++++++++------ 3 files changed, 355 insertions(+), 218 deletions(-) diff --git a/cspell.json b/cspell.json index 6fe9cc4d3c..55c2839a80 100644 --- a/cspell.json +++ b/cspell.json @@ -47,6 +47,7 @@ "sillsdev", "steenwyk", "stringifiable", + "stringz", "stylelint", "Stylesheet", "typedefs", diff --git a/lib/platform-bible-utils/src/string-util.test.ts b/lib/platform-bible-utils/src/string-util.test.ts index 15cc06ddf7..63a48b782a 100644 --- a/lib/platform-bible-utils/src/string-util.test.ts +++ b/lib/platform-bible-utils/src/string-util.test.ts @@ -1,110 +1,34 @@ import { - indexOf, - substring, - length, - toArray, - padStart, - padEnd, - normalize, at, charAt, codePointAt, endsWith, includes, + indexOf, lastIndexOf, + length, + // limit, + normalize, + padEnd, + padStart, + // slice, + // split, startsWith, + // substr, + substring, + toArray, } from './string-util'; const TEST_STRING = 'This is a really really cool string'; const POS_FIRST_REALLY = 10; const POS_SECOND_REALLY = 17; const TEST_STRING_LENGTH = 35; +const TEN_SPACES = ' '; const TO_ARRAY_TEST_STRING = 'Hello'; const TO_ARRAY_TEST_ARRAY = ['H', 'e', 'l', 'l', 'o']; const TO_ARRAY_TEST_STRING_LENGTH = 5; -describe('indexOf', () => { - test('indexOf without position', () => { - const result = indexOf(TEST_STRING, 'really'); - expect(result).toEqual(POS_FIRST_REALLY); - }); - - test('indexOf with position', () => { - const result = indexOf(TEST_STRING, 'really', 12); - expect(result).toEqual(POS_SECOND_REALLY); - }); -}); - -describe('substring', () => { - test('substring with begin', () => { - const result = substring(TEST_STRING, POS_FIRST_REALLY); - expect(result).toEqual('really really cool string'); - }); - - test('substring with end', () => { - const result = substring(TEST_STRING, undefined, POS_FIRST_REALLY); - expect(result).toEqual('This is a '); - }); - - test('substring with begin and end', () => { - const result = substring(TEST_STRING, POS_FIRST_REALLY, POS_SECOND_REALLY); - expect(result).toEqual('really '); - }); -}); - -describe('length', () => { - test('length is correct', () => { - const result = length(TEST_STRING); - expect(result).toEqual(TEST_STRING_LENGTH); - }); -}); - -describe('toArray', () => { - test('toArray returns correct array', () => { - const result = toArray(TO_ARRAY_TEST_STRING); - expect(result).toEqual(TO_ARRAY_TEST_ARRAY); - }); -}); - -describe('padStart', () => { - test('padStart without padString', () => { - const result = padStart(TO_ARRAY_TEST_STRING, TO_ARRAY_TEST_STRING_LENGTH + 10, undefined); - expect(result).toEqual(`##########${TO_ARRAY_TEST_STRING}`); - }); - - // It expects 10 'ha' but it should only give 5 'ha' because that would be length 10 - // ('padStart with padString', () => { - // const result = padStart(TEST_STRING, TEST_STRING_LENGTH + 10, 'ha'); - // expect(result).toEqual(`hahahahaha${TEST_STRING}`); - // }); -}); - -describe('padEnd', () => { - test('padEnd without padString', () => { - const result = padEnd(TEST_STRING, TEST_STRING_LENGTH + 10, undefined); - expect(result).toEqual(`${TEST_STRING}##########`); - }); - - // It expects 10 'ha' but it should only give 5 'ha' because that would be length 10 - // ('padEnd with padString', () => { - // const result = padEnd(TEST_STRING, TEST_STRING_LENGTH + 10, 'ha'); - // expect(result).toEqual(`${TEST_STRING}hahahahaha`); - // }); -}); - -describe('normalize', () => { - test('normalize without form', () => { - const result = normalize(TEST_STRING); - expect(result).toEqual(TEST_STRING); - }); - - test('normalize with form', () => { - const result = normalize(TEST_STRING, 'NFC'); - expect(result).toEqual(TEST_STRING); - }); -}); - describe('at', () => { test('at', () => { const result = at(TEST_STRING, 1); @@ -122,7 +46,7 @@ describe('charAt', () => { describe('codePointAt', () => { test('codePointAt', () => { const result = codePointAt(TEST_STRING, 1); - expect(result).toEqual('h'); + expect(result).toEqual(104); }); }); @@ -151,6 +75,18 @@ describe('includes', () => { }); }); +describe('indexOf', () => { + test('indexOf without position', () => { + const result = indexOf(TEST_STRING, 'really'); + expect(result).toEqual(POS_FIRST_REALLY); + }); + + test('indexOf with position', () => { + const result = indexOf(TEST_STRING, 'really', 12); + expect(result).toEqual(POS_SECOND_REALLY); + }); +}); + describe('lastIndexOf', () => { test('lastIndexOf without position', () => { const result = lastIndexOf(TEST_STRING, 'really'); @@ -165,6 +101,56 @@ describe('lastIndexOf', () => { // }); }); +describe('length', () => { + test('length is correct', () => { + const result = length(TEST_STRING); + expect(result).toEqual(TEST_STRING_LENGTH); + }); +}); + +// TODO: limit test + +describe('normalize', () => { + test('normalize without form', () => { + const result = normalize(TEST_STRING); + expect(result).toEqual(TEST_STRING); + }); + + test('normalize with form', () => { + const result = normalize(TEST_STRING, 'NFC'); + expect(result).toEqual(TEST_STRING); + }); +}); + +describe('padEnd', () => { + test('padEnd without padString', () => { + const result = padEnd(TEST_STRING, TEST_STRING_LENGTH + 10, undefined); + expect(result).toEqual(TEST_STRING + TEN_SPACES); + }); + + // It expects 10 'ha' but it should only give 5 'ha' because that would be length 10 + // ('padEnd with padString', () => { + // const result = padEnd(TEST_STRING, TEST_STRING_LENGTH + 10, 'ha'); + // expect(result).toEqual(`${TEST_STRING}hahahahaha`); + // }); +}); + +describe('padStart', () => { + test('padStart without padString', () => { + const result = padStart(TO_ARRAY_TEST_STRING, TO_ARRAY_TEST_STRING_LENGTH + 10, undefined); + expect(result).toEqual(TEN_SPACES + TO_ARRAY_TEST_STRING); + }); + + // It expects 10 'ha' but it should only give 5 'ha' because that would be length 10 + // ('padStart with padString', () => { + // const result = padStart(TEST_STRING, TEST_STRING_LENGTH + 10, 'ha'); + // expect(result).toEqual(`hahahahaha${TEST_STRING}`); + // }); +}); + +// TODO: slice test +// TODO: split test + describe('startsWith', () => { test('startsWith without position', () => { const result = startsWith(TEST_STRING, 'This'); @@ -178,5 +164,28 @@ describe('startsWith', () => { }); }); -// slice -// split +// TODO: substr test + +describe('substring', () => { + test('substring with begin', () => { + const result = substring(TEST_STRING, POS_FIRST_REALLY); + expect(result).toEqual('really really cool string'); + }); + + test('substring with end', () => { + const result = substring(TEST_STRING, undefined, POS_FIRST_REALLY); + expect(result).toEqual('This is a '); + }); + + test('substring with begin and end', () => { + const result = substring(TEST_STRING, POS_FIRST_REALLY, POS_SECOND_REALLY); + expect(result).toEqual('really '); + }); +}); + +describe('toArray', () => { + test('toArray returns correct array', () => { + const result = toArray(TO_ARRAY_TEST_STRING); + expect(result).toEqual(TO_ARRAY_TEST_ARRAY); + }); +}); diff --git a/lib/platform-bible-utils/src/string-util.ts b/lib/platform-bible-utils/src/string-util.ts index 3cda347cdd..0483e08002 100644 --- a/lib/platform-bible-utils/src/string-util.ts +++ b/lib/platform-bible-utils/src/string-util.ts @@ -3,109 +3,24 @@ import { substring as stringzSubstring, length as stringzLength, toArray as stringzToArray, - limit, - substr, + limit as stringzLimit, + substr as stringzSubstr, } from 'stringz'; // TODO: Note in each JSDOC that we are dealing with Unicode code points instead of UTF-16 character codes // TODO: Overloads +// TODO: Add npm test to platform-bible-utils build step +// Rolf - I added a commented line with the override to the two functions that I found that needed one: normalize, and split. /** - * Returns the index of the first occurrence of a given string + * Finds the Unicode code point at the given index * - * @param {string} string - * @param {string} [searchString] The string to search - * @param {number} [position] Starting position - * @returns {number} Index of the first occurrence of a given string - */ -export function indexOf( - string: string, - searchString: string, - position?: number | undefined, -): number { - return stringzIndexOf(string, searchString, position); -} - -/** - * Returns a substring by providing start and end position - * - * @param string String from which substring will be extracted - * @param begin Starting position - * @param end Ending position - * @returns Substring of the starting string - */ -export function substring( - string: string, - begin?: number | undefined, - end?: number | undefined, -): string { - return stringzSubstring(string, begin, end); -} - -/** - * Returns the length of a string - * - * @param string String from which size will be calculated - * @returns Number that is length of the starting string - */ -export function length(string: string): number { - return stringzLength(string); -} - -/** - * Converts a string to an array of string characters - * - * @param string String to turn into array - * @returns An array of characters from the starting string - */ -export function toArray(string: string): string[] { - return stringzToArray(string); -} - -/** - * Pads this string with another string (multiple times, if needed) until the resulting string - * reaches the given length. The padding is applied from the start of this string. - * - * @param string String to add padding too - * @param targetLength The length of the resulting string once the starting string has been padded - * @param padString The string to pad the current string with - * @returns String with appropriate padding at the start - */ -export function padStart(string: string, targetLength: number, padString?: string): string { - return limit(string, targetLength, padString, 'left'); -} - -/** - * Pads this string with another string (multiple times, if needed) until the resulting string - * reaches the given length. The padding is applied from the end of this string. - * - * @param string String to add padding too - * @param targetLength The length of the resulting string once the starting string has been padded - * @param padString The string to pad the current string with - * @returns String with appropriate padding at the end - */ -export function padEnd(string: string, targetLength: number, padString?: string): string { - return limit(string, targetLength, padString, 'right'); -} - -// TODO: Want to override, but getting an error that it isn't compatible -// export function normalize(string: string, form?: string): string; -export function normalize(string: string, form: 'NFC' | 'NFD' | 'none' = 'NFC'): string { - const upperCaseForm = form.toUpperCase(); - if (upperCaseForm === 'NONE') { - return string; - } - return string.normalize(upperCaseForm); -} - -/** - * Always indexes string as a sequence of Unicode code points - * - * @param string String to index - * @param index Position of the string character to be returned - * @returns New string consisting of the Unicode code point located at the specified offset + * @param {string} string String to index + * @param {number} index Position of the character to be returned + * @returns {string} New string consisting of the Unicode code point located at the specified offset */ export function at(string: string, index: number): string { + // TODO: Add validation for index? can't be less than 0 or greater than string length return substr(string, index, 1); } @@ -115,7 +30,7 @@ export function at(string: string, index: number): string { * * @param string String to index * @param index Position of the string character to be returned - * @returns New string consisting of the Unicode code point located at the specified offset + * @returns {string} New string consisting of the Unicode code point located at the specified offset */ export function charAt(string: string, index: number): string { return at(string, index); @@ -123,21 +38,29 @@ export function charAt(string: string, index: number): string { // TODO: Is this all we need to do here? /** - * @param string String to index - * @param index Position of the string character to be returned - * @returns New string consisting of the Unicode code point located at the specified offset + * Returns a non-negative integer that is the Unicode code point value of the character starting at + * the given index. This function handles Unicode code points instead of UTF-16 character codes. + * + * @param {string} string String to index + * @param {number} index Position of the string character to be returned + * @returns {number | undefined} Non-negative integer representing the code point value of the + * character at the given index, or undefined if there is no element at that position */ -export function codePointAt(string: string, index: number) { - return at(string, index); +export function codePointAt(string: string, index: number): number | undefined { + // TODO: validation for index? + const character = at(string, index); + return character.codePointAt(0); } /** - * Determines whether a string ends with the characters of this string + * Determines whether a string ends with the characters of this string. This function handles + * Unicode code points instead of UTF-16 character codes. * - * @param string String to search through - * @param searchString Characters to search for at the end of the string - * @param endPosition [length(string)] End position where searchString is expected to be found - * @returns True if it ends with searchString, false if it does not + * @param {string} string String to search through + * @param {string} searchString Characters to search for at the end of the string + * @param {number} [endPosition=length(string)] End position where searchString is expected to be + * found. Default is `length(string)` + * @returns {boolean} True if it ends with searchString, false if it does not */ export function endsWith( string: string, @@ -151,12 +74,14 @@ export function endsWith( } /** - * Case-sensitive search to determine if searchString is found in string + * Performs a case-sensitive search to determine if searchString is found in string. This function + * handles Unicode code points instead of UTF-16 character codes. * - * @param string String to search through - * @param searchString String to search for, cannot be regex - * @param position [0] position within the string to start searching for searchString - * @returns True if search string is found, false if it is not + * @param {string} string String to search through + * @param {string} searchString String to search for + * @param {string} [position=0] Position within the string to start searching for searchString. + * Default is `0` + * @returns {boolean} True if search string is found, false if it is not */ export function includes(string: string, searchString: string, position: number = 0): boolean { const partialString = substring(string, position); @@ -166,10 +91,31 @@ export function includes(string: string, searchString: string, position: number } /** - * @param string String to index - * @param searchString Substring to search for. - * @param position - * @returns The index of the last occurrence of searchString found, or -1 if not found. + * Returns the index of the first occurrence of a given string. This function handles Unicode code + * points instead of UTF-16 character codes. + * + * @param {string} string String to search through + * @param {string} searchString The string to search for + * @param {number} [position=0] Start of searching. Default is `0` + * @returns {number} Index of the first occurrence of a given string + */ +export function indexOf( + string: string, + searchString: string, + position: number | undefined = 0, +): number { + return stringzIndexOf(string, searchString, position); +} + +/** + * Searches this string and returns the index of the last occurrence of the specified substring. + * This function handles Unicode code points instead of UTF-16 character codes. + * + * @param {string} string String to search through + * @param {string} searchString Substring to search for + * @param {number} [position=+Infinity] The method returns the index of the last occurrence of the + * specified substring at a position less than or equal to position. . Default is `+Infinity` + * @returns {number} Index of the last occurrence of searchString found, or -1 if not found. */ export function lastIndexOf( string: string, @@ -194,29 +140,210 @@ export function lastIndexOf( } /** - * @param indexStart The index of the first character to include in the returned substring. - * @param indexEnd The index of the first character to exclude from the returned substring - * @returns A new string containing the extracted section of the string. + * Returns the length of a string. This function handles Unicode code points instead of UTF-16 + * character codes. + * + * @param {string} string String to return the length for + * @returns Number that is length of the starting string + */ +export function length(string: string): number { + return stringzLength(string); +} + +// TODO: test +/** + * Limits a string to a given width. This function handles Unicode code points instead of UTF-16 + * character codes. + * + * @param {string} string The string to be limited + * @param {number} [padLimit=16] Desired string length. Default is `16` + * @param {string} [padString=' '] Character to pad the output with. Default is `' '` + * @param {'right' | 'left'} [padPosition='right'] The pad position: 'right' or 'left'. Default is + * `'right'` + * @returns {string} String limited to the given width with the padString provided + */ +export function limit( + string: string, + padLimit: number = 16, + padString: string = ' ', + padPosition: 'right' | 'left' = 'right', +): string { + return stringzLimit(string, padLimit, padString, padPosition); +} + +// TODO: Want to override, but getting an error that it isn't compatible +// export function normalize(string: string, form?: string): string; +/** + * Returns the Unicode Normalization Form of this string. + * + * @param {string} string The starting string + * @param {'NFC' | 'NFD' | 'none'} [form='NFC'] Form specifying the Unicode Normalization Form. + * Default is `'NFC'` + * @returns {string} A string containing the Unicode Normalization Form of the given string. + */ +export function normalize(string: string, form: 'NFC' | 'NFD' | 'none' = 'NFC'): string { + const upperCaseForm = form.toUpperCase(); + if (upperCaseForm === 'NONE') { + return string; + } + return string.normalize(upperCaseForm); +} + +/** + * Pads this string with another string (multiple times, if needed) until the resulting string + * reaches the given length. The padding is applied from the end of this string. This function + * handles Unicode code points instead of UTF-16 character codes. + * + * @param {string} string String to add padding too + * @param {number} targetLength The length of the resulting string once the starting string has been + * padded. If value is less than or equal to length(string), then string is returned as is. + * @param {string} [padString=" "] The string to pad the current string with. If padString is too + * long to stay within targetLength, it will be truncated. Default is `" "` + * @returns {string} String with appropriate padding at the end + */ +export function padEnd(string: string, targetLength: number, padString: string = ' '): string { + if (targetLength <= length(string)) return string; + return limit(string, targetLength, padString, 'right'); +} + +/** + * Pads this string with another string (multiple times, if needed) until the resulting string + * reaches the given length. The padding is applied from the start of this string. This function + * handles Unicode code points instead of UTF-16 character codes. + * + * @param {string} string String to add padding too + * @param {number} targetLength The length of the resulting string once the starting string has been + * padded. If value is less than or equal to length(string), then string is returned as is. + * @param {string} [padString=" "] The string to pad the current string with. If padString is too + * long to stay within the targetLength, it will be truncated from the end. Default is `" "` + * @returns String with of specified targetLength with padString applied from the start + */ +export function padStart(string: string, targetLength: number, padString: string = ' '): string { + if (targetLength <= length(string)) return string; + return limit(string, targetLength, padString, 'left'); +} + +/** + * Extracts a section of this string and returns it as a new string, without modifying the original + * string. This function handles Unicode code points instead of UTF-16 character codes. + * + * @param {string} string The starting string + * @param {number} indexStart The index of the first character to include in the returned substring. + * @param {number} indexEnd The index of the first character to exclude from the returned substring. + * @returns {string} A new string containing the extracted section of the string. */ export function slice(string: string, indexStart: number, indexEnd?: number): string { return substring(string, indexStart, indexEnd); } -// TODO: Fix separator type, implement -// export function split(separator: string, limit: number): string { -// return ''; -// } +// TODO: Test, overload for separator type +// split(splitter: { [Symbol.split](string: string, limit?: number): string[]; }, limit?: number): string[]; +/** + * Takes a pattern and divides the string into an ordered list of substrings by searching for the + * pattern, puts these substrings into an array, and returns the array. This function handles + * Unicode code points instead of UTF-16 character codes. + * + * @param {string} string The string to split + * @param {string | RegExp} separator The pattern describing where each split should occur + * @param {number} splitLimit Limit on the number of substrings to be included in the array. Splits + * the string at each occurrence of specified separator, but stops when limit entries have been + * placed in the array. + * @returns {string[]} An array of strings, split at each point where separator occurs in the + * starting string. + */ +export function split(string: string, separator: string | RegExp, splitLimit?: number): string[] { + const result: string[] = []; + + if (splitLimit === undefined || splitLimit <= 0) { + return [string]; // Return the whole string if limit is not provided or invalid + } + + let currentIndex = 0; + let match: RegExpMatchArray | null; + + match = substr(string, currentIndex).match(separator); + // match() returns either RegExpMatchArray or null + // eslint-disable-next-line no-null/no-null + while (match !== null) { + const matchIndex = match.index ?? 0; + const matchLength = match[0].length; + + result.push(substr(string, currentIndex, matchIndex)); + currentIndex += matchIndex + matchLength; + + if (result.length === splitLimit - 1) { + break; // Reached the specified limit + } + + match = substr(string, currentIndex).match(separator); + } + + result.push(substr(string, currentIndex)); // Add the remaining part of the string + + return result; +} /** - * @param string String to search through - * @param searchString The characters to be searched for at the start of this string. - * @param position [0] The start position at which searchString is expected to be found (the index - * of searchString's first character). - * @returns True if the given characters are found at the beginning of the string, including when - * searchString is an empty string; otherwise, false. + * Determines whether the string begins with the characters of a specified string, returning true or + * false as appropriate. This function handles Unicode code points instead of UTF-16 character + * codes. + * + * @param {string} string String to search through + * @param {string} searchString The characters to be searched for at the start of this string. + * @param {number} [position=0] The start position at which searchString is expected to be found + * (the index of searchString's first character). Default is `0` + * @returns {boolean} True if the given characters are found at the beginning of the string, + * including when searchString is an empty string; otherwise, false. */ export function startsWith(string: string, searchString: string, position: number = 0): boolean { const indexOfSearchString = indexOf(string, searchString, position); if (indexOfSearchString !== 0) return false; return true; } + +// TODO: test +/** + * Returns a substring by providing start and length. This function handles Unicode code points + * instead of UTF-16 character codes. + * + * @param {string} string String to be divided + * @param {number} [begin=Start of string] Start position. Default is `Start of string` + * @param {number} [len=String length minus start parameter] Length of result. Default is `String + * length minus start parameter`. Default is `String length minus start parameter` + * @returns {string} Substring from starting string + */ +export function substr( + string: string, + begin: number = 0, + len: number = length(string) - begin, +): string { + return stringzSubstr(string, begin, len); +} + +/** + * Returns a substring by providing start and end position. This function handles Unicode code + * points instead of UTF-16 character codes. + * + * @param {string} string String to be divided + * @param {string} begin Start position + * @param {number} [end=End of string] End position. Default is `End of string` + * @returns {string} Substring from starting string + */ +export function substring( + string: string, + begin?: number | undefined, + end: number | undefined = length(string), +): string { + return stringzSubstring(string, begin, end); +} + +/** + * Converts a string to an array of string characters. This function handles Unicode code points + * instead of UTF-16 character codes. + * + * @param {string} string String to convert to array + * @returns {string[]} An array of characters from the starting string + */ +export function toArray(string: string): string[] { + return stringzToArray(string); +} From fa9c937fa13faa3b9a36f74e83fced26288bf8b2 Mon Sep 17 00:00:00 2001 From: Rolf Heij Date: Thu, 15 Feb 2024 15:50:28 -0500 Subject: [PATCH 06/22] Reworking tests --- lib/platform-bible-utils/package.json | 2 +- .../src/string-util.test.ts | 57 ++++++++++--------- lib/platform-bible-utils/src/string-util.ts | 1 - 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/lib/platform-bible-utils/package.json b/lib/platform-bible-utils/package.json index 11e2250303..f060b02a74 100644 --- a/lib/platform-bible-utils/package.json +++ b/lib/platform-bible-utils/package.json @@ -32,7 +32,7 @@ "start": "vite --host --open", "build:basic": "tsc && vite build && dts-bundle-generator --config ./dts-bundle-generator.config.ts", "build:docs": "npm install && typedoc", - "build": "npm run build:basic && npm run lint-fix", + "build": "npm run build:basic && npm run lint-fix && npm run test", "watch": "tsc && vite build --watch", "lint": "npm run lint:scripts", "lint:scripts": "cross-env NODE_ENV=development eslint --ext .cjs,.js,.jsx,.ts,.tsx --cache .", diff --git a/lib/platform-bible-utils/src/string-util.test.ts b/lib/platform-bible-utils/src/string-util.test.ts index 63a48b782a..9766ed1590 100644 --- a/lib/platform-bible-utils/src/string-util.test.ts +++ b/lib/platform-bible-utils/src/string-util.test.ts @@ -19,7 +19,9 @@ import { toArray, } from './string-util'; -const TEST_STRING = 'This is a really really cool string'; +const SURROGATE_PAIRS_STRING = +'Look𐐷At🦄All😎These😁Awesome🍕Symbols💩That🚀Are📷Represented😉By👌Surrogate🔥Pairs💋!🌟'; +const TEXT_STRING = 'This is a really really cool string'; const POS_FIRST_REALLY = 10; const POS_SECOND_REALLY = 17; const TEST_STRING_LENGTH = 35; @@ -31,65 +33,64 @@ const TO_ARRAY_TEST_STRING_LENGTH = 5; describe('at', () => { test('at', () => { - const result = at(TEST_STRING, 1); - expect(result).toEqual('h'); + const result = at(SURROGATE_PAIRS_STRING, 4); + expect(result).toEqual('𐐷'); }); }); describe('charAt', () => { test('charAt', () => { - const result = charAt(TEST_STRING, 1); - expect(result).toEqual('h'); + const result = charAt(SURROGATE_PAIRS_STRING, 7); + expect(result).toEqual('🦄'); }); }); describe('codePointAt', () => { test('codePointAt', () => { - const result = codePointAt(TEST_STRING, 1); - expect(result).toEqual(104); + const result = codePointAt(SURROGATE_PAIRS_STRING, 11); + expect(result).toEqual(128526); }); }); describe('endsWith', () => { test('endsWith without position', () => { - const result = endsWith(TEST_STRING, 'string'); + const result = endsWith(SURROGATE_PAIRS_STRING, '💋!🌟'); expect(result).toEqual(true); }); - // Should test what the end is, not what it isn't test('endsWith with position', () => { - const result = endsWith(TEST_STRING, 'string', 8); - expect(result).toEqual(false); + const result = endsWith(SURROGATE_PAIRS_STRING, 'At🦄', 8); + expect(result).toEqual(true); }); }); describe('includes', () => { test('includes without position', () => { - const result = includes(TEST_STRING, 'really'); + const result = includes(TEXT_STRING, 'really'); expect(result).toEqual(true); }); test('includes with position', () => { - const result = includes(TEST_STRING, 'really', 22); + const result = includes(TEXT_STRING, 'really', 22); expect(result).toEqual(false); }); }); describe('indexOf', () => { test('indexOf without position', () => { - const result = indexOf(TEST_STRING, 'really'); + const result = indexOf(TEXT_STRING, 'really'); expect(result).toEqual(POS_FIRST_REALLY); }); test('indexOf with position', () => { - const result = indexOf(TEST_STRING, 'really', 12); + const result = indexOf(TEXT_STRING, 'really', 12); expect(result).toEqual(POS_SECOND_REALLY); }); }); describe('lastIndexOf', () => { test('lastIndexOf without position', () => { - const result = lastIndexOf(TEST_STRING, 'really'); + const result = lastIndexOf(TEXT_STRING, 'really'); expect(result).toEqual(POS_SECOND_REALLY); }); @@ -103,7 +104,7 @@ describe('lastIndexOf', () => { describe('length', () => { test('length is correct', () => { - const result = length(TEST_STRING); + const result = length(TEXT_STRING); expect(result).toEqual(TEST_STRING_LENGTH); }); }); @@ -112,20 +113,20 @@ describe('length', () => { describe('normalize', () => { test('normalize without form', () => { - const result = normalize(TEST_STRING); - expect(result).toEqual(TEST_STRING); + const result = normalize(TEXT_STRING); + expect(result).toEqual(TEXT_STRING); }); test('normalize with form', () => { - const result = normalize(TEST_STRING, 'NFC'); - expect(result).toEqual(TEST_STRING); + const result = normalize(TEXT_STRING, 'NFC'); + expect(result).toEqual(TEXT_STRING); }); }); describe('padEnd', () => { test('padEnd without padString', () => { - const result = padEnd(TEST_STRING, TEST_STRING_LENGTH + 10, undefined); - expect(result).toEqual(TEST_STRING + TEN_SPACES); + const result = padEnd(TEXT_STRING, TEST_STRING_LENGTH + 10, undefined); + expect(result).toEqual(TEXT_STRING + TEN_SPACES); }); // It expects 10 'ha' but it should only give 5 'ha' because that would be length 10 @@ -153,13 +154,13 @@ describe('padStart', () => { describe('startsWith', () => { test('startsWith without position', () => { - const result = startsWith(TEST_STRING, 'This'); + const result = startsWith(TEXT_STRING, 'This'); expect(result).toEqual(true); }); // Should test what the end is, not what it isn't test('startsWith with position', () => { - const result = startsWith(TEST_STRING, 'This', 5); + const result = startsWith(TEXT_STRING, 'This', 5); expect(result).toEqual(false); }); }); @@ -168,17 +169,17 @@ describe('startsWith', () => { describe('substring', () => { test('substring with begin', () => { - const result = substring(TEST_STRING, POS_FIRST_REALLY); + const result = substring(TEXT_STRING, POS_FIRST_REALLY); expect(result).toEqual('really really cool string'); }); test('substring with end', () => { - const result = substring(TEST_STRING, undefined, POS_FIRST_REALLY); + const result = substring(TEXT_STRING, undefined, POS_FIRST_REALLY); expect(result).toEqual('This is a '); }); test('substring with begin and end', () => { - const result = substring(TEST_STRING, POS_FIRST_REALLY, POS_SECOND_REALLY); + const result = substring(TEXT_STRING, POS_FIRST_REALLY, POS_SECOND_REALLY); expect(result).toEqual('really '); }); }); diff --git a/lib/platform-bible-utils/src/string-util.ts b/lib/platform-bible-utils/src/string-util.ts index 0483e08002..1ffaca50a2 100644 --- a/lib/platform-bible-utils/src/string-util.ts +++ b/lib/platform-bible-utils/src/string-util.ts @@ -9,7 +9,6 @@ import { // TODO: Note in each JSDOC that we are dealing with Unicode code points instead of UTF-16 character codes // TODO: Overloads -// TODO: Add npm test to platform-bible-utils build step // Rolf - I added a commented line with the override to the two functions that I found that needed one: normalize, and split. /** From 206fe63d5a772c6f1be6205c842b0f9f20bfe5f9 Mon Sep 17 00:00:00 2001 From: Rolf Heij Date: Fri, 16 Feb 2024 10:13:13 -0500 Subject: [PATCH 07/22] Add test --- .../src/string-util.test.ts | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/lib/platform-bible-utils/src/string-util.test.ts b/lib/platform-bible-utils/src/string-util.test.ts index 9766ed1590..f6b811e47e 100644 --- a/lib/platform-bible-utils/src/string-util.test.ts +++ b/lib/platform-bible-utils/src/string-util.test.ts @@ -20,10 +20,11 @@ import { } from './string-util'; const SURROGATE_PAIRS_STRING = -'Look𐐷At🦄All😎These😁Awesome🍕Symbols💩That🚀Are📷Represented😉By👌Surrogate🔥Pairs💋!🌟'; +'Look𐐷At🦄All😎These😁Awesome🍕Symbols💩That🚀Are📷Represented😉By🍕Surrogate🔥Pairs💋!🌟'; const TEXT_STRING = 'This is a really really cool string'; -const POS_FIRST_REALLY = 10; -const POS_SECOND_REALLY = 17; +const POS_FIRST_REALLY = 25; +const POS_SECOND_REALLY = 57; +const SURROGATE_PAIRS_STRING_LENGTH = 76; const TEST_STRING_LENGTH = 35; const TEN_SPACES = ' '; @@ -66,46 +67,44 @@ describe('endsWith', () => { describe('includes', () => { test('includes without position', () => { - const result = includes(TEXT_STRING, 'really'); + const result = includes(SURROGATE_PAIRS_STRING, '🍕Symbols💩'); expect(result).toEqual(true); }); test('includes with position', () => { - const result = includes(TEXT_STRING, 'really', 22); - expect(result).toEqual(false); + const result = includes(SURROGATE_PAIRS_STRING, '🦄All😎', 8); + expect(result).toEqual(true); }); }); describe('indexOf', () => { test('indexOf without position', () => { - const result = indexOf(TEXT_STRING, 'really'); + const result = indexOf(SURROGATE_PAIRS_STRING, '🍕'); expect(result).toEqual(POS_FIRST_REALLY); }); test('indexOf with position', () => { - const result = indexOf(TEXT_STRING, 'really', 12); + const result = indexOf(SURROGATE_PAIRS_STRING, '🍕', 40); expect(result).toEqual(POS_SECOND_REALLY); }); }); describe('lastIndexOf', () => { test('lastIndexOf without position', () => { - const result = lastIndexOf(TEXT_STRING, 'really'); + const result = lastIndexOf(SURROGATE_PAIRS_STRING, '🍕'); expect(result).toEqual(POS_SECOND_REALLY); }); - // Expecting -1 but returning 17 - // position should set the "start" of the string to 20, there is no 'really' from 20 to the end of the test string - // ('lastIndexOf with position', () => { - // const result = lastIndexOf(TEST_STRING, 'really', 20); - // expect(result).toEqual(-1); - // }); + test('lastIndexOf with position', () => { + const result = lastIndexOf(SURROGATE_PAIRS_STRING, '🍕', 5); + expect(result).toEqual(-1); + }); }); describe('length', () => { test('length is correct', () => { - const result = length(TEXT_STRING); - expect(result).toEqual(TEST_STRING_LENGTH); + const result = length(SURROGATE_PAIRS_STRING); + expect(result).toEqual(SURROGATE_PAIRS_STRING_LENGTH); }); }); From ada45148ed06bdebde3960953a70056069ed480b Mon Sep 17 00:00:00 2001 From: Jolie Rabideau Date: Fri, 16 Feb 2024 11:45:46 -0500 Subject: [PATCH 08/22] unit test rework, fix function implementations, note questions --- .../src/string-util.test.ts | 147 +++++++++++++----- lib/platform-bible-utils/src/string-util.ts | 11 +- 2 files changed, 114 insertions(+), 44 deletions(-) diff --git a/lib/platform-bible-utils/src/string-util.test.ts b/lib/platform-bible-utils/src/string-util.test.ts index f6b811e47e..6fc9430cb1 100644 --- a/lib/platform-bible-utils/src/string-util.test.ts +++ b/lib/platform-bible-utils/src/string-util.test.ts @@ -14,23 +14,24 @@ import { // slice, // split, startsWith, - // substr, + substr, substring, toArray, } from './string-util'; const SURROGATE_PAIRS_STRING = -'Look𐐷At🦄All😎These😁Awesome🍕Symbols💩That🚀Are📷Represented😉By🍕Surrogate🔥Pairs💋!🌟'; -const TEXT_STRING = 'This is a really really cool string'; -const POS_FIRST_REALLY = 25; -const POS_SECOND_REALLY = 57; + 'Look𐐷At🦄All😎These😁Awesome🍕Symbols💩That🚀Are📷Represented😉By🍕Surrogate🔥Pairs💋!🌟'; + +const SHORTER_SURROGATE_PAIRS_STRING = 'Look𐐷At🦄'; +const SHORTER_SURROGATE_PAIRS_ARRAY = ['L', 'o', 'o', 'k', '𐐷', 'A', 't', '🦄']; + +const POS_FIRST_PIZZA = 25; +const POS_SECOND_PIZZA = 57; const SURROGATE_PAIRS_STRING_LENGTH = 76; -const TEST_STRING_LENGTH = 35; const TEN_SPACES = ' '; -const TO_ARRAY_TEST_STRING = 'Hello'; -const TO_ARRAY_TEST_ARRAY = ['H', 'e', 'l', 'l', 'o']; -const TO_ARRAY_TEST_STRING_LENGTH = 5; +const NORMALIZE_STRING = '\u0041\u006d\u00e9\u006c\u0069\u0065'; +const NORMALIZE_SURROGATE_PAIRS = '\u0041\u006d\u0065\u0301\u006c\u0069\u0065'; describe('at', () => { test('at', () => { @@ -80,19 +81,19 @@ describe('includes', () => { describe('indexOf', () => { test('indexOf without position', () => { const result = indexOf(SURROGATE_PAIRS_STRING, '🍕'); - expect(result).toEqual(POS_FIRST_REALLY); + expect(result).toEqual(POS_FIRST_PIZZA); }); test('indexOf with position', () => { const result = indexOf(SURROGATE_PAIRS_STRING, '🍕', 40); - expect(result).toEqual(POS_SECOND_REALLY); + expect(result).toEqual(POS_SECOND_PIZZA); }); }); describe('lastIndexOf', () => { test('lastIndexOf without position', () => { const result = lastIndexOf(SURROGATE_PAIRS_STRING, '🍕'); - expect(result).toEqual(POS_SECOND_REALLY); + expect(result).toEqual(POS_SECOND_PIZZA); }); test('lastIndexOf with position', () => { @@ -108,84 +109,150 @@ describe('length', () => { }); }); -// TODO: limit test +// TODO: limit test, waiting +// TODO: add tests once we add override? describe('normalize', () => { - test('normalize without form', () => { - const result = normalize(TEXT_STRING); - expect(result).toEqual(TEXT_STRING); + test('normalize with no forms, compare strings', () => { + const regularStringResult = normalize(NORMALIZE_STRING, 'none'); + const surrogatePairStringResult = normalize(NORMALIZE_SURROGATE_PAIRS, 'none'); + expect(regularStringResult === surrogatePairStringResult).toEqual(false); + }); + + test('normalize with different forms, compare strings', () => { + const NFCResult = normalize(NORMALIZE_STRING, 'NFC'); + const NFDResult = normalize(NORMALIZE_SURROGATE_PAIRS, 'NFD'); + expect(NFCResult === NFDResult).toEqual(false); + }); + + test('normalize with same form, compare strings', () => { + const regularStringResult = normalize(NORMALIZE_STRING, 'NFC'); + const surrogatePairStringResult = normalize(NORMALIZE_SURROGATE_PAIRS, 'NFC'); + expect(regularStringResult === surrogatePairStringResult).toEqual(true); }); - test('normalize with form', () => { - const result = normalize(TEXT_STRING, 'NFC'); - expect(result).toEqual(TEXT_STRING); + test('normalize surrogate pairs string', () => { + const result = normalize(NORMALIZE_SURROGATE_PAIRS, 'NFC'); + expect(result).toEqual(NORMALIZE_STRING); + }); + + test('normalize surrogate pairs string as its own form', () => { + const result = normalize(NORMALIZE_SURROGATE_PAIRS, 'NFD'); + expect(result).toEqual(NORMALIZE_SURROGATE_PAIRS); }); }); describe('padEnd', () => { test('padEnd without padString', () => { - const result = padEnd(TEXT_STRING, TEST_STRING_LENGTH + 10, undefined); - expect(result).toEqual(TEXT_STRING + TEN_SPACES); + const result = padEnd(SURROGATE_PAIRS_STRING, SURROGATE_PAIRS_STRING_LENGTH + 10, undefined); + expect(result).toEqual(SURROGATE_PAIRS_STRING + TEN_SPACES); }); + // TODO: Finish test, once implementation is fixed // It expects 10 'ha' but it should only give 5 'ha' because that would be length 10 + // limit only works when length(padString) = 1 // ('padEnd with padString', () => { - // const result = padEnd(TEST_STRING, TEST_STRING_LENGTH + 10, 'ha'); - // expect(result).toEqual(`${TEST_STRING}hahahahaha`); + // const result = padEnd(TEXT_STRING, TEST_STRING_LENGTH + 10, 'ha'); + // expect(result).toEqual(`${TEXT_STRING}hahahahaha`); // }); }); describe('padStart', () => { test('padStart without padString', () => { - const result = padStart(TO_ARRAY_TEST_STRING, TO_ARRAY_TEST_STRING_LENGTH + 10, undefined); - expect(result).toEqual(TEN_SPACES + TO_ARRAY_TEST_STRING); + const result = padStart(SURROGATE_PAIRS_STRING, SURROGATE_PAIRS_STRING_LENGTH + 10, undefined); + expect(result).toEqual(TEN_SPACES + SURROGATE_PAIRS_STRING); }); + // TODO: Finish test, once implementation is fixed // It expects 10 'ha' but it should only give 5 'ha' because that would be length 10 + // limit only works when length(padString) = 1 // ('padStart with padString', () => { // const result = padStart(TEST_STRING, TEST_STRING_LENGTH + 10, 'ha'); // expect(result).toEqual(`hahahahaha${TEST_STRING}`); // }); }); -// TODO: slice test -// TODO: split test +// TODO: slice test, waiting +// ('slice', () => { +// ('slice', () => { +// const result = slice(SURROGATE_PAIRS_STRING, ) +// }) +// }) + +// TODO: fix split implementation and then test, add tests once we add override? +// ('split', () => { +// ('split without splitLimit', () => { +// const result = SURROGATE_PAIRS_STRING.split('🍕'); +// expect(result).toEqual(SURROGATE_PAIRS_ARRAY); +// }); + +// ('split by empty string', () => { +// const result = split(SHORTER_SURROGATE_PAIRS_STRING, ''); +// expect(result).toEqual(SHORTER_SURROGATE_PAIRS_ARRAY); +// }); +// }); describe('startsWith', () => { test('startsWith without position', () => { - const result = startsWith(TEXT_STRING, 'This'); + const result = startsWith(SURROGATE_PAIRS_STRING, 'Look𐐷'); expect(result).toEqual(true); }); - // Should test what the end is, not what it isn't - test('startsWith with position', () => { - const result = startsWith(TEXT_STRING, 'This', 5); + test('startsWith with position, searchString is not the start', () => { + const result = startsWith(SURROGATE_PAIRS_STRING, 'Look𐐷', 5); expect(result).toEqual(false); }); + + test('startsWith with position, searchString is the start', () => { + const result = startsWith(SURROGATE_PAIRS_STRING, 'At🦄', 5); + expect(result).toEqual(true); + }); }); -// TODO: substr test +describe('substr', () => { + test('substr without begin or end', () => { + const result = substr(SURROGATE_PAIRS_STRING); + expect(result).toEqual(SURROGATE_PAIRS_STRING); + }); + + test('substr with begin', () => { + const result = substr(SURROGATE_PAIRS_STRING, 5); + expect(result).toEqual( + 'At🦄All😎These😁Awesome🍕Symbols💩That🚀Are📷Represented😉By🍕Surrogate🔥Pairs💋!🌟', + ); + }); + + test('substr with end', () => { + const result = substr(SURROGATE_PAIRS_STRING, undefined, 25); + expect(result).toEqual('Look𐐷At🦄All😎These😁Awesome'); + }); + + test('substr with begin and end', () => { + const result = substr(SURROGATE_PAIRS_STRING, 5, 25); + expect(result).toEqual('At🦄All😎These😁Awesome🍕Symb'); + }); +}); describe('substring', () => { test('substring with begin', () => { - const result = substring(TEXT_STRING, POS_FIRST_REALLY); - expect(result).toEqual('really really cool string'); + const result = substring(SURROGATE_PAIRS_STRING, POS_FIRST_PIZZA); + expect(result).toEqual('🍕Symbols💩That🚀Are📷Represented😉By🍕Surrogate🔥Pairs💋!🌟'); }); test('substring with end', () => { - const result = substring(TEXT_STRING, undefined, POS_FIRST_REALLY); - expect(result).toEqual('This is a '); + const result = substring(SURROGATE_PAIRS_STRING, undefined, POS_FIRST_PIZZA); + expect(result).toEqual('Look𐐷At🦄All😎These😁Awesome'); }); test('substring with begin and end', () => { - const result = substring(TEXT_STRING, POS_FIRST_REALLY, POS_SECOND_REALLY); - expect(result).toEqual('really '); + const result = substring(SURROGATE_PAIRS_STRING, POS_FIRST_PIZZA, POS_SECOND_PIZZA); + expect(result).toEqual('🍕Symbols💩That🚀Are📷Represented😉By'); }); }); describe('toArray', () => { test('toArray returns correct array', () => { - const result = toArray(TO_ARRAY_TEST_STRING); - expect(result).toEqual(TO_ARRAY_TEST_ARRAY); + const result = toArray(SHORTER_SURROGATE_PAIRS_STRING); + expect(result).toEqual(SHORTER_SURROGATE_PAIRS_ARRAY); }); }); diff --git a/lib/platform-bible-utils/src/string-util.ts b/lib/platform-bible-utils/src/string-util.ts index 1ffaca50a2..407108e82d 100644 --- a/lib/platform-bible-utils/src/string-util.ts +++ b/lib/platform-bible-utils/src/string-util.ts @@ -149,7 +149,7 @@ export function length(string: string): number { return stringzLength(string); } -// TODO: test +// TODO: test, ask TJ if we want this /** * Limits a string to a given width. This function handles Unicode code points instead of UTF-16 * character codes. @@ -170,7 +170,7 @@ export function limit( return stringzLimit(string, padLimit, padString, padPosition); } -// TODO: Want to override, but getting an error that it isn't compatible +// TODO: Want to override, but getting an error that it isn't compatible, check if we need to validate the form to make sure its one of the provided options // export function normalize(string: string, form?: string): string; /** * Returns the Unicode Normalization Form of this string. @@ -188,6 +188,7 @@ export function normalize(string: string, form: 'NFC' | 'NFD' | 'none' = 'NFC'): return string.normalize(upperCaseForm); } +// TODO: limit only works when length(padString) = 1 /** * Pads this string with another string (multiple times, if needed) until the resulting string * reaches the given length. The padding is applied from the end of this string. This function @@ -205,6 +206,7 @@ export function padEnd(string: string, targetLength: number, padString: string = return limit(string, targetLength, padString, 'right'); } +// TODO: limit only works when length(padString) = 1 /** * Pads this string with another string (multiple times, if needed) until the resulting string * reaches the given length. The padding is applied from the start of this string. This function @@ -222,6 +224,7 @@ export function padStart(string: string, targetLength: number, padString: string return limit(string, targetLength, padString, 'left'); } +// TODO: Do we need to implement both this and substring with subtle differences, or treat them the same /** * Extracts a section of this string and returns it as a new string, without modifying the original * string. This function handles Unicode code points instead of UTF-16 character codes. @@ -296,11 +299,11 @@ export function split(string: string, separator: string | RegExp, splitLimit?: n */ export function startsWith(string: string, searchString: string, position: number = 0): boolean { const indexOfSearchString = indexOf(string, searchString, position); - if (indexOfSearchString !== 0) return false; + if (indexOfSearchString !== position) return false; return true; } -// TODO: test +// TODO: test, ask TJ if we want this since its deprecated in string /** * Returns a substring by providing start and length. This function handles Unicode code points * instead of UTF-16 character codes. From a1c12b5c52b7da79edb584bd3f6a09baa78f33db Mon Sep 17 00:00:00 2001 From: Jolie Rabideau Date: Fri, 16 Feb 2024 11:58:59 -0500 Subject: [PATCH 09/22] adjust at implementation and test --- lib/platform-bible-utils/src/string-util.test.ts | 12 +++++++++++- lib/platform-bible-utils/src/string-util.ts | 4 ++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/platform-bible-utils/src/string-util.test.ts b/lib/platform-bible-utils/src/string-util.test.ts index 6fc9430cb1..58a0c04d15 100644 --- a/lib/platform-bible-utils/src/string-util.test.ts +++ b/lib/platform-bible-utils/src/string-util.test.ts @@ -34,10 +34,20 @@ const NORMALIZE_STRING = '\u0041\u006d\u00e9\u006c\u0069\u0065'; const NORMALIZE_SURROGATE_PAIRS = '\u0041\u006d\u0065\u0301\u006c\u0069\u0065'; describe('at', () => { - test('at', () => { + test('at with in bounds index', () => { const result = at(SURROGATE_PAIRS_STRING, 4); expect(result).toEqual('𐐷'); }); + + test('at with negative index returns last character', () => { + const result = at(SURROGATE_PAIRS_STRING, -1); + expect(result).toEqual('🌟'); + }); + + test('at with index greater than length returns empty string', () => { + const result = at(SURROGATE_PAIRS_STRING, length(SURROGATE_PAIRS_STRING) + 10); + expect(result).toEqual(''); + }); }); describe('charAt', () => { diff --git a/lib/platform-bible-utils/src/string-util.ts b/lib/platform-bible-utils/src/string-util.ts index 407108e82d..cd51d11008 100644 --- a/lib/platform-bible-utils/src/string-util.ts +++ b/lib/platform-bible-utils/src/string-util.ts @@ -9,8 +9,8 @@ import { // TODO: Note in each JSDOC that we are dealing with Unicode code points instead of UTF-16 character codes // TODO: Overloads -// Rolf - I added a commented line with the override to the two functions that I found that needed one: normalize, and split. +// TODO: Do we want this to throw instead of return empty string? /** * Finds the Unicode code point at the given index * @@ -19,7 +19,7 @@ import { * @returns {string} New string consisting of the Unicode code point located at the specified offset */ export function at(string: string, index: number): string { - // TODO: Add validation for index? can't be less than 0 or greater than string length + if (index > length(string) || index < -length(string)) return ''; return substr(string, index, 1); } From eb231438662122da06909f9bd978dbed77f28fef Mon Sep 17 00:00:00 2001 From: Jolie Rabideau Date: Fri, 16 Feb 2024 13:30:42 -0500 Subject: [PATCH 10/22] fix normalize overrides --- lib/platform-bible-utils/src/string-util.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/platform-bible-utils/src/string-util.ts b/lib/platform-bible-utils/src/string-util.ts index cd51d11008..a97643dca7 100644 --- a/lib/platform-bible-utils/src/string-util.ts +++ b/lib/platform-bible-utils/src/string-util.ts @@ -170,8 +170,7 @@ export function limit( return stringzLimit(string, padLimit, padString, padPosition); } -// TODO: Want to override, but getting an error that it isn't compatible, check if we need to validate the form to make sure its one of the provided options -// export function normalize(string: string, form?: string): string; +// TODO: Check if we need to validate the form to make sure its one of the provided options /** * Returns the Unicode Normalization Form of this string. * @@ -180,7 +179,9 @@ export function limit( * Default is `'NFC'` * @returns {string} A string containing the Unicode Normalization Form of the given string. */ -export function normalize(string: string, form: 'NFC' | 'NFD' | 'none' = 'NFC'): string { +export function normalize(string: string, form: 'NFC' | 'NFD' | 'none'): string; +export function normalize(string: string, form: string): string; +export function normalize(string: string, form: string = 'NFC'): string { const upperCaseForm = form.toUpperCase(); if (upperCaseForm === 'NONE') { return string; From ea1d64d2eadec064e1b2ac2ab4be29a14c4cc681 Mon Sep 17 00:00:00 2001 From: Rolf Heij Date: Fri, 16 Feb 2024 16:58:40 -0500 Subject: [PATCH 11/22] good stuff! --- .../src/string-util.test.ts | 54 +++++++++++++------ lib/platform-bible-utils/src/string-util.ts | 53 ++++++++++-------- 2 files changed, 69 insertions(+), 38 deletions(-) diff --git a/lib/platform-bible-utils/src/string-util.test.ts b/lib/platform-bible-utils/src/string-util.test.ts index 58a0c04d15..d0fd2de7df 100644 --- a/lib/platform-bible-utils/src/string-util.test.ts +++ b/lib/platform-bible-utils/src/string-util.test.ts @@ -12,7 +12,7 @@ import { padEnd, padStart, // slice, - // split, + split, startsWith, substr, substring, @@ -22,8 +22,11 @@ import { const SURROGATE_PAIRS_STRING = 'Look𐐷At🦄All😎These😁Awesome🍕Symbols💩That🚀Are📷Represented😉By🍕Surrogate🔥Pairs💋!🌟'; -const SHORTER_SURROGATE_PAIRS_STRING = 'Look𐐷At🦄'; -const SHORTER_SURROGATE_PAIRS_ARRAY = ['L', 'o', 'o', 'k', '𐐷', 'A', 't', '🦄']; +const SHORT_SURROGATE_PAIRS_STRING = 'Look𐐷At🦄'; +const SHORT_SURROGATE_PAIRS_ARRAY = ['L', 'o', 'o', 'k', '𐐷', 'A', 't', '🦄']; + +const SHORTER_SURROGATE_PAIRS_STRING = 'Look𐐷At🦄This𐐷Thing😉Its𐐷Awesome'; +const SHORTER_SURROGATE_PAIRS_ARRAY = ['Look', 'At🦄This', 'Thing😉Its', 'Awesome']; const POS_FIRST_PIZZA = 25; const POS_SECOND_PIZZA = 57; @@ -189,18 +192,37 @@ describe('padStart', () => { // }) // }) -// TODO: fix split implementation and then test, add tests once we add override? -// ('split', () => { -// ('split without splitLimit', () => { -// const result = SURROGATE_PAIRS_STRING.split('🍕'); -// expect(result).toEqual(SURROGATE_PAIRS_ARRAY); -// }); +describe('split', () => { + test('split without splitLimit', () => { + const result = split(SHORTER_SURROGATE_PAIRS_STRING, '𐐷'); + expect(result).toEqual(SHORTER_SURROGATE_PAIRS_ARRAY); + }); + + test('split with splitLimit', () => { + const result = split(SHORTER_SURROGATE_PAIRS_STRING, '𐐷', 2); + expect(result).toEqual(['Look', 'At🦄This𐐷Thing😉Its𐐷Awesome']); + }); + + test('split by empty string', () => { + const result = split(SHORT_SURROGATE_PAIRS_STRING, ''); + expect(result).toEqual(SHORT_SURROGATE_PAIRS_ARRAY); + }); + + test('split by empty string with splitLimit', () => { + const result = split(SHORT_SURROGATE_PAIRS_STRING, '', 3); + expect(result).toEqual(['L', 'o', 'o']); + }); -// ('split by empty string', () => { -// const result = split(SHORTER_SURROGATE_PAIRS_STRING, ''); -// expect(result).toEqual(SHORTER_SURROGATE_PAIRS_ARRAY); -// }); -// }); + test('split with RegExp separator', () => { + const result = split(SHORTER_SURROGATE_PAIRS_STRING, /[A-Z]/); + expect(result).toEqual(['', 'ook𐐷', 't🦄', 'his𐐷', 'hing😉', 'ts𐐷', 'wesome']); + }); + + test('split with RegExp separator that contains surrogate pairs', () => { + const result = split(SHORTER_SURROGATE_PAIRS_STRING, /🦄/); + expect(result).toEqual(['Look𐐷At', 'This𐐷Thing😉Its𐐷Awesome']); + }); +}); describe('startsWith', () => { test('startsWith without position', () => { @@ -262,7 +284,7 @@ describe('substring', () => { describe('toArray', () => { test('toArray returns correct array', () => { - const result = toArray(SHORTER_SURROGATE_PAIRS_STRING); - expect(result).toEqual(SHORTER_SURROGATE_PAIRS_ARRAY); + const result = toArray(SHORT_SURROGATE_PAIRS_STRING); + expect(result).toEqual(SHORT_SURROGATE_PAIRS_ARRAY); }); }); diff --git a/lib/platform-bible-utils/src/string-util.ts b/lib/platform-bible-utils/src/string-util.ts index a97643dca7..156177c158 100644 --- a/lib/platform-bible-utils/src/string-util.ts +++ b/lib/platform-bible-utils/src/string-util.ts @@ -8,7 +8,6 @@ import { } from 'stringz'; // TODO: Note in each JSDOC that we are dealing with Unicode code points instead of UTF-16 character codes -// TODO: Overloads // TODO: Do we want this to throw instead of return empty string? /** @@ -239,8 +238,6 @@ export function slice(string: string, indexStart: number, indexEnd?: number): st return substring(string, indexStart, indexEnd); } -// TODO: Test, overload for separator type -// split(splitter: { [Symbol.split](string: string, limit?: number): string[]; }, limit?: number): string[]; /** * Takes a pattern and divides the string into an ordered list of substrings by searching for the * pattern, puts these substrings into an array, and returns the array. This function handles @@ -251,37 +248,49 @@ export function slice(string: string, indexStart: number, indexEnd?: number): st * @param {number} splitLimit Limit on the number of substrings to be included in the array. Splits * the string at each occurrence of specified separator, but stops when limit entries have been * placed in the array. - * @returns {string[]} An array of strings, split at each point where separator occurs in the - * starting string. + * @returns {string[] | undefined} An array of strings, split at each point where separator occurs + * in the starting string. Returns undefined if separator is not found in string. */ -export function split(string: string, separator: string | RegExp, splitLimit?: number): string[] { +export function split( + string: string, + separator: string | RegExp, + splitLimit?: number, +): string[] | undefined { const result: string[] = []; - if (splitLimit === undefined || splitLimit <= 0) { - return [string]; // Return the whole string if limit is not provided or invalid + if (splitLimit !== undefined && splitLimit <= 0) { + return [string]; + } + + if (separator === '') return toArray(string).slice(0, splitLimit); + + let regexSeparator = separator; + if ( + typeof separator === 'string' || + (separator instanceof RegExp && !separator.flags.includes('g')) + ) { + regexSeparator = new RegExp(separator, 'g'); } + const matches: RegExpMatchArray | null = string.match(regexSeparator); + let currentIndex = 0; - let match: RegExpMatchArray | null; - match = substr(string, currentIndex).match(separator); - // match() returns either RegExpMatchArray or null - // eslint-disable-next-line no-null/no-null - while (match !== null) { - const matchIndex = match.index ?? 0; - const matchLength = match[0].length; + if (!matches) return undefined; - result.push(substr(string, currentIndex, matchIndex)); - currentIndex += matchIndex + matchLength; + for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) { + const matchIndex = indexOf(string, matches[index], currentIndex); + const matchLength = length(matches[index]); - if (result.length === splitLimit - 1) { - break; // Reached the specified limit - } + result.push(substring(string, currentIndex, matchIndex)); + currentIndex = matchIndex + matchLength; - match = substr(string, currentIndex).match(separator); + if (splitLimit !== undefined && result.length === splitLimit) { + break; + } } - result.push(substr(string, currentIndex)); // Add the remaining part of the string + result.push(substring(string, currentIndex)); return result; } From 2bbb9b4baf18a5d18b305cf8196fedf0d92ee191 Mon Sep 17 00:00:00 2001 From: Rolf Heij Date: Fri, 16 Feb 2024 17:01:21 -0500 Subject: [PATCH 12/22] Fix test and add a new test --- lib/platform-bible-utils/src/string-util.test.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/platform-bible-utils/src/string-util.test.ts b/lib/platform-bible-utils/src/string-util.test.ts index d0fd2de7df..b5c23be8d4 100644 --- a/lib/platform-bible-utils/src/string-util.test.ts +++ b/lib/platform-bible-utils/src/string-util.test.ts @@ -86,9 +86,14 @@ describe('includes', () => { }); test('includes with position', () => { - const result = includes(SURROGATE_PAIRS_STRING, '🦄All😎', 8); + const result = includes(SURROGATE_PAIRS_STRING, '🦄All😎', 7); expect(result).toEqual(true); }); + + test('includes with position that is to high, so no matches are found', () => { + const result = includes(SURROGATE_PAIRS_STRING, '🦄All😎', 10); + expect(result).toEqual(false); + }); }); describe('indexOf', () => { From 72c7baefd0e377c916c22634770af7ca40c2a6ab Mon Sep 17 00:00:00 2001 From: Jolie Rabideau Date: Mon, 19 Feb 2024 11:24:40 -0500 Subject: [PATCH 13/22] work on todos, slice implementation and tests --- .../src/string-util.test.ts | 75 ++++++------- lib/platform-bible-utils/src/string-util.ts | 103 ++++++++---------- 2 files changed, 82 insertions(+), 96 deletions(-) diff --git a/lib/platform-bible-utils/src/string-util.test.ts b/lib/platform-bible-utils/src/string-util.test.ts index b5c23be8d4..b708d567c4 100644 --- a/lib/platform-bible-utils/src/string-util.test.ts +++ b/lib/platform-bible-utils/src/string-util.test.ts @@ -7,14 +7,12 @@ import { indexOf, lastIndexOf, length, - // limit, normalize, padEnd, padStart, - // slice, + slice, split, startsWith, - substr, substring, toArray, } from './string-util'; @@ -47,9 +45,9 @@ describe('at', () => { expect(result).toEqual('🌟'); }); - test('at with index greater than length returns empty string', () => { + test('at with index greater than length returns undefined', () => { const result = at(SURROGATE_PAIRS_STRING, length(SURROGATE_PAIRS_STRING) + 10); - expect(result).toEqual(''); + expect(result).toEqual(undefined); }); }); @@ -58,6 +56,8 @@ describe('charAt', () => { const result = charAt(SURROGATE_PAIRS_STRING, 7); expect(result).toEqual('🦄'); }); + + // TODO: more tests }); describe('codePointAt', () => { @@ -65,6 +65,8 @@ describe('codePointAt', () => { const result = codePointAt(SURROGATE_PAIRS_STRING, 11); expect(result).toEqual(128526); }); + + // TODO: more tests }); describe('endsWith', () => { @@ -127,9 +129,6 @@ describe('length', () => { }); }); -// TODO: limit test, waiting - -// TODO: add tests once we add override? describe('normalize', () => { test('normalize with no forms, compare strings', () => { const regularStringResult = normalize(NORMALIZE_STRING, 'none'); @@ -166,7 +165,9 @@ describe('padEnd', () => { expect(result).toEqual(SURROGATE_PAIRS_STRING + TEN_SPACES); }); - // TODO: Finish test, once implementation is fixed + // TODO: test with one character padString + + // Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59 // It expects 10 'ha' but it should only give 5 'ha' because that would be length 10 // limit only works when length(padString) = 1 // ('padEnd with padString', () => { @@ -181,7 +182,9 @@ describe('padStart', () => { expect(result).toEqual(TEN_SPACES + SURROGATE_PAIRS_STRING); }); - // TODO: Finish test, once implementation is fixed + // TODO: test with one character padString + + // Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59 // It expects 10 'ha' but it should only give 5 'ha' because that would be length 10 // limit only works when length(padString) = 1 // ('padStart with padString', () => { @@ -190,12 +193,28 @@ describe('padStart', () => { // }); }); -// TODO: slice test, waiting -// ('slice', () => { -// ('slice', () => { -// const result = slice(SURROGATE_PAIRS_STRING, ) -// }) -// }) +describe('slice', () => { + test('slice with with end greater than negative length of string returns empty string', () => { + const result = slice(SHORT_SURROGATE_PAIRS_STRING, 0, -1000); + expect(result).toEqual(''); + }); + + test('slice with begin greater than negative length of string returns whole string', () => { + const result = slice(SHORT_SURROGATE_PAIRS_STRING, -1000); + expect(result).toEqual(SHORT_SURROGATE_PAIRS_STRING); + }); + + // Failing receives '' + // test('slice with begin of -1 returns last character', () => { + // const result = slice(SHORT_SURROGATE_PAIRS_STRING, -1); + // expect(result).toEqual('🦄'); + // }); + + test('slice with in bounds begin and end', () => { + const result = slice(SHORT_SURROGATE_PAIRS_STRING, 0, 2); + expect(result).toEqual('Lo'); + }); +}); describe('split', () => { test('split without splitLimit', () => { @@ -246,30 +265,6 @@ describe('startsWith', () => { }); }); -describe('substr', () => { - test('substr without begin or end', () => { - const result = substr(SURROGATE_PAIRS_STRING); - expect(result).toEqual(SURROGATE_PAIRS_STRING); - }); - - test('substr with begin', () => { - const result = substr(SURROGATE_PAIRS_STRING, 5); - expect(result).toEqual( - 'At🦄All😎These😁Awesome🍕Symbols💩That🚀Are📷Represented😉By🍕Surrogate🔥Pairs💋!🌟', - ); - }); - - test('substr with end', () => { - const result = substr(SURROGATE_PAIRS_STRING, undefined, 25); - expect(result).toEqual('Look𐐷At🦄All😎These😁Awesome'); - }); - - test('substr with begin and end', () => { - const result = substr(SURROGATE_PAIRS_STRING, 5, 25); - expect(result).toEqual('At🦄All😎These😁Awesome🍕Symb'); - }); -}); - describe('substring', () => { test('substring with begin', () => { const result = substring(SURROGATE_PAIRS_STRING, POS_FIRST_PIZZA); diff --git a/lib/platform-bible-utils/src/string-util.ts b/lib/platform-bible-utils/src/string-util.ts index 156177c158..9c8286cbe5 100644 --- a/lib/platform-bible-utils/src/string-util.ts +++ b/lib/platform-bible-utils/src/string-util.ts @@ -7,47 +7,46 @@ import { substr as stringzSubstr, } from 'stringz'; -// TODO: Note in each JSDOC that we are dealing with Unicode code points instead of UTF-16 character codes - -// TODO: Do we want this to throw instead of return empty string? /** * Finds the Unicode code point at the given index * * @param {string} string String to index - * @param {number} index Position of the character to be returned - * @returns {string} New string consisting of the Unicode code point located at the specified offset + * @param {number} index Position of the character to be returned in range of 0 to -length(string) + * @returns {string} New string consisting of the Unicode code point located at the specified + * offset, undefined if index is out of bounds */ -export function at(string: string, index: number): string { - if (index > length(string) || index < -length(string)) return ''; +export function at(string: string, index: number): string | undefined { + if (index > length(string) || index < -length(string)) return undefined; return substr(string, index, 1); } -// TODO: Is this all we need to do here? /** * Always indexes string as a sequence of Unicode code points * * @param string String to index - * @param index Position of the string character to be returned - * @returns {string} New string consisting of the Unicode code point located at the specified offset + * @param index Position of the string character to be returned, in the range of 0 to + * length(string)-1 + * @returns {string} New string consisting of the Unicode code point located at the specified + * offset, empty string if index is out of bounds */ export function charAt(string: string, index: number): string { - return at(string, index); + if (index < 0 || index > length(string) - 1) return ''; + return substr(string, index, 1); } -// TODO: Is this all we need to do here? /** * Returns a non-negative integer that is the Unicode code point value of the character starting at * the given index. This function handles Unicode code points instead of UTF-16 character codes. * * @param {string} string String to index - * @param {number} index Position of the string character to be returned + * @param {number} index Position of the string character to be returned, in the range of 0 to + * length(string)-1 * @returns {number | undefined} Non-negative integer representing the code point value of the * character at the given index, or undefined if there is no element at that position */ export function codePointAt(string: string, index: number): number | undefined { - // TODO: validation for index? - const character = at(string, index); - return character.codePointAt(0); + if (index < 0 || index > length(string) - 1) return undefined; + return substr(string, index, 1).codePointAt(0); } /** @@ -148,39 +147,15 @@ export function length(string: string): number { return stringzLength(string); } -// TODO: test, ask TJ if we want this -/** - * Limits a string to a given width. This function handles Unicode code points instead of UTF-16 - * character codes. - * - * @param {string} string The string to be limited - * @param {number} [padLimit=16] Desired string length. Default is `16` - * @param {string} [padString=' '] Character to pad the output with. Default is `' '` - * @param {'right' | 'left'} [padPosition='right'] The pad position: 'right' or 'left'. Default is - * `'right'` - * @returns {string} String limited to the given width with the padString provided - */ -export function limit( - string: string, - padLimit: number = 16, - padString: string = ' ', - padPosition: 'right' | 'left' = 'right', -): string { - return stringzLimit(string, padLimit, padString, padPosition); -} - -// TODO: Check if we need to validate the form to make sure its one of the provided options /** * Returns the Unicode Normalization Form of this string. * * @param {string} string The starting string - * @param {'NFC' | 'NFD' | 'none'} [form='NFC'] Form specifying the Unicode Normalization Form. - * Default is `'NFC'` + * @param {'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'} [form='NFC'] Form specifying the Unicode + * Normalization Form. Default is `'NFC'` * @returns {string} A string containing the Unicode Normalization Form of the given string. */ -export function normalize(string: string, form: 'NFC' | 'NFD' | 'none'): string; -export function normalize(string: string, form: string): string; -export function normalize(string: string, form: string = 'NFC'): string { +export function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string { const upperCaseForm = form.toUpperCase(); if (upperCaseForm === 'NONE') { return string; @@ -188,7 +163,6 @@ export function normalize(string: string, form: string = 'NFC'): string { return string.normalize(upperCaseForm); } -// TODO: limit only works when length(padString) = 1 /** * Pads this string with another string (multiple times, if needed) until the resulting string * reaches the given length. The padding is applied from the end of this string. This function @@ -201,12 +175,12 @@ export function normalize(string: string, form: string = 'NFC'): string { * long to stay within targetLength, it will be truncated. Default is `" "` * @returns {string} String with appropriate padding at the end */ +// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59 export function padEnd(string: string, targetLength: number, padString: string = ' '): string { if (targetLength <= length(string)) return string; - return limit(string, targetLength, padString, 'right'); + return stringzLimit(string, targetLength, padString, 'right'); } -// TODO: limit only works when length(padString) = 1 /** * Pads this string with another string (multiple times, if needed) until the resulting string * reaches the given length. The padding is applied from the start of this string. This function @@ -219,12 +193,20 @@ export function padEnd(string: string, targetLength: number, padString: string = * long to stay within the targetLength, it will be truncated from the end. Default is `" "` * @returns String with of specified targetLength with padString applied from the start */ +// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59 export function padStart(string: string, targetLength: number, padString: string = ' '): string { if (targetLength <= length(string)) return string; - return limit(string, targetLength, padString, 'left'); + return stringzLimit(string, targetLength, padString, 'left'); } -// TODO: Do we need to implement both this and substring with subtle differences, or treat them the same +// function validateSliceIndex(string: string, index: number) { +// if (index < -length(string)) return -length(string); +// if (index > length(string)) return length(string); +// if (index < 0) return index + length(string); +// return index; +// } + +// TODO: slice accepts negative and loops include differences /** * Extracts a section of this string and returns it as a new string, without modifying the original * string. This function handles Unicode code points instead of UTF-16 character codes. @@ -235,7 +217,20 @@ export function padStart(string: string, targetLength: number, padString: string * @returns {string} A new string containing the extracted section of the string. */ export function slice(string: string, indexStart: number, indexEnd?: number): string { - return substring(string, indexStart, indexEnd); + let newStart = indexStart; + let newEnd = indexEnd || 0; + + if (!newStart) newStart = 0; + if (newStart >= length(string)) return ''; + if (newStart < 0) newStart += length(string); + + if (newEnd >= length(string)) newEnd = length(string) - 1; + if (newEnd < 0) newEnd += length(string); + + // AFTER normalizing negatives + if (newEnd <= newStart) return ''; + + return substr(string, newStart, newEnd - newStart); } /** @@ -313,10 +308,10 @@ export function startsWith(string: string, searchString: string, position: numbe return true; } -// TODO: test, ask TJ if we want this since its deprecated in string /** * Returns a substring by providing start and length. This function handles Unicode code points - * instead of UTF-16 character codes. + * instead of UTF-16 character codes. This function is not exported because it is considered + * deprecated, however it is still useful as a local helper function. * * @param {string} string String to be divided * @param {number} [begin=Start of string] Start position. Default is `Start of string` @@ -324,11 +319,7 @@ export function startsWith(string: string, searchString: string, position: numbe * length minus start parameter`. Default is `String length minus start parameter` * @returns {string} Substring from starting string */ -export function substr( - string: string, - begin: number = 0, - len: number = length(string) - begin, -): string { +function substr(string: string, begin: number = 0, len: number = length(string) - begin): string { return stringzSubstr(string, begin, len); } From 115f3e87eb41ff6dded8eaffabcba45062a6efbb Mon Sep 17 00:00:00 2001 From: Rolf Heij Date: Mon, 19 Feb 2024 14:01:23 -0500 Subject: [PATCH 14/22] Finish string utils and their tests --- lib/platform-bible-utils/dist/index.cjs | 2 +- lib/platform-bible-utils/dist/index.cjs.map | 2 +- lib/platform-bible-utils/dist/index.d.ts | 148 ++++- lib/platform-bible-utils/dist/index.js | 545 ++++++++++-------- lib/platform-bible-utils/dist/index.js.map | 2 +- .../src/string-util.test.ts | 219 +++++-- lib/platform-bible-utils/src/string-util.ts | 49 +- 7 files changed, 634 insertions(+), 333 deletions(-) diff --git a/lib/platform-bible-utils/dist/index.cjs b/lib/platform-bible-utils/dist/index.cjs index 8b8db2ceaf..4a41f1a86f 100644 --- a/lib/platform-bible-utils/dist/index.cjs +++ b/lib/platform-bible-utils/dist/index.cjs @@ -1,2 +1,2 @@ -"use strict";var ae=Object.defineProperty;var oe=(t,e,r)=>e in t?ae(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var p=(t,e,r)=>(oe(t,typeof e!="symbol"?e+"":e,r),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class ie{constructor(e,r=1e4){p(this,"variableName");p(this,"promiseToValue");p(this,"resolver");p(this,"rejecter");this.variableName=e,this.promiseToValue=new Promise((s,n)=>{this.resolver=s,this.rejecter=n}),r>0&&setTimeout(()=>{this.rejecter&&(this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`),this.complete())},r),Object.seal(this)}get promise(){return this.promiseToValue}get hasSettled(){return Object.isFrozen(this)}resolveToValue(e,r=!1){if(this.resolver)console.debug(`${this.variableName} is being resolved now`),this.resolver(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent resolution of ${this.variableName}`)}}rejectWithReason(e,r=!1){if(this.rejecter)console.debug(`${this.variableName} is being rejected now`),this.rejecter(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent rejection of ${this.variableName}`)}}complete(){this.resolver=void 0,this.rejecter=void 0,Object.freeze(this)}}function ue(){return"00-0-4-1-000".replace(/[^-]/g,t=>((Math.random()+~~t)*65536>>t).toString(16).padStart(4,"0"))}function B(t){return typeof t=="string"||t instanceof String}function E(t){return JSON.parse(JSON.stringify(t))}function le(t,e=300){if(B(t))throw new Error("Tried to debounce a string! Could be XSS");let r;return(...s)=>{clearTimeout(r),r=setTimeout(()=>t(...s),e)}}function ce(t,e,r){const s=new Map;return t.forEach(n=>{const a=e(n),o=s.get(a),i=r?r(n,a):n;o?o.push(i):s.set(a,[i])}),s}function fe(t){return typeof t=="object"&&t!==null&&"message"in t&&typeof t.message=="string"}function he(t){if(fe(t))return t;try{return new Error(JSON.stringify(t))}catch{return new Error(String(t))}}function pe(t){return he(t).message}function J(t){return new Promise(e=>setTimeout(e,t))}function me(t,e){const r=J(e).then(()=>{});return Promise.any([r,t()])}function de(t,e="obj"){const r=new Set;Object.getOwnPropertyNames(t).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(a){console.debug(`Skipping ${n} on ${e} due to error: ${a}`)}});let s=Object.getPrototypeOf(t);for(;s&&Object.getPrototypeOf(s);)Object.getOwnPropertyNames(s).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(a){console.debug(`Skipping ${n} on ${e}'s prototype due to error: ${a}`)}}),s=Object.getPrototypeOf(s);return r}function ge(t,e={}){return new Proxy(e,{get(r,s){return s in r?r[s]:async(...n)=>(await t())[s](...n)}})}class be{constructor(e,r){p(this,"baseDocument");p(this,"contributions",new Map);p(this,"latestOutput");p(this,"options");this.baseDocument=e,this.options=r,this.updateBaseDocument(e)}updateBaseDocument(e){return this.validateStartingDocument(e),this.baseDocument=this.options.copyDocuments?E(e):e,this.rebuild()}addOrUpdateContribution(e,r){this.validateContribution(e,r);const s=this.contributions.get(e),n=this.options.copyDocuments&&r?E(r):r;this.contributions.set(e,n);try{return this.rebuild()}catch(a){throw s?this.contributions.set(e,s):this.contributions.delete(e),new Error(`Error when setting the document named ${e}: ${a}`)}}deleteContribution(e){const r=this.contributions.get(e);if(!r)throw new Error("{documentKey} does not exist");this.contributions.delete(e);try{return this.rebuild()}catch(s){throw this.contributions.set(e,r),new Error(`Error when deleting the document named ${e}: ${s}`)}}rebuild(){if(this.contributions.size===0){let r=E(this.baseDocument);return r=this.transformFinalOutput(r),this.validateOutput(r),this.latestOutput=r,this.latestOutput}let e=this.baseDocument;return this.contributions.forEach(r=>{e=G(e,r,this.options.ignoreDuplicateProperties),this.validateOutput(e)}),e=this.transformFinalOutput(e),this.validateOutput(e),this.latestOutput=e,this.latestOutput}}function Ne(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||Array.isArray(r))&&(e=!1)}),e}function ve(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||!Array.isArray(r))&&(e=!1)}),e}function G(t,e,r){const s=E(t);return e&&Object.keys(e).forEach(n=>{if(Object.hasOwn(t,n)){if(Ne(t[n],e[n]))s[n]=G(t[n],e[n],r);else if(ve(t[n],e[n]))s[n]=s[n].concat(e[n]);else if(!r)throw new Error(`Cannot merge objects: key "${n}" already exists in the target object`)}else s[n]=e[n]}),s}class ye{constructor(e="Anonymous"){p(this,"unsubscribers",new Set);this.name=e}add(...e){e.forEach(r=>{"dispose"in r?this.unsubscribers.add(r.dispose):this.unsubscribers.add(r)})}async runAllUnsubscribers(){const e=[...this.unsubscribers].map(s=>s()),r=await Promise.all(e);return this.unsubscribers.clear(),r.every((s,n)=>(s||console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${n} failed!`),s))}}class Ee{constructor(){p(this,"subscribe",this.event);p(this,"subscriptions");p(this,"lazyEvent");p(this,"isDisposed",!1);p(this,"dispose",()=>this.disposeFn());p(this,"emit",e=>{this.emitFn(e)})}get event(){return this.assertNotDisposed(),this.lazyEvent||(this.lazyEvent=e=>{if(!e||typeof e!="function")throw new Error("Event handler callback must be a function!");return this.subscriptions||(this.subscriptions=[]),this.subscriptions.push(e),()=>{if(!this.subscriptions)return!1;const r=this.subscriptions.indexOf(e);return r<0?!1:(this.subscriptions.splice(r,1),!0)}}),this.lazyEvent}emitFn(e){var r;this.assertNotDisposed(),(r=this.subscriptions)==null||r.forEach(s=>s(e))}assertNotDisposed(){if(this.isDisposed)throw new Error("Emitter is disposed")}disposeFn(){return this.assertNotDisposed(),this.isDisposed=!0,this.subscriptions=void 0,this.lazyEvent=void 0,Promise.resolve(!0)}}const U=[{shortName:"ERR",fullNames:["ERROR"],chapters:-1},{shortName:"GEN",fullNames:["Genesis"],chapters:50},{shortName:"EXO",fullNames:["Exodus"],chapters:40},{shortName:"LEV",fullNames:["Leviticus"],chapters:27},{shortName:"NUM",fullNames:["Numbers"],chapters:36},{shortName:"DEU",fullNames:["Deuteronomy"],chapters:34},{shortName:"JOS",fullNames:["Joshua"],chapters:24},{shortName:"JDG",fullNames:["Judges"],chapters:21},{shortName:"RUT",fullNames:["Ruth"],chapters:4},{shortName:"1SA",fullNames:["1 Samuel"],chapters:31},{shortName:"2SA",fullNames:["2 Samuel"],chapters:24},{shortName:"1KI",fullNames:["1 Kings"],chapters:22},{shortName:"2KI",fullNames:["2 Kings"],chapters:25},{shortName:"1CH",fullNames:["1 Chronicles"],chapters:29},{shortName:"2CH",fullNames:["2 Chronicles"],chapters:36},{shortName:"EZR",fullNames:["Ezra"],chapters:10},{shortName:"NEH",fullNames:["Nehemiah"],chapters:13},{shortName:"EST",fullNames:["Esther"],chapters:10},{shortName:"JOB",fullNames:["Job"],chapters:42},{shortName:"PSA",fullNames:["Psalm","Psalms"],chapters:150},{shortName:"PRO",fullNames:["Proverbs"],chapters:31},{shortName:"ECC",fullNames:["Ecclesiastes"],chapters:12},{shortName:"SNG",fullNames:["Song of Solomon","Song of Songs"],chapters:8},{shortName:"ISA",fullNames:["Isaiah"],chapters:66},{shortName:"JER",fullNames:["Jeremiah"],chapters:52},{shortName:"LAM",fullNames:["Lamentations"],chapters:5},{shortName:"EZK",fullNames:["Ezekiel"],chapters:48},{shortName:"DAN",fullNames:["Daniel"],chapters:12},{shortName:"HOS",fullNames:["Hosea"],chapters:14},{shortName:"JOL",fullNames:["Joel"],chapters:3},{shortName:"AMO",fullNames:["Amos"],chapters:9},{shortName:"OBA",fullNames:["Obadiah"],chapters:1},{shortName:"JON",fullNames:["Jonah"],chapters:4},{shortName:"MIC",fullNames:["Micah"],chapters:7},{shortName:"NAM",fullNames:["Nahum"],chapters:3},{shortName:"HAB",fullNames:["Habakkuk"],chapters:3},{shortName:"ZEP",fullNames:["Zephaniah"],chapters:3},{shortName:"HAG",fullNames:["Haggai"],chapters:2},{shortName:"ZEC",fullNames:["Zechariah"],chapters:14},{shortName:"MAL",fullNames:["Malachi"],chapters:4},{shortName:"MAT",fullNames:["Matthew"],chapters:28},{shortName:"MRK",fullNames:["Mark"],chapters:16},{shortName:"LUK",fullNames:["Luke"],chapters:24},{shortName:"JHN",fullNames:["John"],chapters:21},{shortName:"ACT",fullNames:["Acts"],chapters:28},{shortName:"ROM",fullNames:["Romans"],chapters:16},{shortName:"1CO",fullNames:["1 Corinthians"],chapters:16},{shortName:"2CO",fullNames:["2 Corinthians"],chapters:13},{shortName:"GAL",fullNames:["Galatians"],chapters:6},{shortName:"EPH",fullNames:["Ephesians"],chapters:6},{shortName:"PHP",fullNames:["Philippians"],chapters:4},{shortName:"COL",fullNames:["Colossians"],chapters:4},{shortName:"1TH",fullNames:["1 Thessalonians"],chapters:5},{shortName:"2TH",fullNames:["2 Thessalonians"],chapters:3},{shortName:"1TI",fullNames:["1 Timothy"],chapters:6},{shortName:"2TI",fullNames:["2 Timothy"],chapters:4},{shortName:"TIT",fullNames:["Titus"],chapters:3},{shortName:"PHM",fullNames:["Philemon"],chapters:1},{shortName:"HEB",fullNames:["Hebrews"],chapters:13},{shortName:"JAS",fullNames:["James"],chapters:5},{shortName:"1PE",fullNames:["1 Peter"],chapters:5},{shortName:"2PE",fullNames:["2 Peter"],chapters:3},{shortName:"1JN",fullNames:["1 John"],chapters:5},{shortName:"2JN",fullNames:["2 John"],chapters:1},{shortName:"3JN",fullNames:["3 John"],chapters:1},{shortName:"JUD",fullNames:["Jude"],chapters:1},{shortName:"REV",fullNames:["Revelation"],chapters:22}],V=1,F=U.length-1,H=1,k=1,K=t=>{var e;return((e=U[t])==null?void 0:e.chapters)??-1},we=(t,e)=>({bookNum:Math.max(V,Math.min(t.bookNum+e,F)),chapterNum:1,verseNum:1}),Oe=(t,e)=>({...t,chapterNum:Math.min(Math.max(H,t.chapterNum+e),K(t.bookNum)),verseNum:1}),$e=(t,e)=>({...t,verseNum:Math.max(k,t.verseNum+e)}),Ae=t=>(...e)=>t.map(s=>s(...e)).every(s=>s),qe=t=>async(...e)=>{const r=t.map(async s=>s(...e));return(await Promise.all(r)).every(s=>s)};var M=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},b={},Se=()=>{const t="\\ud800-\\udfff",e="\\u0300-\\u036f",r="\\ufe20-\\ufe2f",s="\\u20d0-\\u20ff",n="\\u1ab0-\\u1aff",a="\\u1dc0-\\u1dff",o=e+r+s+n+a,i="\\ufe0e\\ufe0f",c="\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93",h=`[${t}]`,u=`[${o}]`,l="\\ud83c[\\udffb-\\udfff]",f=`(?:${u}|${l})`,d=`[^${t}]`,m="(?:\\uD83C[\\uDDE6-\\uDDFF]){2}",v="[\\ud800-\\udbff][\\udc00-\\udfff]",$="\\u200d",ee="(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)",te=`[${c}]`,j=`${f}?`,C=`[${i}]?`,re=`(?:${$}(?:${[d,m,v].join("|")})${C+j})*`,se=C+j+re,ne=`(?:${[`${d}${u}?`,u,m,v,h,te].join("|")})`;return new RegExp(`${ee}|${l}(?=${l})|${ne+se}`,"g")},je=M&&M.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(b,"__esModule",{value:!0});var O=je(Se);function A(t){if(typeof t!="string")throw new Error("A string is expected as input");return t.match(O.default())||[]}var Ce=b.toArray=A;function S(t){if(typeof t!="string")throw new Error("Input must be a string");var e=t.match(O.default());return e===null?0:e.length}var Me=b.length=S;function L(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");(typeof e!="number"||e<0)&&(e=0),typeof r=="number"&&r<0&&(r=0);var s=t.match(O.default());return s?s.slice(e,r).join(""):""}var Pe=b.substring=L;function Te(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");var s=S(t);if(typeof e!="number"&&(e=parseInt(e,10)),e>=s)return"";e<0&&(e+=s);var n;typeof r>"u"?n=s:(typeof r!="number"&&(r=parseInt(r,10)),n=r>=0?r+e:e);var a=t.match(O.default());return a?a.slice(e,n).join(""):""}b.substr=Te;function Re(t,e,r,s){if(e===void 0&&(e=16),r===void 0&&(r="#"),s===void 0&&(s="right"),typeof t!="string"||typeof e!="number")throw new Error("Invalid arguments specified");if(["left","right"].indexOf(s)===-1)throw new Error("Pad position should be either left or right");typeof r!="string"&&(r=String(r));var n=S(t);if(n>e)return L(t,0,e);if(n=s.length)return e===""?s.length:-1;if(e==="")return r;var n=A(e),a=!1,o;for(o=r;o{W(t,e,r,"left")},Ge=(t,e,r)=>{W(t,e,r,"right")},Ue=(t,e="NFC")=>{const r=e.toUpperCase();return r==="NONE"?t:t.normalize(r)};var Ve=Object.getOwnPropertyNames,Fe=Object.getOwnPropertySymbols,He=Object.prototype.hasOwnProperty;function P(t,e){return function(s,n,a){return t(s,n,a)&&e(s,n,a)}}function w(t){return function(r,s,n){if(!r||!s||typeof r!="object"||typeof s!="object")return t(r,s,n);var a=n.cache,o=a.get(r),i=a.get(s);if(o&&i)return o===s&&i===r;a.set(r,s),a.set(s,r);var c=t(r,s,n);return a.delete(r),a.delete(s),c}}function T(t){return Ve(t).concat(Fe(t))}var Z=Object.hasOwn||function(t,e){return He.call(t,e)};function N(t,e){return t||e?t===e:t===e||t!==t&&e!==e}var X="_owner",R=Object.getOwnPropertyDescriptor,D=Object.keys;function ke(t,e,r){var s=t.length;if(e.length!==s)return!1;for(;s-- >0;)if(!r.equals(t[s],e[s],s,s,t,e,r))return!1;return!0}function Ke(t,e){return N(t.getTime(),e.getTime())}function I(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.entries(),a=0,o,i;(o=n.next())&&!o.done;){for(var c=e.entries(),h=!1,u=0;(i=c.next())&&!i.done;){var l=o.value,f=l[0],d=l[1],m=i.value,v=m[0],$=m[1];!h&&!s[u]&&(h=r.equals(f,v,a,u,t,e,r)&&r.equals(d,$,f,v,t,e,r))&&(s[u]=!0),u++}if(!h)return!1;a++}return!0}function Le(t,e,r){var s=D(t),n=s.length;if(D(e).length!==n)return!1;for(var a;n-- >0;)if(a=s[n],a===X&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!Z(e,a)||!r.equals(t[a],e[a],a,a,t,e,r))return!1;return!0}function y(t,e,r){var s=T(t),n=s.length;if(T(e).length!==n)return!1;for(var a,o,i;n-- >0;)if(a=s[n],a===X&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!Z(e,a)||!r.equals(t[a],e[a],a,a,t,e,r)||(o=R(t,a),i=R(e,a),(o||i)&&(!o||!i||o.configurable!==i.configurable||o.enumerable!==i.enumerable||o.writable!==i.writable)))return!1;return!0}function We(t,e){return N(t.valueOf(),e.valueOf())}function Ze(t,e){return t.source===e.source&&t.flags===e.flags}function x(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.values(),a,o;(a=n.next())&&!a.done;){for(var i=e.values(),c=!1,h=0;(o=i.next())&&!o.done;)!c&&!s[h]&&(c=r.equals(a.value,o.value,a.value,o.value,t,e,r))&&(s[h]=!0),h++;if(!c)return!1}return!0}function Xe(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}var Qe="[object Arguments]",Ye="[object Boolean]",et="[object Date]",tt="[object Map]",rt="[object Number]",st="[object Object]",nt="[object RegExp]",at="[object Set]",ot="[object String]",it=Array.isArray,_=typeof ArrayBuffer=="function"&&ArrayBuffer.isView?ArrayBuffer.isView:null,z=Object.assign,ut=Object.prototype.toString.call.bind(Object.prototype.toString);function lt(t){var e=t.areArraysEqual,r=t.areDatesEqual,s=t.areMapsEqual,n=t.areObjectsEqual,a=t.arePrimitiveWrappersEqual,o=t.areRegExpsEqual,i=t.areSetsEqual,c=t.areTypedArraysEqual;return function(u,l,f){if(u===l)return!0;if(u==null||l==null||typeof u!="object"||typeof l!="object")return u!==u&&l!==l;var d=u.constructor;if(d!==l.constructor)return!1;if(d===Object)return n(u,l,f);if(it(u))return e(u,l,f);if(_!=null&&_(u))return c(u,l,f);if(d===Date)return r(u,l,f);if(d===RegExp)return o(u,l,f);if(d===Map)return s(u,l,f);if(d===Set)return i(u,l,f);var m=ut(u);return m===et?r(u,l,f):m===nt?o(u,l,f):m===tt?s(u,l,f):m===at?i(u,l,f):m===st?typeof u.then!="function"&&typeof l.then!="function"&&n(u,l,f):m===Qe?n(u,l,f):m===Ye||m===rt||m===ot?a(u,l,f):!1}}function ct(t){var e=t.circular,r=t.createCustomConfig,s=t.strict,n={areArraysEqual:s?y:ke,areDatesEqual:Ke,areMapsEqual:s?P(I,y):I,areObjectsEqual:s?y:Le,arePrimitiveWrappersEqual:We,areRegExpsEqual:Ze,areSetsEqual:s?P(x,y):x,areTypedArraysEqual:s?y:Xe};if(r&&(n=z({},n,r(n))),e){var a=w(n.areArraysEqual),o=w(n.areMapsEqual),i=w(n.areObjectsEqual),c=w(n.areSetsEqual);n=z({},n,{areArraysEqual:a,areMapsEqual:o,areObjectsEqual:i,areSetsEqual:c})}return n}function ft(t){return function(e,r,s,n,a,o,i){return t(e,r,i)}}function ht(t){var e=t.circular,r=t.comparator,s=t.createState,n=t.equals,a=t.strict;if(s)return function(c,h){var u=s(),l=u.cache,f=l===void 0?e?new WeakMap:void 0:l,d=u.meta;return r(c,h,{cache:f,equals:n,meta:d,strict:a})};if(e)return function(c,h){return r(c,h,{cache:new WeakMap,equals:n,meta:void 0,strict:a})};var o={cache:void 0,equals:n,meta:void 0,strict:a};return function(c,h){return r(c,h,o)}}var pt=g();g({strict:!0});g({circular:!0});g({circular:!0,strict:!0});g({createInternalComparator:function(){return N}});g({strict:!0,createInternalComparator:function(){return N}});g({circular:!0,createInternalComparator:function(){return N}});g({circular:!0,createInternalComparator:function(){return N},strict:!0});function g(t){t===void 0&&(t={});var e=t.circular,r=e===void 0?!1:e,s=t.createInternalComparator,n=t.createState,a=t.strict,o=a===void 0?!1:a,i=ct(t),c=lt(i),h=s?s(c):ft(c);return ht({circular:r,comparator:c,createState:n,equals:h,strict:o})}function mt(t,e){return pt(t,e)}function q(t,e,r){return JSON.stringify(t,(n,a)=>{let o=a;return e&&(o=e(n,o)),o===void 0&&(o=null),o},r)}function Q(t,e){function r(n){return Object.keys(n).forEach(a=>{n[a]===null?n[a]=void 0:typeof n[a]=="object"&&(n[a]=r(n[a]))}),n}const s=JSON.parse(t,e);if(s!==null)return typeof s=="object"?r(s):s}function dt(t){try{const e=q(t);return e===q(Q(e))}catch{return!1}}const gt=t=>t.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/"),Y={title:"Platform.Bible menus",type:"object",properties:{mainMenu:{description:"Top level menu for the application",$ref:"#/$defs/multiColumnMenu"},defaultWebViewTopMenu:{description:"Default top menu for web views that don't specify their own",$ref:"#/$defs/multiColumnMenu"},defaultWebViewContextMenu:{description:"Default context menu for web views that don't specify their own",$ref:"#/$defs/singleColumnMenu"},webViewMenus:{description:"Menus that apply per web view in the application",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{$ref:"#/$defs/menusForOneWebView"}},additionalProperties:!1}},required:["mainMenu","defaultWebViewTopMenu","defaultWebViewContextMenu","webViewMenus"],additionalProperties:!1,$defs:{localizeKey:{description:"Identifier for a string that will be localized in a menu based on the user's UI language",type:"string",pattern:"^%[\\w\\-\\.]+%$"},referencedItem:{description:"Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)",type:"string",pattern:"^[\\w\\-]+\\.[\\w\\-]+$"},columnsWithHeaders:{description:"Group of columns that can be combined with other columns to form a multi-column menu",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single column with a header string",type:"object",properties:{label:{description:"Header text for this this column in the UI",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},order:{description:"Relative order of this column compared to other columns (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu groups to this column",type:"boolean"}},required:["label","order"],additionalProperties:!1}},properties:{isExtensible:{description:"Defines whether contributions are allowed to add columns to this multi-column menu",type:"boolean"}}},menuGroups:{description:"Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single group that contains menu items",type:"object",oneOf:[{properties:{column:{description:"Column where this group belongs, not required for single column menus",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["order"],additionalProperties:!1},{properties:{menuItem:{description:"Menu item that anchors the submenu where this group belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["menuItem","order"],additionalProperties:!1}]}},additionalProperties:!1},menuItem:{description:"Single item in a menu that can be clicked on to take an action or can be the parent of a submenu",type:"object",oneOf:[{properties:{id:{description:"ID for this menu item that holds a submenu",$ref:"#/$defs/referencedItem"}},required:["id"]},{properties:{command:{description:"Name of the PAPI command to run when this menu item is selected.",$ref:"#/$defs/referencedItem"},iconPathBefore:{description:"Path to the icon to display before the menu text",type:"string"},iconPathAfter:{description:"Path to the icon to display after the menu text",type:"string"}},required:["command"]}],properties:{label:{description:"Key that represents the text of this menu item to display",$ref:"#/$defs/localizeKey"},tooltip:{description:"Key that represents the text to display if a mouse pointer hovers over the menu item",$ref:"#/$defs/localizeKey"},searchTerms:{description:"Key that represents additional words the platform should reference when users are searching for menu items",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},group:{description:"Group to which this menu item belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this menu item compared to other menu items in the same group (sorted ascending)",type:"number"}},required:["label","group","order"],unevaluatedProperties:!1},groupsAndItems:{description:"Core schema for a column",type:"object",properties:{groups:{description:"Groups that belong in this menu",$ref:"#/$defs/menuGroups"},items:{description:"List of menu items that belong in this menu",type:"array",items:{$ref:"#/$defs/menuItem"},uniqueItems:!0}},required:["groups","items"]},singleColumnMenu:{description:"Menu that contains a column without a header",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"}],unevaluatedProperties:!1},multiColumnMenu:{description:"Menu that can contain multiple columns with headers",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"},{properties:{columns:{description:"Columns that belong in this menu",$ref:"#/$defs/columnsWithHeaders"}},required:["columns"]}],unevaluatedProperties:!1},menusForOneWebView:{description:"Set of menus that are associated with a single tab",type:"object",properties:{includeDefaults:{description:"Indicates whether the platform default menus should be included for this webview",type:"boolean"},topMenu:{description:"Menu that opens when you click on the top left corner of a tab",$ref:"#/$defs/multiColumnMenu"},contextMenu:{description:"Menu that opens when you right click on the main body/area of a tab",$ref:"#/$defs/singleColumnMenu"}},additionalProperties:!1}}};Object.freeze(Y);exports.AsyncVariable=ie;exports.DocumentCombinerEngine=be;exports.FIRST_SCR_BOOK_NUM=V;exports.FIRST_SCR_CHAPTER_NUM=H;exports.FIRST_SCR_VERSE_NUM=k;exports.LAST_SCR_BOOK_NUM=F;exports.PlatformEventEmitter=Ee;exports.UnsubscriberAsyncList=ye;exports.aggregateUnsubscriberAsyncs=qe;exports.aggregateUnsubscribers=Ae;exports.createSyncProxyForAsyncObject=ge;exports.debounce=le;exports.deepClone=E;exports.deepEqual=mt;exports.deserialize=Q;exports.getAllObjectFunctionNames=de;exports.getChaptersForBook=K;exports.getErrorMessage=pe;exports.groupBy=ce;exports.htmlEncode=gt;exports.indexOf=xe;exports.isSerializable=dt;exports.isString=B;exports.length=ze;exports.menuDocumentSchema=Y;exports.newGuid=ue;exports.normalize=Ue;exports.offsetBook=we;exports.offsetChapter=Oe;exports.offsetVerse=$e;exports.padEnd=Ge;exports.padStart=Je;exports.serialize=q;exports.substring=_e;exports.toArray=Be;exports.wait=J;exports.waitForDuration=me; +"use strict";var fe=Object.defineProperty;var he=(t,e,r)=>e in t?fe(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var p=(t,e,r)=>(he(t,typeof e!="symbol"?e+"":e,r),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class pe{constructor(e,r=1e4){p(this,"variableName");p(this,"promiseToValue");p(this,"resolver");p(this,"rejecter");this.variableName=e,this.promiseToValue=new Promise((s,n)=>{this.resolver=s,this.rejecter=n}),r>0&&setTimeout(()=>{this.rejecter&&(this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`),this.complete())},r),Object.seal(this)}get promise(){return this.promiseToValue}get hasSettled(){return Object.isFrozen(this)}resolveToValue(e,r=!1){if(this.resolver)console.debug(`${this.variableName} is being resolved now`),this.resolver(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent resolution of ${this.variableName}`)}}rejectWithReason(e,r=!1){if(this.rejecter)console.debug(`${this.variableName} is being rejected now`),this.rejecter(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent rejection of ${this.variableName}`)}}complete(){this.resolver=void 0,this.rejecter=void 0,Object.freeze(this)}}function me(){return"00-0-4-1-000".replace(/[^-]/g,t=>((Math.random()+~~t)*65536>>t).toString(16).padStart(4,"0"))}function V(t){return typeof t=="string"||t instanceof String}function E(t){return JSON.parse(JSON.stringify(t))}function de(t,e=300){if(V(t))throw new Error("Tried to debounce a string! Could be XSS");let r;return(...s)=>{clearTimeout(r),r=setTimeout(()=>t(...s),e)}}function be(t,e,r){const s=new Map;return t.forEach(n=>{const o=e(n),a=s.get(o),i=r?r(n,o):n;a?a.push(i):s.set(o,[i])}),s}function Ne(t){return typeof t=="object"&&t!==null&&"message"in t&&typeof t.message=="string"}function ge(t){if(Ne(t))return t;try{return new Error(JSON.stringify(t))}catch{return new Error(String(t))}}function ve(t){return ge(t).message}function F(t){return new Promise(e=>setTimeout(e,t))}function ye(t,e){const r=F(e).then(()=>{});return Promise.any([r,t()])}function we(t,e="obj"){const r=new Set;Object.getOwnPropertyNames(t).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e} due to error: ${o}`)}});let s=Object.getPrototypeOf(t);for(;s&&Object.getPrototypeOf(s);)Object.getOwnPropertyNames(s).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e}'s prototype due to error: ${o}`)}}),s=Object.getPrototypeOf(s);return r}function Ee(t,e={}){return new Proxy(e,{get(r,s){return s in r?r[s]:async(...n)=>(await t())[s](...n)}})}class Oe{constructor(e,r){p(this,"baseDocument");p(this,"contributions",new Map);p(this,"latestOutput");p(this,"options");this.baseDocument=e,this.options=r,this.updateBaseDocument(e)}updateBaseDocument(e){return this.validateStartingDocument(e),this.baseDocument=this.options.copyDocuments?E(e):e,this.rebuild()}addOrUpdateContribution(e,r){this.validateContribution(e,r);const s=this.contributions.get(e),n=this.options.copyDocuments&&r?E(r):r;this.contributions.set(e,n);try{return this.rebuild()}catch(o){throw s?this.contributions.set(e,s):this.contributions.delete(e),new Error(`Error when setting the document named ${e}: ${o}`)}}deleteContribution(e){const r=this.contributions.get(e);if(!r)throw new Error("{documentKey} does not exist");this.contributions.delete(e);try{return this.rebuild()}catch(s){throw this.contributions.set(e,r),new Error(`Error when deleting the document named ${e}: ${s}`)}}rebuild(){if(this.contributions.size===0){let r=E(this.baseDocument);return r=this.transformFinalOutput(r),this.validateOutput(r),this.latestOutput=r,this.latestOutput}let e=this.baseDocument;return this.contributions.forEach(r=>{e=H(e,r,this.options.ignoreDuplicateProperties),this.validateOutput(e)}),e=this.transformFinalOutput(e),this.validateOutput(e),this.latestOutput=e,this.latestOutput}}function $e(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||Array.isArray(r))&&(e=!1)}),e}function Ae(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||!Array.isArray(r))&&(e=!1)}),e}function H(t,e,r){const s=E(t);return e&&Object.keys(e).forEach(n=>{if(Object.hasOwn(t,n)){if($e(t[n],e[n]))s[n]=H(t[n],e[n],r);else if(Ae(t[n],e[n]))s[n]=s[n].concat(e[n]);else if(!r)throw new Error(`Cannot merge objects: key "${n}" already exists in the target object`)}else s[n]=e[n]}),s}class qe{constructor(e="Anonymous"){p(this,"unsubscribers",new Set);this.name=e}add(...e){e.forEach(r=>{"dispose"in r?this.unsubscribers.add(r.dispose):this.unsubscribers.add(r)})}async runAllUnsubscribers(){const e=[...this.unsubscribers].map(s=>s()),r=await Promise.all(e);return this.unsubscribers.clear(),r.every((s,n)=>(s||console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${n} failed!`),s))}}class Se{constructor(){p(this,"subscribe",this.event);p(this,"subscriptions");p(this,"lazyEvent");p(this,"isDisposed",!1);p(this,"dispose",()=>this.disposeFn());p(this,"emit",e=>{this.emitFn(e)})}get event(){return this.assertNotDisposed(),this.lazyEvent||(this.lazyEvent=e=>{if(!e||typeof e!="function")throw new Error("Event handler callback must be a function!");return this.subscriptions||(this.subscriptions=[]),this.subscriptions.push(e),()=>{if(!this.subscriptions)return!1;const r=this.subscriptions.indexOf(e);return r<0?!1:(this.subscriptions.splice(r,1),!0)}}),this.lazyEvent}emitFn(e){var r;this.assertNotDisposed(),(r=this.subscriptions)==null||r.forEach(s=>s(e))}assertNotDisposed(){if(this.isDisposed)throw new Error("Emitter is disposed")}disposeFn(){return this.assertNotDisposed(),this.isDisposed=!0,this.subscriptions=void 0,this.lazyEvent=void 0,Promise.resolve(!0)}}const k=[{shortName:"ERR",fullNames:["ERROR"],chapters:-1},{shortName:"GEN",fullNames:["Genesis"],chapters:50},{shortName:"EXO",fullNames:["Exodus"],chapters:40},{shortName:"LEV",fullNames:["Leviticus"],chapters:27},{shortName:"NUM",fullNames:["Numbers"],chapters:36},{shortName:"DEU",fullNames:["Deuteronomy"],chapters:34},{shortName:"JOS",fullNames:["Joshua"],chapters:24},{shortName:"JDG",fullNames:["Judges"],chapters:21},{shortName:"RUT",fullNames:["Ruth"],chapters:4},{shortName:"1SA",fullNames:["1 Samuel"],chapters:31},{shortName:"2SA",fullNames:["2 Samuel"],chapters:24},{shortName:"1KI",fullNames:["1 Kings"],chapters:22},{shortName:"2KI",fullNames:["2 Kings"],chapters:25},{shortName:"1CH",fullNames:["1 Chronicles"],chapters:29},{shortName:"2CH",fullNames:["2 Chronicles"],chapters:36},{shortName:"EZR",fullNames:["Ezra"],chapters:10},{shortName:"NEH",fullNames:["Nehemiah"],chapters:13},{shortName:"EST",fullNames:["Esther"],chapters:10},{shortName:"JOB",fullNames:["Job"],chapters:42},{shortName:"PSA",fullNames:["Psalm","Psalms"],chapters:150},{shortName:"PRO",fullNames:["Proverbs"],chapters:31},{shortName:"ECC",fullNames:["Ecclesiastes"],chapters:12},{shortName:"SNG",fullNames:["Song of Solomon","Song of Songs"],chapters:8},{shortName:"ISA",fullNames:["Isaiah"],chapters:66},{shortName:"JER",fullNames:["Jeremiah"],chapters:52},{shortName:"LAM",fullNames:["Lamentations"],chapters:5},{shortName:"EZK",fullNames:["Ezekiel"],chapters:48},{shortName:"DAN",fullNames:["Daniel"],chapters:12},{shortName:"HOS",fullNames:["Hosea"],chapters:14},{shortName:"JOL",fullNames:["Joel"],chapters:3},{shortName:"AMO",fullNames:["Amos"],chapters:9},{shortName:"OBA",fullNames:["Obadiah"],chapters:1},{shortName:"JON",fullNames:["Jonah"],chapters:4},{shortName:"MIC",fullNames:["Micah"],chapters:7},{shortName:"NAM",fullNames:["Nahum"],chapters:3},{shortName:"HAB",fullNames:["Habakkuk"],chapters:3},{shortName:"ZEP",fullNames:["Zephaniah"],chapters:3},{shortName:"HAG",fullNames:["Haggai"],chapters:2},{shortName:"ZEC",fullNames:["Zechariah"],chapters:14},{shortName:"MAL",fullNames:["Malachi"],chapters:4},{shortName:"MAT",fullNames:["Matthew"],chapters:28},{shortName:"MRK",fullNames:["Mark"],chapters:16},{shortName:"LUK",fullNames:["Luke"],chapters:24},{shortName:"JHN",fullNames:["John"],chapters:21},{shortName:"ACT",fullNames:["Acts"],chapters:28},{shortName:"ROM",fullNames:["Romans"],chapters:16},{shortName:"1CO",fullNames:["1 Corinthians"],chapters:16},{shortName:"2CO",fullNames:["2 Corinthians"],chapters:13},{shortName:"GAL",fullNames:["Galatians"],chapters:6},{shortName:"EPH",fullNames:["Ephesians"],chapters:6},{shortName:"PHP",fullNames:["Philippians"],chapters:4},{shortName:"COL",fullNames:["Colossians"],chapters:4},{shortName:"1TH",fullNames:["1 Thessalonians"],chapters:5},{shortName:"2TH",fullNames:["2 Thessalonians"],chapters:3},{shortName:"1TI",fullNames:["1 Timothy"],chapters:6},{shortName:"2TI",fullNames:["2 Timothy"],chapters:4},{shortName:"TIT",fullNames:["Titus"],chapters:3},{shortName:"PHM",fullNames:["Philemon"],chapters:1},{shortName:"HEB",fullNames:["Hebrews"],chapters:13},{shortName:"JAS",fullNames:["James"],chapters:5},{shortName:"1PE",fullNames:["1 Peter"],chapters:5},{shortName:"2PE",fullNames:["2 Peter"],chapters:3},{shortName:"1JN",fullNames:["1 John"],chapters:5},{shortName:"2JN",fullNames:["2 John"],chapters:1},{shortName:"3JN",fullNames:["3 John"],chapters:1},{shortName:"JUD",fullNames:["Jude"],chapters:1},{shortName:"REV",fullNames:["Revelation"],chapters:22}],K=1,W=k.length-1,L=1,Z=1,X=t=>{var e;return((e=k[t])==null?void 0:e.chapters)??-1},je=(t,e)=>({bookNum:Math.max(K,Math.min(t.bookNum+e,W)),chapterNum:1,verseNum:1}),Ce=(t,e)=>({...t,chapterNum:Math.min(Math.max(L,t.chapterNum+e),X(t.bookNum)),verseNum:1}),Me=(t,e)=>({...t,verseNum:Math.max(Z,t.verseNum+e)}),Pe=t=>(...e)=>t.map(s=>s(...e)).every(s=>s),Te=t=>async(...e)=>{const r=t.map(async s=>s(...e));return(await Promise.all(r)).every(s=>s)};var R=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},g={},Re=()=>{const t="\\ud800-\\udfff",e="\\u0300-\\u036f",r="\\ufe20-\\ufe2f",s="\\u20d0-\\u20ff",n="\\u1ab0-\\u1aff",o="\\u1dc0-\\u1dff",a=e+r+s+n+o,i="\\ufe0e\\ufe0f",c="\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93",h=`[${t}]`,u=`[${a}]`,l="\\ud83c[\\udffb-\\udfff]",f=`(?:${u}|${l})`,b=`[^${t}]`,m="(?:\\uD83C[\\uDDE6-\\uDDFF]){2}",y="[\\ud800-\\udbff][\\udc00-\\udfff]",q="\\u200d",ae="(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)",ie=`[${c}]`,P=`${f}?`,T=`[${i}]?`,ue=`(?:${q}(?:${[b,m,y].join("|")})${T+P})*`,le=T+P+ue,ce=`(?:${[`${b}${u}?`,u,m,y,h,ie].join("|")})`;return new RegExp(`${ae}|${l}(?=${l})|${ce+le}`,"g")},De=R&&R.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(g,"__esModule",{value:!0});var $=De(Re);function S(t){if(typeof t!="string")throw new Error("A string is expected as input");return t.match($.default())||[]}var Ie=g.toArray=S;function C(t){if(typeof t!="string")throw new Error("Input must be a string");var e=t.match($.default());return e===null?0:e.length}var _e=g.length=C;function Q(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");(typeof e!="number"||e<0)&&(e=0),typeof r=="number"&&r<0&&(r=0);var s=t.match($.default());return s?s.slice(e,r).join(""):""}var ze=g.substring=Q;function Be(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");var s=C(t);if(typeof e!="number"&&(e=parseInt(e,10)),e>=s)return"";e<0&&(e+=s);var n;typeof r>"u"?n=s:(typeof r!="number"&&(r=parseInt(r,10)),n=r>=0?r+e:e);var o=t.match($.default());return o?o.slice(e,n).join(""):""}var Je=g.substr=Be;function xe(t,e,r,s){if(e===void 0&&(e=16),r===void 0&&(r="#"),s===void 0&&(s="right"),typeof t!="string"||typeof e!="number")throw new Error("Invalid arguments specified");if(["left","right"].indexOf(s)===-1)throw new Error("Pad position should be either left or right");typeof r!="string"&&(r=String(r));var n=C(t);if(n>e)return Q(t,0,e);if(n=s.length)return e===""?s.length:-1;if(e==="")return r;var n=S(e),o=!1,a;for(a=r;ad(t)||e<-d(t)))return A(t,e,1)}function Fe(t,e){return e<0||e>d(t)-1?"":A(t,e,1)}function He(t,e){if(!(e<0||e>d(t)-1))return A(t,e,1).codePointAt(0)}function ke(t,e,r=d(t)){const s=te(t,e);return!(s===-1||s+d(e)!==r)}function Ke(t,e,r=0){const s=M(t,r);return ee(s,e)!==-1}function ee(t,e,r=0){return Ue(t,e,r)}function te(t,e,r=1/0){let s=r;s<0?s=0:s>=d(t)&&(s=d(t)-1);for(let n=s;n>=0;n--)if(A(t,n,d(e))===e)return n;return-1}function d(t){return _e(t)}function We(t,e){const r=e.toUpperCase();return r==="NONE"?t:t.normalize(r)}function Le(t,e,r=" "){return e<=d(t)?t:Y(t,e,r,"right")}function Ze(t,e,r=" "){return e<=d(t)?t:Y(t,e,r,"left")}function D(t,e){return e>t?t:e<-t?0:e<0?e+t:e}function Xe(t,e,r){const s=d(t);if(e>s||r&&(e>r&&!(e>0&&e-s)||r<-s||e<0&&e>-s&&r>0))return"";const n=D(s,e),o=r?D(s,r):void 0;return M(t,n,o)}function A(t,e=0,r=d(t)-e){return Je(t,e,r)}function M(t,e,r=d(t)){return ze(t,e,r)}function Qe(t){return Ie(t)}var Ye=Object.getOwnPropertyNames,et=Object.getOwnPropertySymbols,tt=Object.prototype.hasOwnProperty;function I(t,e){return function(s,n,o){return t(s,n,o)&&e(s,n,o)}}function O(t){return function(r,s,n){if(!r||!s||typeof r!="object"||typeof s!="object")return t(r,s,n);var o=n.cache,a=o.get(r),i=o.get(s);if(a&&i)return a===s&&i===r;o.set(r,s),o.set(s,r);var c=t(r,s,n);return o.delete(r),o.delete(s),c}}function _(t){return Ye(t).concat(et(t))}var re=Object.hasOwn||function(t,e){return tt.call(t,e)};function v(t,e){return t||e?t===e:t===e||t!==t&&e!==e}var se="_owner",z=Object.getOwnPropertyDescriptor,B=Object.keys;function rt(t,e,r){var s=t.length;if(e.length!==s)return!1;for(;s-- >0;)if(!r.equals(t[s],e[s],s,s,t,e,r))return!1;return!0}function st(t,e){return v(t.getTime(),e.getTime())}function J(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.entries(),o=0,a,i;(a=n.next())&&!a.done;){for(var c=e.entries(),h=!1,u=0;(i=c.next())&&!i.done;){var l=a.value,f=l[0],b=l[1],m=i.value,y=m[0],q=m[1];!h&&!s[u]&&(h=r.equals(f,y,o,u,t,e,r)&&r.equals(b,q,f,y,t,e,r))&&(s[u]=!0),u++}if(!h)return!1;o++}return!0}function nt(t,e,r){var s=B(t),n=s.length;if(B(e).length!==n)return!1;for(var o;n-- >0;)if(o=s[n],o===se&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!re(e,o)||!r.equals(t[o],e[o],o,o,t,e,r))return!1;return!0}function w(t,e,r){var s=_(t),n=s.length;if(_(e).length!==n)return!1;for(var o,a,i;n-- >0;)if(o=s[n],o===se&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!re(e,o)||!r.equals(t[o],e[o],o,o,t,e,r)||(a=z(t,o),i=z(e,o),(a||i)&&(!a||!i||a.configurable!==i.configurable||a.enumerable!==i.enumerable||a.writable!==i.writable)))return!1;return!0}function ot(t,e){return v(t.valueOf(),e.valueOf())}function at(t,e){return t.source===e.source&&t.flags===e.flags}function x(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.values(),o,a;(o=n.next())&&!o.done;){for(var i=e.values(),c=!1,h=0;(a=i.next())&&!a.done;)!c&&!s[h]&&(c=r.equals(o.value,a.value,o.value,a.value,t,e,r))&&(s[h]=!0),h++;if(!c)return!1}return!0}function it(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}var ut="[object Arguments]",lt="[object Boolean]",ct="[object Date]",ft="[object Map]",ht="[object Number]",pt="[object Object]",mt="[object RegExp]",dt="[object Set]",bt="[object String]",Nt=Array.isArray,G=typeof ArrayBuffer=="function"&&ArrayBuffer.isView?ArrayBuffer.isView:null,U=Object.assign,gt=Object.prototype.toString.call.bind(Object.prototype.toString);function vt(t){var e=t.areArraysEqual,r=t.areDatesEqual,s=t.areMapsEqual,n=t.areObjectsEqual,o=t.arePrimitiveWrappersEqual,a=t.areRegExpsEqual,i=t.areSetsEqual,c=t.areTypedArraysEqual;return function(u,l,f){if(u===l)return!0;if(u==null||l==null||typeof u!="object"||typeof l!="object")return u!==u&&l!==l;var b=u.constructor;if(b!==l.constructor)return!1;if(b===Object)return n(u,l,f);if(Nt(u))return e(u,l,f);if(G!=null&&G(u))return c(u,l,f);if(b===Date)return r(u,l,f);if(b===RegExp)return a(u,l,f);if(b===Map)return s(u,l,f);if(b===Set)return i(u,l,f);var m=gt(u);return m===ct?r(u,l,f):m===mt?a(u,l,f):m===ft?s(u,l,f):m===dt?i(u,l,f):m===pt?typeof u.then!="function"&&typeof l.then!="function"&&n(u,l,f):m===ut?n(u,l,f):m===lt||m===ht||m===bt?o(u,l,f):!1}}function yt(t){var e=t.circular,r=t.createCustomConfig,s=t.strict,n={areArraysEqual:s?w:rt,areDatesEqual:st,areMapsEqual:s?I(J,w):J,areObjectsEqual:s?w:nt,arePrimitiveWrappersEqual:ot,areRegExpsEqual:at,areSetsEqual:s?I(x,w):x,areTypedArraysEqual:s?w:it};if(r&&(n=U({},n,r(n))),e){var o=O(n.areArraysEqual),a=O(n.areMapsEqual),i=O(n.areObjectsEqual),c=O(n.areSetsEqual);n=U({},n,{areArraysEqual:o,areMapsEqual:a,areObjectsEqual:i,areSetsEqual:c})}return n}function wt(t){return function(e,r,s,n,o,a,i){return t(e,r,i)}}function Et(t){var e=t.circular,r=t.comparator,s=t.createState,n=t.equals,o=t.strict;if(s)return function(c,h){var u=s(),l=u.cache,f=l===void 0?e?new WeakMap:void 0:l,b=u.meta;return r(c,h,{cache:f,equals:n,meta:b,strict:o})};if(e)return function(c,h){return r(c,h,{cache:new WeakMap,equals:n,meta:void 0,strict:o})};var a={cache:void 0,equals:n,meta:void 0,strict:o};return function(c,h){return r(c,h,a)}}var Ot=N();N({strict:!0});N({circular:!0});N({circular:!0,strict:!0});N({createInternalComparator:function(){return v}});N({strict:!0,createInternalComparator:function(){return v}});N({circular:!0,createInternalComparator:function(){return v}});N({circular:!0,createInternalComparator:function(){return v},strict:!0});function N(t){t===void 0&&(t={});var e=t.circular,r=e===void 0?!1:e,s=t.createInternalComparator,n=t.createState,o=t.strict,a=o===void 0?!1:o,i=yt(t),c=vt(i),h=s?s(c):wt(c);return Et({circular:r,comparator:c,createState:n,equals:h,strict:a})}function $t(t,e){return Ot(t,e)}function j(t,e,r){return JSON.stringify(t,(n,o)=>{let a=o;return e&&(a=e(n,a)),a===void 0&&(a=null),a},r)}function ne(t,e){function r(n){return Object.keys(n).forEach(o=>{n[o]===null?n[o]=void 0:typeof n[o]=="object"&&(n[o]=r(n[o]))}),n}const s=JSON.parse(t,e);if(s!==null)return typeof s=="object"?r(s):s}function At(t){try{const e=j(t);return e===j(ne(e))}catch{return!1}}const qt=t=>t.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/"),oe={title:"Platform.Bible menus",type:"object",properties:{mainMenu:{description:"Top level menu for the application",$ref:"#/$defs/multiColumnMenu"},defaultWebViewTopMenu:{description:"Default top menu for web views that don't specify their own",$ref:"#/$defs/multiColumnMenu"},defaultWebViewContextMenu:{description:"Default context menu for web views that don't specify their own",$ref:"#/$defs/singleColumnMenu"},webViewMenus:{description:"Menus that apply per web view in the application",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{$ref:"#/$defs/menusForOneWebView"}},additionalProperties:!1}},required:["mainMenu","defaultWebViewTopMenu","defaultWebViewContextMenu","webViewMenus"],additionalProperties:!1,$defs:{localizeKey:{description:"Identifier for a string that will be localized in a menu based on the user's UI language",type:"string",pattern:"^%[\\w\\-\\.]+%$"},referencedItem:{description:"Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)",type:"string",pattern:"^[\\w\\-]+\\.[\\w\\-]+$"},columnsWithHeaders:{description:"Group of columns that can be combined with other columns to form a multi-column menu",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single column with a header string",type:"object",properties:{label:{description:"Header text for this this column in the UI",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},order:{description:"Relative order of this column compared to other columns (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu groups to this column",type:"boolean"}},required:["label","order"],additionalProperties:!1}},properties:{isExtensible:{description:"Defines whether contributions are allowed to add columns to this multi-column menu",type:"boolean"}}},menuGroups:{description:"Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single group that contains menu items",type:"object",oneOf:[{properties:{column:{description:"Column where this group belongs, not required for single column menus",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["order"],additionalProperties:!1},{properties:{menuItem:{description:"Menu item that anchors the submenu where this group belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["menuItem","order"],additionalProperties:!1}]}},additionalProperties:!1},menuItem:{description:"Single item in a menu that can be clicked on to take an action or can be the parent of a submenu",type:"object",oneOf:[{properties:{id:{description:"ID for this menu item that holds a submenu",$ref:"#/$defs/referencedItem"}},required:["id"]},{properties:{command:{description:"Name of the PAPI command to run when this menu item is selected.",$ref:"#/$defs/referencedItem"},iconPathBefore:{description:"Path to the icon to display before the menu text",type:"string"},iconPathAfter:{description:"Path to the icon to display after the menu text",type:"string"}},required:["command"]}],properties:{label:{description:"Key that represents the text of this menu item to display",$ref:"#/$defs/localizeKey"},tooltip:{description:"Key that represents the text to display if a mouse pointer hovers over the menu item",$ref:"#/$defs/localizeKey"},searchTerms:{description:"Key that represents additional words the platform should reference when users are searching for menu items",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},group:{description:"Group to which this menu item belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this menu item compared to other menu items in the same group (sorted ascending)",type:"number"}},required:["label","group","order"],unevaluatedProperties:!1},groupsAndItems:{description:"Core schema for a column",type:"object",properties:{groups:{description:"Groups that belong in this menu",$ref:"#/$defs/menuGroups"},items:{description:"List of menu items that belong in this menu",type:"array",items:{$ref:"#/$defs/menuItem"},uniqueItems:!0}},required:["groups","items"]},singleColumnMenu:{description:"Menu that contains a column without a header",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"}],unevaluatedProperties:!1},multiColumnMenu:{description:"Menu that can contain multiple columns with headers",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"},{properties:{columns:{description:"Columns that belong in this menu",$ref:"#/$defs/columnsWithHeaders"}},required:["columns"]}],unevaluatedProperties:!1},menusForOneWebView:{description:"Set of menus that are associated with a single tab",type:"object",properties:{includeDefaults:{description:"Indicates whether the platform default menus should be included for this webview",type:"boolean"},topMenu:{description:"Menu that opens when you click on the top left corner of a tab",$ref:"#/$defs/multiColumnMenu"},contextMenu:{description:"Menu that opens when you right click on the main body/area of a tab",$ref:"#/$defs/singleColumnMenu"}},additionalProperties:!1}}};Object.freeze(oe);exports.AsyncVariable=pe;exports.DocumentCombinerEngine=Oe;exports.FIRST_SCR_BOOK_NUM=K;exports.FIRST_SCR_CHAPTER_NUM=L;exports.FIRST_SCR_VERSE_NUM=Z;exports.LAST_SCR_BOOK_NUM=W;exports.PlatformEventEmitter=Se;exports.UnsubscriberAsyncList=qe;exports.aggregateUnsubscriberAsyncs=Te;exports.aggregateUnsubscribers=Pe;exports.at=Ve;exports.charAt=Fe;exports.codePointAt=He;exports.createSyncProxyForAsyncObject=Ee;exports.debounce=de;exports.deepClone=E;exports.deepEqual=$t;exports.deserialize=ne;exports.endsWith=ke;exports.getAllObjectFunctionNames=we;exports.getChaptersForBook=X;exports.getErrorMessage=ve;exports.groupBy=be;exports.htmlEncode=qt;exports.includes=Ke;exports.indexOf=ee;exports.isSerializable=At;exports.isString=V;exports.lastIndexOf=te;exports.length=d;exports.menuDocumentSchema=oe;exports.newGuid=me;exports.normalize=We;exports.offsetBook=je;exports.offsetChapter=Ce;exports.offsetVerse=Me;exports.padEnd=Le;exports.padStart=Ze;exports.serialize=j;exports.slice=Xe;exports.substring=M;exports.toArray=Qe;exports.wait=F;exports.waitForDuration=ye; //# sourceMappingURL=index.cjs.map diff --git a/lib/platform-bible-utils/dist/index.cjs.map b/lib/platform-bible-utils/dist/index.cjs.map index e86370236d..2a1792717d 100644 --- a/lib/platform-bible-utils/dist/index.cjs.map +++ b/lib/platform-bible-utils/dist/index.cjs.map @@ -1 +1 @@ -{"version":3,"file":"index.cjs","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit,\n} from 'stringz';\n\nexport const indexOf = stringzIndexOf;\nexport const substring = stringzSubstring;\nexport const length = stringzLength;\nexport const toArray = stringzToArray;\n\nexport const padStart = (string: string, targetLength: number, padString?: string) => {\n limit(string, targetLength, padString, 'left');\n};\n\nexport const padEnd = (string: string, targetLength: number, padString?: string) => {\n limit(string, targetLength, padString, 'right');\n};\n\nexport const normalize = (string: string, form: 'NFC' | 'NFD' | 'none' = 'NFC') => {\n const upperCaseForm = form.toUpperCase();\n if(upperCaseForm==='NONE')\n {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","stringzIndexOf","stringzSubstring","stringzLength","stringzToArray","padStart","string","targetLength","padEnd","normalize","form","upperCaseForm","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","result","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","matchIndex","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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CX,YACE,2FACF,KAAM,SACN,QAAS,kBACX,EACA,eAAgB,CACd,YACE,oGACF,KAAM,SACN,QAAS,yBACX,EACA,mBAAoB,CAClB,YACE,uFACF,KAAM,SACN,kBAAmB,CACjB,0BAA2B,CACzB,YAAa,qCACb,KAAM,SACN,WAAY,CACV,MAAO,CACL,YAAa,6CACb,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YACE,6EACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,8EACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,QAAS,OAAO,EAC3B,qBAAsB,EACxB,CACF,EACA,WAAY,CACV,aAAc,CACZ,YACE,qFACF,KAAM,SACR,CACF,CACF,EACA,WAAY,CACV,YACE,uJACF,KAAM,SACN,kBAAmB,CACjB,0BAA2B,CACzB,YAAa,wCACb,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,OAAQ,CACN,YACE,wEACF,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,OAAO,EAClB,qBAAsB,EACxB,EACA,CACE,WAAY,CACV,SAAU,CACR,YAAa,8DACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,WAAY,OAAO,EAC9B,qBAAsB,EACxB,CACF,CACF,CACF,EACA,qBAAsB,EACxB,EACA,SAAU,CACR,YACE,mGACF,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,GAAI,CACF,YAAa,6CACb,KAAM,wBACR,CACF,EACA,SAAU,CAAC,IAAI,CACjB,EACA,CACE,WAAY,CACV,QAAS,CACP,YAAa,mEACb,KAAM,wBACR,EACA,eAAgB,CACd,YAAa,mDACb,KAAM,QACR,EACA,cAAe,CACb,YAAa,kDACb,KAAM,QACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,WAAY,CACV,MAAO,CACL,YAAa,4DACb,KAAM,qBACR,EACA,QAAS,CACP,YACE,uFACF,KAAM,qBACR,EACA,YAAa,CACX,YACE,6GACF,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YAAa,wCACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,qGACF,KAAM,QACR,CACF,EACA,SAAU,CAAC,QAAS,QAAS,OAAO,EACpC,sBAAuB,EACzB,EACA,eAAgB,CACd,YAAa,2BACb,KAAM,SACN,WAAY,CACV,OAAQ,CACN,YAAa,kCACb,KAAM,oBACR,EACA,MAAO,CACL,YAAa,8CACb,KAAM,QACN,MAAO,CAAE,KAAM,kBAAmB,EAClC,YAAa,EACf,CACF,EACA,SAAU,CAAC,SAAU,OAAO,CAC9B,EACA,iBAAkB,CAChB,YAAa,+CACb,KAAM,SACN,MAAO,CAAC,CAAE,KAAM,yBAA0B,EAC1C,sBAAuB,EACzB,EACA,gBAAiB,CACf,YAAa,sDACb,KAAM,SACN,MAAO,CACL,CAAE,KAAM,wBAAyB,EACjC,CACE,WAAY,CACV,QAAS,CACP,YAAa,mCACb,KAAM,4BACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,sBAAuB,EACzB,EACA,mBAAoB,CAClB,YAAa,qDACb,KAAM,SACN,WAAY,CACV,gBAAiB,CACf,YACE,mFACF,KAAM,SACR,EACA,QAAS,CACP,YAAa,iEACb,KAAM,yBACR,EACA,YAAa,CACX,YAAa,sEACb,KAAM,0BACR,CACF,EACA,qBAAsB,EACxB,CACF,CACF,EAEA,OAAO,OAAOA,CAAkB","x_google_ignoreList":[7,8,10]} \ No newline at end of file +{"version":3,"file":"index.cjs","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * Finds the Unicode code point at the given index\n *\n * @param {string} string String to index\n * @param {number} index Position of the character to be returned in range of 0 to -length(string)\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > length(string) || index < -length(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * Always indexes string as a sequence of Unicode code points\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, empty string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > length(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to index\n * @param {number} index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {number | undefined} Non-negative integer representing the code point value of the\n * character at the given index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > length(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * Determines whether a string ends with the characters of this string. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Characters to search for at the end of the string\n * @param {number} [endPosition=length(string)] End position where searchString is expected to be\n * found. Default is `length(string)`\n * @returns {boolean} True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = length(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + length(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * Performs a case-sensitive search to determine if searchString is found in string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString String to search for\n * @param {string} [position=0] Position within the string to start searching for searchString.\n * Default is `0`\n * @returns {boolean} True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * Returns the index of the first occurrence of a given string. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The string to search for\n * @param {number} [position=0] Start of searching. Default is `0`\n * @returns {number} Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * Searches this string and returns the index of the last occurrence of the specified substring.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Substring to search for\n * @param {number} [position=+Infinity] The method returns the index of the last occurrence of the\n * specified substring at a position less than or equal to position. . Default is `+Infinity`\n * @returns {number} Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(\n string: string,\n searchString: string,\n position: number = +Infinity,\n): number {\n let validatedPosition = position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= length(string)) {\n validatedPosition = length(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, length(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * Returns the length of a string. This function handles Unicode code points instead of UTF-16\n * character codes.\n *\n * @param {string} string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function length(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * Returns the Unicode Normalization Form of this string.\n *\n * @param {string} string The starting string\n * @param {'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'} [form='NFC'] Form specifying the Unicode\n * Normalization Form. Default is `'NFC'`\n * @returns {string} A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within targetLength, it will be truncated. Default is `\" \"`\n * @returns {string} String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\nfunction correctSliceIndex(stringLength: number, index: number) {\n if (index > stringLength) return stringLength;\n if (index < -stringLength) return 0;\n if (index < 0) return index + stringLength;\n return index;\n}\n\n/**\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The starting string\n * @param {number} indexStart The index of the first character to include in the returned substring.\n * @param {number} indexEnd The index of the first character to exclude from the returned substring.\n * @returns {string} A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const stringLength: number = length(string);\n if (\n indexStart > stringLength ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(\n indexStart > 0 &&\n indexStart < stringLength &&\n indexEnd < 0 &&\n indexEnd > -stringLength\n )) ||\n indexEnd < -stringLength ||\n (indexStart < 0 && indexStart > -stringLength && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(stringLength, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The string to split\n * @param {string | RegExp} separator The pattern describing where each split should occur\n * @param {number} splitLimit Limit on the number of substrings to be included in the array. Splits\n * the string at each occurrence of specified separator, but stops when limit entries have been\n * placed in the array.\n * @returns {string[] | undefined} An array of strings, split at each point where separator occurs\n * in the starting string. Returns undefined if separator is not found in string.\n */\nexport function split(\n string: string,\n separator: string | RegExp,\n splitLimit?: number,\n): string[] | undefined {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !separator.flags.includes('g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return undefined;\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = length(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate. This function handles Unicode code points instead of UTF-16 character\n * codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The characters to be searched for at the start of this string.\n * @param {number} [position=0] The start position at which searchString is expected to be found\n * (the index of searchString's first character). Default is `0`\n * @returns {boolean} True if the given characters are found at the beginning of the string,\n * including when searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * Returns a substring by providing start and length. This function handles Unicode code points\n * instead of UTF-16 character codes. This function is not exported because it is considered\n * deprecated, however it is still useful as a local helper function.\n *\n * @param {string} string String to be divided\n * @param {number} [begin=Start of string] Start position. Default is `Start of string`\n * @param {number} [len=String length minus start parameter] Length of result. Default is `String\n * length minus start parameter`. Default is `String length minus start parameter`\n * @returns {string} Substring from starting string\n */\nfunction substr(string: string, begin: number = 0, len: number = length(string) - begin): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * Returns a substring by providing start and end position. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to be divided\n * @param {string} begin Start position\n * @param {number} [end=End of string] End position. Default is `End of string`\n * @returns {string} Substring from starting string\n */\nexport function substring(\n string: string,\n begin?: number | undefined,\n end: number | undefined = length(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * Converts a string to an array of string characters. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param {string} string String to convert to array\n * @returns {string[]} An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","stringLength","slice","indexStart","indexEnd","newStart","newEnd","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","result","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","matchIndex","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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,CACE,WAAY,CACV,OAAQ,CACN,YACE,wEACF,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,OAAO,EAClB,qBAAsB,EACxB,EACA,CACE,WAAY,CACV,SAAU,CACR,YAAa,8DACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,WAAY,OAAO,EAC9B,qBAAsB,EACxB,CACF,CACF,CACF,EACA,qBAAsB,EACxB,EACA,SAAU,CACR,YACE,mGACF,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,GAAI,CACF,YAAa,6CACb,KAAM,wBACR,CACF,EACA,SAAU,CAAC,IAAI,CACjB,EACA,CACE,WAAY,CACV,QAAS,CACP,YAAa,mEACb,KAAM,wBACR,EACA,eAAgB,CACd,YAAa,mDACb,KAAM,QACR,EACA,cAAe,CACb,YAAa,kDACb,KAAM,QACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,WAAY,CACV,MAAO,CACL,YAAa,4DACb,KAAM,qBACR,EACA,QAAS,CACP,YACE,uFACF,KAAM,qBACR,EACA,YAAa,CACX,YACE,6GACF,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YAAa,wCACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,qGACF,KAAM,QACR,CACF,EACA,SAAU,CAAC,QAAS,QAAS,OAAO,EACpC,sBAAuB,EACzB,EACA,eAAgB,CACd,YAAa,2BACb,KAAM,SACN,WAAY,CACV,OAAQ,CACN,YAAa,kCACb,KAAM,oBACR,EACA,MAAO,CACL,YAAa,8CACb,KAAM,QACN,MAAO,CAAE,KAAM,kBAAmB,EAClC,YAAa,EACf,CACF,EACA,SAAU,CAAC,SAAU,OAAO,CAC9B,EACA,iBAAkB,CAChB,YAAa,+CACb,KAAM,SACN,MAAO,CAAC,CAAE,KAAM,yBAA0B,EAC1C,sBAAuB,EACzB,EACA,gBAAiB,CACf,YAAa,sDACb,KAAM,SACN,MAAO,CACL,CAAE,KAAM,wBAAyB,EACjC,CACE,WAAY,CACV,QAAS,CACP,YAAa,mCACb,KAAM,4BACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,sBAAuB,EACzB,EACA,mBAAoB,CAClB,YAAa,qDACb,KAAM,SACN,WAAY,CACV,gBAAiB,CACf,YACE,mFACF,KAAM,SACR,EACA,QAAS,CACP,YAAa,iEACb,KAAM,yBACR,EACA,YAAa,CACX,YAAa,sEACb,KAAM,0BACR,CACF,EACA,qBAAsB,EACxB,CACF,CACF,EAEA,OAAO,OAAOA,EAAkB","x_google_ignoreList":[7,8,10]} \ No newline at end of file diff --git a/lib/platform-bible-utils/dist/index.d.ts b/lib/platform-bible-utils/dist/index.d.ts index 09c36b173b..4284645a03 100644 --- a/lib/platform-bible-utils/dist/index.d.ts +++ b/lib/platform-bible-utils/dist/index.d.ts @@ -1,7 +1,5 @@ // Generated by dts-bundle-generator v9.2.4 -import { indexOf as stringzIndexOf, length as stringzLength, substring as stringzSubstring, toArray as stringzToArray } from 'stringz'; - /** This class provides a convenient way for one task to wait on a variable that another task sets. */ export declare class AsyncVariable { private readonly variableName; @@ -374,13 +372,143 @@ export declare function getAllObjectFunctionNames(obj: { * @returns A synchronous proxy for the asynchronous object. */ export declare function createSyncProxyForAsyncObject(getObject: (args?: unknown[]) => Promise, objectToProxy?: Partial): T; -export declare const indexOf: typeof stringzIndexOf; -export declare const substring: typeof stringzSubstring; -declare const length$1: typeof stringzLength; -export declare const toArray: typeof stringzToArray; -export declare const padStart: (string: string, targetLength: number, padString?: string) => void; -export declare const padEnd: (string: string, targetLength: number, padString?: string) => void; -export declare const normalize: (string: string, form?: "NFC" | "NFD" | "none") => string; +/** + * Finds the Unicode code point at the given index + * + * @param {string} string String to index + * @param {number} index Position of the character to be returned in range of 0 to -length(string) + * @returns {string} New string consisting of the Unicode code point located at the specified + * offset, undefined if index is out of bounds + */ +export declare function at(string: string, index: number): string | undefined; +/** + * Always indexes string as a sequence of Unicode code points + * + * @param string String to index + * @param index Position of the string character to be returned, in the range of 0 to + * length(string)-1 + * @returns {string} New string consisting of the Unicode code point located at the specified + * offset, empty string if index is out of bounds + */ +export declare function charAt(string: string, index: number): string; +/** + * Returns a non-negative integer that is the Unicode code point value of the character starting at + * the given index. This function handles Unicode code points instead of UTF-16 character codes. + * + * @param {string} string String to index + * @param {number} index Position of the string character to be returned, in the range of 0 to + * length(string)-1 + * @returns {number | undefined} Non-negative integer representing the code point value of the + * character at the given index, or undefined if there is no element at that position + */ +export declare function codePointAt(string: string, index: number): number | undefined; +/** + * Determines whether a string ends with the characters of this string. This function handles + * Unicode code points instead of UTF-16 character codes. + * + * @param {string} string String to search through + * @param {string} searchString Characters to search for at the end of the string + * @param {number} [endPosition=length(string)] End position where searchString is expected to be + * found. Default is `length(string)` + * @returns {boolean} True if it ends with searchString, false if it does not + */ +export declare function endsWith(string: string, searchString: string, endPosition?: number): boolean; +/** + * Performs a case-sensitive search to determine if searchString is found in string. This function + * handles Unicode code points instead of UTF-16 character codes. + * + * @param {string} string String to search through + * @param {string} searchString String to search for + * @param {string} [position=0] Position within the string to start searching for searchString. + * Default is `0` + * @returns {boolean} True if search string is found, false if it is not + */ +export declare function includes(string: string, searchString: string, position?: number): boolean; +/** + * Returns the index of the first occurrence of a given string. This function handles Unicode code + * points instead of UTF-16 character codes. + * + * @param {string} string String to search through + * @param {string} searchString The string to search for + * @param {number} [position=0] Start of searching. Default is `0` + * @returns {number} Index of the first occurrence of a given string + */ +export declare function indexOf(string: string, searchString: string, position?: number | undefined): number; +/** + * Searches this string and returns the index of the last occurrence of the specified substring. + * This function handles Unicode code points instead of UTF-16 character codes. + * + * @param {string} string String to search through + * @param {string} searchString Substring to search for + * @param {number} [position=+Infinity] The method returns the index of the last occurrence of the + * specified substring at a position less than or equal to position. . Default is `+Infinity` + * @returns {number} Index of the last occurrence of searchString found, or -1 if not found. + */ +export declare function lastIndexOf(string: string, searchString: string, position?: number): number; +declare function length$1(string: string): number; +/** + * Returns the Unicode Normalization Form of this string. + * + * @param {string} string The starting string + * @param {'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'} [form='NFC'] Form specifying the Unicode + * Normalization Form. Default is `'NFC'` + * @returns {string} A string containing the Unicode Normalization Form of the given string. + */ +export declare function normalize(string: string, form: "NFC" | "NFD" | "NFKC" | "NFKD" | "none"): string; +/** + * Pads this string with another string (multiple times, if needed) until the resulting string + * reaches the given length. The padding is applied from the end of this string. This function + * handles Unicode code points instead of UTF-16 character codes. + * + * @param {string} string String to add padding too + * @param {number} targetLength The length of the resulting string once the starting string has been + * padded. If value is less than or equal to length(string), then string is returned as is. + * @param {string} [padString=" "] The string to pad the current string with. If padString is too + * long to stay within targetLength, it will be truncated. Default is `" "` + * @returns {string} String with appropriate padding at the end + */ +export declare function padEnd(string: string, targetLength: number, padString?: string): string; +/** + * Pads this string with another string (multiple times, if needed) until the resulting string + * reaches the given length. The padding is applied from the start of this string. This function + * handles Unicode code points instead of UTF-16 character codes. + * + * @param {string} string String to add padding too + * @param {number} targetLength The length of the resulting string once the starting string has been + * padded. If value is less than or equal to length(string), then string is returned as is. + * @param {string} [padString=" "] The string to pad the current string with. If padString is too + * long to stay within the targetLength, it will be truncated from the end. Default is `" "` + * @returns String with of specified targetLength with padString applied from the start + */ +export declare function padStart(string: string, targetLength: number, padString?: string): string; +/** + * Extracts a section of this string and returns it as a new string, without modifying the original + * string. This function handles Unicode code points instead of UTF-16 character codes. + * + * @param {string} string The starting string + * @param {number} indexStart The index of the first character to include in the returned substring. + * @param {number} indexEnd The index of the first character to exclude from the returned substring. + * @returns {string} A new string containing the extracted section of the string. + */ +export declare function slice(string: string, indexStart: number, indexEnd?: number): string; +/** + * Returns a substring by providing start and end position. This function handles Unicode code + * points instead of UTF-16 character codes. + * + * @param {string} string String to be divided + * @param {string} begin Start position + * @param {number} [end=End of string] End position. Default is `End of string` + * @returns {string} Substring from starting string + */ +export declare function substring(string: string, begin?: number | undefined, end?: number | undefined): string; +/** + * Converts a string to an array of string characters. This function handles Unicode code points + * instead of UTF-16 character codes. + * + * @param {string} string String to convert to array + * @returns {string[]} An array of characters from the starting string + */ +export declare function toArray(string: string): string[]; /** * Check that two objects are deeply equal, comparing members of each object and such * @@ -831,3 +959,5 @@ export declare const menuDocumentSchema: { export { length$1 as length, }; + +export {}; diff --git a/lib/platform-bible-utils/dist/index.js b/lib/platform-bible-utils/dist/index.js index ed94d687eb..8ee64aed3b 100644 --- a/lib/platform-bible-utils/dist/index.js +++ b/lib/platform-bible-utils/dist/index.js @@ -1,7 +1,7 @@ -var Z = Object.defineProperty; -var X = (t, e, r) => e in t ? Z(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r; -var p = (t, e, r) => (X(t, typeof e != "symbol" ? e + "" : e, r), r); -class Ke { +var ee = Object.defineProperty; +var te = (t, e, r) => e in t ? ee(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r; +var p = (t, e, r) => (te(t, typeof e != "symbol" ? e + "" : e, r), r); +class et { /** * Creates an instance of the class * @@ -75,7 +75,7 @@ class Ke { this.resolver = void 0, this.rejecter = void 0, Object.freeze(this); } } -function Le() { +function tt() { return "00-0-4-1-000".replace( /[^-]/g, (t) => ( @@ -85,36 +85,36 @@ function Le() { ) ); } -function Q(t) { +function re(t) { return typeof t == "string" || t instanceof String; } -function E(t) { +function O(t) { return JSON.parse(JSON.stringify(t)); } -function We(t, e = 300) { - if (Q(t)) +function rt(t, e = 300) { + if (re(t)) throw new Error("Tried to debounce a string! Could be XSS"); let r; return (...s) => { clearTimeout(r), r = setTimeout(() => t(...s), e); }; } -function Ze(t, e, r) { +function st(t, e, r) { const s = /* @__PURE__ */ new Map(); return t.forEach((n) => { - const a = e(n), o = s.get(a), i = r ? r(n, a) : n; - o ? o.push(i) : s.set(a, [i]); + const o = e(n), a = s.get(o), i = r ? r(n, o) : n; + a ? a.push(i) : s.set(o, [i]); }), s; } -function Y(t) { +function se(t) { return typeof t == "object" && // We're potentially dealing with objects we didn't create, so they might contain `null` // eslint-disable-next-line no-null/no-null t !== null && "message" in t && // Type assert `error` to check it's `message`. // eslint-disable-next-line no-type-assertion/no-type-assertion typeof t.message == "string"; } -function ee(t) { - if (Y(t)) +function ne(t) { + if (se(t)) return t; try { return new Error(JSON.stringify(t)); @@ -122,24 +122,24 @@ function ee(t) { return new Error(String(t)); } } -function Xe(t) { - return ee(t).message; +function nt(t) { + return ne(t).message; } -function te(t) { +function oe(t) { return new Promise((e) => setTimeout(e, t)); } -function Qe(t, e) { - const r = te(e).then(() => { +function ot(t, e) { + const r = oe(e).then(() => { }); return Promise.any([r, t()]); } -function Ye(t, e = "obj") { +function at(t, e = "obj") { const r = /* @__PURE__ */ new Set(); Object.getOwnPropertyNames(t).forEach((n) => { try { typeof t[n] == "function" && r.add(n); - } catch (a) { - console.debug(`Skipping ${n} on ${e} due to error: ${a}`); + } catch (o) { + console.debug(`Skipping ${n} on ${e} due to error: ${o}`); } }); let s = Object.getPrototypeOf(t); @@ -147,20 +147,20 @@ function Ye(t, e = "obj") { Object.getOwnPropertyNames(s).forEach((n) => { try { typeof t[n] == "function" && r.add(n); - } catch (a) { - console.debug(`Skipping ${n} on ${e}'s prototype due to error: ${a}`); + } catch (o) { + console.debug(`Skipping ${n} on ${e}'s prototype due to error: ${o}`); } }), s = Object.getPrototypeOf(s); return r; } -function et(t, e = {}) { +function it(t, e = {}) { return new Proxy(e, { get(r, s) { return s in r ? r[s] : async (...n) => (await t())[s](...n); } }); } -class tt { +class ut { /** * Create a DocumentCombinerEngine instance * @@ -181,7 +181,7 @@ class tt { * @returns Recalculated output document given the new starting state and existing other documents */ updateBaseDocument(e) { - return this.validateStartingDocument(e), this.baseDocument = this.options.copyDocuments ? E(e) : e, this.rebuild(); + return this.validateStartingDocument(e), this.baseDocument = this.options.copyDocuments ? O(e) : e, this.rebuild(); } /** * Add or update one of the contribution documents for the composition process @@ -193,12 +193,12 @@ class tt { */ addOrUpdateContribution(e, r) { this.validateContribution(e, r); - const s = this.contributions.get(e), n = this.options.copyDocuments && r ? E(r) : r; + const s = this.contributions.get(e), n = this.options.copyDocuments && r ? O(r) : r; this.contributions.set(e, n); try { return this.rebuild(); - } catch (a) { - throw s ? this.contributions.set(e, s) : this.contributions.delete(e), new Error(`Error when setting the document named ${e}: ${a}`); + } catch (o) { + throw s ? this.contributions.set(e, s) : this.contributions.delete(e), new Error(`Error when setting the document named ${e}: ${o}`); } } /** @@ -226,12 +226,12 @@ class tt { */ rebuild() { if (this.contributions.size === 0) { - let r = E(this.baseDocument); + let r = O(this.baseDocument); return r = this.transformFinalOutput(r), this.validateOutput(r), this.latestOutput = r, this.latestOutput; } let e = this.baseDocument; return this.contributions.forEach((r) => { - e = _( + e = V( e, r, this.options.ignoreDuplicateProperties @@ -239,24 +239,24 @@ class tt { }), e = this.transformFinalOutput(e), this.validateOutput(e), this.latestOutput = e, this.latestOutput; } } -function re(...t) { +function ae(...t) { let e = !0; return t.forEach((r) => { (!r || typeof r != "object" || Array.isArray(r)) && (e = !1); }), e; } -function se(...t) { +function ie(...t) { let e = !0; return t.forEach((r) => { (!r || typeof r != "object" || !Array.isArray(r)) && (e = !1); }), e; } -function _(t, e, r) { - const s = E(t); +function V(t, e, r) { + const s = O(t); return e && Object.keys(e).forEach((n) => { if (Object.hasOwn(t, n)) { - if (re(t[n], e[n])) - s[n] = _( + if (ae(t[n], e[n])) + s[n] = V( // We know these are objects from the `if` check /* eslint-disable no-type-assertion/no-type-assertion */ t[n], @@ -264,7 +264,7 @@ function _(t, e, r) { r /* eslint-enable no-type-assertion/no-type-assertion */ ); - else if (se(t[n], e[n])) + else if (ie(t[n], e[n])) s[n] = s[n].concat(e[n]); else if (!r) throw new Error(`Cannot merge objects: key "${n}" already exists in the target object`); @@ -272,7 +272,7 @@ function _(t, e, r) { s[n] = e[n]; }), s; } -class rt { +class lt { constructor(e = "Anonymous") { p(this, "unsubscribers", /* @__PURE__ */ new Set()); this.name = e; @@ -297,7 +297,7 @@ class rt { return this.unsubscribers.clear(), r.every((s, n) => (s || console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${n} failed!`), s)); } } -class st { +class ct { constructor() { /** * Subscribes a function to run when this event is emitted. @@ -366,7 +366,7 @@ class st { return this.assertNotDisposed(), this.isDisposed = !0, this.subscriptions = void 0, this.lazyEvent = void 0, Promise.resolve(!0); } } -const G = [ +const H = [ { shortName: "ERR", fullNames: ["ERROR"], chapters: -1 }, { shortName: "GEN", fullNames: ["Genesis"], chapters: 50 }, { shortName: "EXO", fullNames: ["Exodus"], chapters: 40 }, @@ -434,145 +434,199 @@ const G = [ { shortName: "3JN", fullNames: ["3 John"], chapters: 1 }, { shortName: "JUD", fullNames: ["Jude"], chapters: 1 }, { shortName: "REV", fullNames: ["Revelation"], chapters: 22 } -], ne = 1, ae = G.length - 1, oe = 1, ie = 1, ue = (t) => { +], ue = 1, le = H.length - 1, ce = 1, fe = 1, he = (t) => { var e; - return ((e = G[t]) == null ? void 0 : e.chapters) ?? -1; -}, nt = (t, e) => ({ - bookNum: Math.max(ne, Math.min(t.bookNum + e, ae)), + return ((e = H[t]) == null ? void 0 : e.chapters) ?? -1; +}, ft = (t, e) => ({ + bookNum: Math.max(ue, Math.min(t.bookNum + e, le)), chapterNum: 1, verseNum: 1 -}), at = (t, e) => ({ +}), ht = (t, e) => ({ ...t, chapterNum: Math.min( - Math.max(oe, t.chapterNum + e), - ue(t.bookNum) + Math.max(ce, t.chapterNum + e), + he(t.bookNum) ), verseNum: 1 -}), ot = (t, e) => ({ +}), pt = (t, e) => ({ ...t, - verseNum: Math.max(ie, t.verseNum + e) -}), it = (t) => (...e) => t.map((s) => s(...e)).every((s) => s), ut = (t) => async (...e) => { + verseNum: Math.max(fe, t.verseNum + e) +}), mt = (t) => (...e) => t.map((s) => s(...e)).every((s) => s), dt = (t) => async (...e) => { const r = t.map(async (s) => s(...e)); return (await Promise.all(r)).every((s) => s); }; -var M = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}, b = {}, le = () => { - const t = "\\ud800-\\udfff", e = "\\u0300-\\u036f", r = "\\ufe20-\\ufe2f", s = "\\u20d0-\\u20ff", n = "\\u1ab0-\\u1aff", a = "\\u1dc0-\\u1dff", o = e + r + s + n + a, i = "\\ufe0e\\ufe0f", c = "\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93", h = `[${t}]`, u = `[${o}]`, l = "\\ud83c[\\udffb-\\udfff]", f = `(?:${u}|${l})`, d = `[^${t}]`, m = "(?:\\uD83C[\\uDDE6-\\uDDFF]){2}", v = "[\\ud800-\\udbff][\\udc00-\\udfff]", $ = "\\u200d", F = "(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)", k = `[${c}]`, j = `${f}?`, C = `[${i}]?`, K = `(?:${$}(?:${[d, m, v].join("|")})${C + j})*`, L = C + j + K, W = `(?:${[`${d}${u}?`, u, m, v, h, k].join("|")})`; - return new RegExp(`${F}|${l}(?=${l})|${W + L}`, "g"); -}, ce = M && M.__importDefault || function(t) { +var S = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}, v = {}, pe = () => { + const t = "\\ud800-\\udfff", e = "\\u0300-\\u036f", r = "\\ufe20-\\ufe2f", s = "\\u20d0-\\u20ff", n = "\\u1ab0-\\u1aff", o = "\\u1dc0-\\u1dff", a = e + r + s + n + o, i = "\\ufe0e\\ufe0f", c = "\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93", h = `[${t}]`, u = `[${a}]`, l = "\\ud83c[\\udffb-\\udfff]", f = `(?:${u}|${l})`, b = `[^${t}]`, m = "(?:\\uD83C[\\uDDE6-\\uDDFF]){2}", y = "[\\ud800-\\udbff][\\udc00-\\udfff]", q = "\\u200d", L = "(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)", Z = `[${c}]`, M = `${f}?`, P = `[${i}]?`, X = `(?:${q}(?:${[b, m, y].join("|")})${P + M})*`, Q = P + M + X, Y = `(?:${[`${b}${u}?`, u, m, y, h, Z].join("|")})`; + return new RegExp(`${L}|${l}(?=${l})|${Y + Q}`, "g"); +}, me = S && S.__importDefault || function(t) { return t && t.__esModule ? t : { default: t }; }; -Object.defineProperty(b, "__esModule", { value: !0 }); -var O = ce(le); -function A(t) { +Object.defineProperty(v, "__esModule", { value: !0 }); +var $ = me(pe); +function j(t) { if (typeof t != "string") throw new Error("A string is expected as input"); - return t.match(O.default()) || []; + return t.match($.default()) || []; } -var fe = b.toArray = A; -function q(t) { +var de = v.toArray = j; +function C(t) { if (typeof t != "string") throw new Error("Input must be a string"); - var e = t.match(O.default()); + var e = t.match($.default()); return e === null ? 0 : e.length; } -var he = b.length = q; -function B(t, e, r) { +var be = v.length = C; +function U(t, e, r) { if (e === void 0 && (e = 0), typeof t != "string") throw new Error("Input must be a string"); (typeof e != "number" || e < 0) && (e = 0), typeof r == "number" && r < 0 && (r = 0); - var s = t.match(O.default()); + var s = t.match($.default()); return s ? s.slice(e, r).join("") : ""; } -var pe = b.substring = B; -function me(t, e, r) { +var Ne = v.substring = U; +function ve(t, e, r) { if (e === void 0 && (e = 0), typeof t != "string") throw new Error("Input must be a string"); - var s = q(t); + var s = C(t); if (typeof e != "number" && (e = parseInt(e, 10)), e >= s) return ""; e < 0 && (e += s); var n; typeof r > "u" ? n = s : (typeof r != "number" && (r = parseInt(r, 10)), n = r >= 0 ? r + e : e); - var a = t.match(O.default()); - return a ? a.slice(e, n).join("") : ""; + var o = t.match($.default()); + return o ? o.slice(e, n).join("") : ""; } -b.substr = me; -function de(t, e, r, s) { +var ge = v.substr = ve; +function ye(t, e, r, s) { if (e === void 0 && (e = 16), r === void 0 && (r = "#"), s === void 0 && (s = "right"), typeof t != "string" || typeof e != "number") throw new Error("Invalid arguments specified"); if (["left", "right"].indexOf(s) === -1) throw new Error("Pad position should be either left or right"); typeof r != "string" && (r = String(r)); - var n = q(t); + var n = C(t); if (n > e) - return B(t, 0, e); + return U(t, 0, e); if (n < e) { - var a = r.repeat(e - n); - return s === "left" ? a + t : t + a; + var o = r.repeat(e - n); + return s === "left" ? o + t : t + o; } return t; } -var V = b.limit = de; -function ge(t, e, r) { +var F = v.limit = ye; +function we(t, e, r) { if (r === void 0 && (r = 0), typeof t != "string") throw new Error("Input must be a string"); if (t === "") return e === "" ? 0 : -1; r = Number(r), r = isNaN(r) ? 0 : r, e = String(e); - var s = A(t); + var s = j(t); if (r >= s.length) return e === "" ? s.length : -1; if (e === "") return r; - var n = A(e), a = !1, o; - for (o = r; o < s.length; o += 1) { - for (var i = 0; i < n.length && n[i] === s[o + i]; ) + var n = j(e), o = !1, a; + for (a = r; a < s.length; a += 1) { + for (var i = 0; i < n.length && n[i] === s[a + i]; ) i += 1; - if (i === n.length && n[i - 1] === s[o + i - 1]) { - a = !0; + if (i === n.length && n[i - 1] === s[a + i - 1]) { + o = !0; break; } } - return a ? o : -1; + return o ? a : -1; +} +var Ee = v.indexOf = we; +function bt(t, e) { + if (!(e > d(t) || e < -d(t))) + return A(t, e, 1); +} +function Nt(t, e) { + return e < 0 || e > d(t) - 1 ? "" : A(t, e, 1); +} +function vt(t, e) { + if (!(e < 0 || e > d(t) - 1)) + return A(t, e, 1).codePointAt(0); } -var be = b.indexOf = ge; -const lt = be, ct = pe, ft = he, ht = fe, pt = (t, e, r) => { - V(t, e, r, "left"); -}, mt = (t, e, r) => { - V(t, e, r, "right"); -}, dt = (t, e = "NFC") => { +function gt(t, e, r = d(t)) { + const s = $e(t, e); + return !(s === -1 || s + d(e) !== r); +} +function yt(t, e, r = 0) { + const s = k(t, r); + return Oe(s, e) !== -1; +} +function Oe(t, e, r = 0) { + return Ee(t, e, r); +} +function $e(t, e, r = 1 / 0) { + let s = r; + s < 0 ? s = 0 : s >= d(t) && (s = d(t) - 1); + for (let n = s; n >= 0; n--) + if (A(t, n, d(e)) === e) + return n; + return -1; +} +function d(t) { + return be(t); +} +function wt(t, e) { const r = e.toUpperCase(); return r === "NONE" ? t : t.normalize(r); -}; -var Ne = Object.getOwnPropertyNames, ve = Object.getOwnPropertySymbols, ye = Object.prototype.hasOwnProperty; -function P(t, e) { - return function(s, n, a) { - return t(s, n, a) && e(s, n, a); +} +function Et(t, e, r = " ") { + return e <= d(t) ? t : F(t, e, r, "right"); +} +function Ot(t, e, r = " ") { + return e <= d(t) ? t : F(t, e, r, "left"); +} +function T(t, e) { + return e > t ? t : e < -t ? 0 : e < 0 ? e + t : e; +} +function $t(t, e, r) { + const s = d(t); + if (e > s || r && (e > r && !(e > 0 && e < s && r < 0 && r > -s) || r < -s || e < 0 && e > -s && r > 0)) + return ""; + const n = T(s, e), o = r ? T(s, r) : void 0; + return k(t, n, o); +} +function A(t, e = 0, r = d(t) - e) { + return ge(t, e, r); +} +function k(t, e, r = d(t)) { + return Ne(t, e, r); +} +function At(t) { + return de(t); +} +var Ae = Object.getOwnPropertyNames, qe = Object.getOwnPropertySymbols, je = Object.prototype.hasOwnProperty; +function D(t, e) { + return function(s, n, o) { + return t(s, n, o) && e(s, n, o); }; } -function w(t) { +function E(t) { return function(r, s, n) { if (!r || !s || typeof r != "object" || typeof s != "object") return t(r, s, n); - var a = n.cache, o = a.get(r), i = a.get(s); - if (o && i) - return o === s && i === r; - a.set(r, s), a.set(s, r); + var o = n.cache, a = o.get(r), i = o.get(s); + if (a && i) + return a === s && i === r; + o.set(r, s), o.set(s, r); var c = t(r, s, n); - return a.delete(r), a.delete(s), c; + return o.delete(r), o.delete(s), c; }; } -function S(t) { - return Ne(t).concat(ve(t)); +function R(t) { + return Ae(t).concat(qe(t)); } -var H = Object.hasOwn || function(t, e) { - return ye.call(t, e); +var K = Object.hasOwn || function(t, e) { + return je.call(t, e); }; -function N(t, e) { +function g(t, e) { return t || e ? t === e : t === e || t !== t && e !== e; } -var U = "_owner", T = Object.getOwnPropertyDescriptor, D = Object.keys; -function we(t, e, r) { +var W = "_owner", I = Object.getOwnPropertyDescriptor, z = Object.keys; +function Ce(t, e, r) { var s = t.length; if (e.length !== s) return !1; @@ -581,59 +635,59 @@ function we(t, e, r) { return !1; return !0; } -function Ee(t, e) { - return N(t.getTime(), e.getTime()); +function Me(t, e) { + return g(t.getTime(), e.getTime()); } -function R(t, e, r) { +function _(t, e, r) { if (t.size !== e.size) return !1; - for (var s = {}, n = t.entries(), a = 0, o, i; (o = n.next()) && !o.done; ) { + for (var s = {}, n = t.entries(), o = 0, a, i; (a = n.next()) && !a.done; ) { for (var c = e.entries(), h = !1, u = 0; (i = c.next()) && !i.done; ) { - var l = o.value, f = l[0], d = l[1], m = i.value, v = m[0], $ = m[1]; - !h && !s[u] && (h = r.equals(f, v, a, u, t, e, r) && r.equals(d, $, f, v, t, e, r)) && (s[u] = !0), u++; + var l = a.value, f = l[0], b = l[1], m = i.value, y = m[0], q = m[1]; + !h && !s[u] && (h = r.equals(f, y, o, u, t, e, r) && r.equals(b, q, f, y, t, e, r)) && (s[u] = !0), u++; } if (!h) return !1; - a++; + o++; } return !0; } -function Oe(t, e, r) { - var s = D(t), n = s.length; - if (D(e).length !== n) +function Pe(t, e, r) { + var s = z(t), n = s.length; + if (z(e).length !== n) return !1; - for (var a; n-- > 0; ) - if (a = s[n], a === U && (t.$$typeof || e.$$typeof) && t.$$typeof !== e.$$typeof || !H(e, a) || !r.equals(t[a], e[a], a, a, t, e, r)) + for (var o; n-- > 0; ) + if (o = s[n], o === W && (t.$$typeof || e.$$typeof) && t.$$typeof !== e.$$typeof || !K(e, o) || !r.equals(t[o], e[o], o, o, t, e, r)) return !1; return !0; } -function y(t, e, r) { - var s = S(t), n = s.length; - if (S(e).length !== n) +function w(t, e, r) { + var s = R(t), n = s.length; + if (R(e).length !== n) return !1; - for (var a, o, i; n-- > 0; ) - if (a = s[n], a === U && (t.$$typeof || e.$$typeof) && t.$$typeof !== e.$$typeof || !H(e, a) || !r.equals(t[a], e[a], a, a, t, e, r) || (o = T(t, a), i = T(e, a), (o || i) && (!o || !i || o.configurable !== i.configurable || o.enumerable !== i.enumerable || o.writable !== i.writable))) + for (var o, a, i; n-- > 0; ) + if (o = s[n], o === W && (t.$$typeof || e.$$typeof) && t.$$typeof !== e.$$typeof || !K(e, o) || !r.equals(t[o], e[o], o, o, t, e, r) || (a = I(t, o), i = I(e, o), (a || i) && (!a || !i || a.configurable !== i.configurable || a.enumerable !== i.enumerable || a.writable !== i.writable))) return !1; return !0; } -function $e(t, e) { - return N(t.valueOf(), e.valueOf()); +function Se(t, e) { + return g(t.valueOf(), e.valueOf()); } -function Ae(t, e) { +function Te(t, e) { return t.source === e.source && t.flags === e.flags; } -function x(t, e, r) { +function J(t, e, r) { if (t.size !== e.size) return !1; - for (var s = {}, n = t.values(), a, o; (a = n.next()) && !a.done; ) { - for (var i = e.values(), c = !1, h = 0; (o = i.next()) && !o.done; ) - !c && !s[h] && (c = r.equals(a.value, o.value, a.value, o.value, t, e, r)) && (s[h] = !0), h++; + for (var s = {}, n = t.values(), o, a; (o = n.next()) && !o.done; ) { + for (var i = e.values(), c = !1, h = 0; (a = i.next()) && !a.done; ) + !c && !s[h] && (c = r.equals(o.value, a.value, o.value, a.value, t, e, r)) && (s[h] = !0), h++; if (!c) return !1; } return !0; } -function qe(t, e) { +function De(t, e) { var r = t.length; if (e.length !== r) return !1; @@ -642,72 +696,72 @@ function qe(t, e) { return !1; return !0; } -var je = "[object Arguments]", Ce = "[object Boolean]", Me = "[object Date]", Pe = "[object Map]", Se = "[object Number]", Te = "[object Object]", De = "[object RegExp]", Re = "[object Set]", xe = "[object String]", Ie = Array.isArray, I = typeof ArrayBuffer == "function" && ArrayBuffer.isView ? ArrayBuffer.isView : null, z = Object.assign, ze = Object.prototype.toString.call.bind(Object.prototype.toString); -function Je(t) { - var e = t.areArraysEqual, r = t.areDatesEqual, s = t.areMapsEqual, n = t.areObjectsEqual, a = t.arePrimitiveWrappersEqual, o = t.areRegExpsEqual, i = t.areSetsEqual, c = t.areTypedArraysEqual; +var Re = "[object Arguments]", Ie = "[object Boolean]", ze = "[object Date]", _e = "[object Map]", Je = "[object Number]", Ge = "[object Object]", xe = "[object RegExp]", Be = "[object Set]", Ve = "[object String]", He = Array.isArray, G = typeof ArrayBuffer == "function" && ArrayBuffer.isView ? ArrayBuffer.isView : null, x = Object.assign, Ue = Object.prototype.toString.call.bind(Object.prototype.toString); +function Fe(t) { + var e = t.areArraysEqual, r = t.areDatesEqual, s = t.areMapsEqual, n = t.areObjectsEqual, o = t.arePrimitiveWrappersEqual, a = t.areRegExpsEqual, i = t.areSetsEqual, c = t.areTypedArraysEqual; return function(u, l, f) { if (u === l) return !0; if (u == null || l == null || typeof u != "object" || typeof l != "object") return u !== u && l !== l; - var d = u.constructor; - if (d !== l.constructor) + var b = u.constructor; + if (b !== l.constructor) return !1; - if (d === Object) + if (b === Object) return n(u, l, f); - if (Ie(u)) + if (He(u)) return e(u, l, f); - if (I != null && I(u)) + if (G != null && G(u)) return c(u, l, f); - if (d === Date) + if (b === Date) return r(u, l, f); - if (d === RegExp) - return o(u, l, f); - if (d === Map) + if (b === RegExp) + return a(u, l, f); + if (b === Map) return s(u, l, f); - if (d === Set) + if (b === Set) return i(u, l, f); - var m = ze(u); - return m === Me ? r(u, l, f) : m === De ? o(u, l, f) : m === Pe ? s(u, l, f) : m === Re ? i(u, l, f) : m === Te ? typeof u.then != "function" && typeof l.then != "function" && n(u, l, f) : m === je ? n(u, l, f) : m === Ce || m === Se || m === xe ? a(u, l, f) : !1; + var m = Ue(u); + return m === ze ? r(u, l, f) : m === xe ? a(u, l, f) : m === _e ? s(u, l, f) : m === Be ? i(u, l, f) : m === Ge ? typeof u.then != "function" && typeof l.then != "function" && n(u, l, f) : m === Re ? n(u, l, f) : m === Ie || m === Je || m === Ve ? o(u, l, f) : !1; }; } -function _e(t) { +function ke(t) { var e = t.circular, r = t.createCustomConfig, s = t.strict, n = { - areArraysEqual: s ? y : we, - areDatesEqual: Ee, - areMapsEqual: s ? P(R, y) : R, - areObjectsEqual: s ? y : Oe, - arePrimitiveWrappersEqual: $e, - areRegExpsEqual: Ae, - areSetsEqual: s ? P(x, y) : x, - areTypedArraysEqual: s ? y : qe + areArraysEqual: s ? w : Ce, + areDatesEqual: Me, + areMapsEqual: s ? D(_, w) : _, + areObjectsEqual: s ? w : Pe, + arePrimitiveWrappersEqual: Se, + areRegExpsEqual: Te, + areSetsEqual: s ? D(J, w) : J, + areTypedArraysEqual: s ? w : De }; - if (r && (n = z({}, n, r(n))), e) { - var a = w(n.areArraysEqual), o = w(n.areMapsEqual), i = w(n.areObjectsEqual), c = w(n.areSetsEqual); - n = z({}, n, { - areArraysEqual: a, - areMapsEqual: o, + if (r && (n = x({}, n, r(n))), e) { + var o = E(n.areArraysEqual), a = E(n.areMapsEqual), i = E(n.areObjectsEqual), c = E(n.areSetsEqual); + n = x({}, n, { + areArraysEqual: o, + areMapsEqual: a, areObjectsEqual: i, areSetsEqual: c }); } return n; } -function Ge(t) { - return function(e, r, s, n, a, o, i) { +function Ke(t) { + return function(e, r, s, n, o, a, i) { return t(e, r, i); }; } -function Be(t) { - var e = t.circular, r = t.comparator, s = t.createState, n = t.equals, a = t.strict; +function We(t) { + var e = t.circular, r = t.comparator, s = t.createState, n = t.equals, o = t.strict; if (s) return function(c, h) { - var u = s(), l = u.cache, f = l === void 0 ? e ? /* @__PURE__ */ new WeakMap() : void 0 : l, d = u.meta; + var u = s(), l = u.cache, f = l === void 0 ? e ? /* @__PURE__ */ new WeakMap() : void 0 : l, b = u.meta; return r(c, h, { cache: f, equals: n, - meta: d, - strict: a + meta: b, + strict: o }); }; if (e) @@ -716,83 +770,83 @@ function Be(t) { cache: /* @__PURE__ */ new WeakMap(), equals: n, meta: void 0, - strict: a + strict: o }); }; - var o = { + var a = { cache: void 0, equals: n, meta: void 0, - strict: a + strict: o }; return function(c, h) { - return r(c, h, o); + return r(c, h, a); }; } -var Ve = g(); -g({ strict: !0 }); -g({ circular: !0 }); -g({ +var Le = N(); +N({ strict: !0 }); +N({ circular: !0 }); +N({ circular: !0, strict: !0 }); -g({ +N({ createInternalComparator: function() { - return N; + return g; } }); -g({ +N({ strict: !0, createInternalComparator: function() { - return N; + return g; } }); -g({ +N({ circular: !0, createInternalComparator: function() { - return N; + return g; } }); -g({ +N({ circular: !0, createInternalComparator: function() { - return N; + return g; }, strict: !0 }); -function g(t) { +function N(t) { t === void 0 && (t = {}); - var e = t.circular, r = e === void 0 ? !1 : e, s = t.createInternalComparator, n = t.createState, a = t.strict, o = a === void 0 ? !1 : a, i = _e(t), c = Je(i), h = s ? s(c) : Ge(c); - return Be({ circular: r, comparator: c, createState: n, equals: h, strict: o }); + var e = t.circular, r = e === void 0 ? !1 : e, s = t.createInternalComparator, n = t.createState, o = t.strict, a = o === void 0 ? !1 : o, i = ke(t), c = Fe(i), h = s ? s(c) : Ke(c); + return We({ circular: r, comparator: c, createState: n, equals: h, strict: a }); } -function gt(t, e) { - return Ve(t, e); +function qt(t, e) { + return Le(t, e); } -function J(t, e, r) { - return JSON.stringify(t, (n, a) => { - let o = a; - return e && (o = e(n, o)), o === void 0 && (o = null), o; +function B(t, e, r) { + return JSON.stringify(t, (n, o) => { + let a = o; + return e && (a = e(n, a)), a === void 0 && (a = null), a; }, r); } -function He(t, e) { +function Ze(t, e) { function r(n) { - return Object.keys(n).forEach((a) => { - n[a] === null ? n[a] = void 0 : typeof n[a] == "object" && (n[a] = r(n[a])); + return Object.keys(n).forEach((o) => { + n[o] === null ? n[o] = void 0 : typeof n[o] == "object" && (n[o] = r(n[o])); }), n; } const s = JSON.parse(t, e); if (s !== null) return typeof s == "object" ? r(s) : s; } -function bt(t) { +function jt(t) { try { - const e = J(t); - return e === J(He(e)); + const e = B(t); + return e === B(Ze(e)); } catch { return !1; } } -const Nt = (t) => t.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'").replace(/\//g, "/"), Ue = { +const Ct = (t) => t.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'").replace(/\//g, "/"), Xe = { title: "Platform.Bible menus", type: "object", properties: { @@ -1038,44 +1092,51 @@ const Nt = (t) => t.replace(/&/g, "&").replace(//g, " } } }; -Object.freeze(Ue); +Object.freeze(Xe); export { - Ke as AsyncVariable, - tt as DocumentCombinerEngine, - ne as FIRST_SCR_BOOK_NUM, - oe as FIRST_SCR_CHAPTER_NUM, - ie as FIRST_SCR_VERSE_NUM, - ae as LAST_SCR_BOOK_NUM, - st as PlatformEventEmitter, - rt as UnsubscriberAsyncList, - ut as aggregateUnsubscriberAsyncs, - it as aggregateUnsubscribers, - et as createSyncProxyForAsyncObject, - We as debounce, - E as deepClone, - gt as deepEqual, - He as deserialize, - Ye as getAllObjectFunctionNames, - ue as getChaptersForBook, - Xe as getErrorMessage, - Ze as groupBy, - Nt as htmlEncode, - lt as indexOf, - bt as isSerializable, - Q as isString, - ft as length, - Ue as menuDocumentSchema, - Le as newGuid, - dt as normalize, - nt as offsetBook, - at as offsetChapter, - ot as offsetVerse, - mt as padEnd, - pt as padStart, - J as serialize, - ct as substring, - ht as toArray, - te as wait, - Qe as waitForDuration + et as AsyncVariable, + ut as DocumentCombinerEngine, + ue as FIRST_SCR_BOOK_NUM, + ce as FIRST_SCR_CHAPTER_NUM, + fe as FIRST_SCR_VERSE_NUM, + le as LAST_SCR_BOOK_NUM, + ct as PlatformEventEmitter, + lt as UnsubscriberAsyncList, + dt as aggregateUnsubscriberAsyncs, + mt as aggregateUnsubscribers, + bt as at, + Nt as charAt, + vt as codePointAt, + it as createSyncProxyForAsyncObject, + rt as debounce, + O as deepClone, + qt as deepEqual, + Ze as deserialize, + gt as endsWith, + at as getAllObjectFunctionNames, + he as getChaptersForBook, + nt as getErrorMessage, + st as groupBy, + Ct as htmlEncode, + yt as includes, + Oe as indexOf, + jt as isSerializable, + re as isString, + $e as lastIndexOf, + d as length, + Xe as menuDocumentSchema, + tt as newGuid, + wt as normalize, + ft as offsetBook, + ht as offsetChapter, + pt as offsetVerse, + Et as padEnd, + Ot as padStart, + B as serialize, + $t as slice, + k as substring, + At as toArray, + oe as wait, + ot as waitForDuration }; //# sourceMappingURL=index.js.map diff --git a/lib/platform-bible-utils/dist/index.js.map b/lib/platform-bible-utils/dist/index.js.map index e1d138faf0..4aa3369fd7 100644 --- a/lib/platform-bible-utils/dist/index.js.map +++ b/lib/platform-bible-utils/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit,\n} from 'stringz';\n\nexport const indexOf = stringzIndexOf;\nexport const substring = stringzSubstring;\nexport const length = stringzLength;\nexport const toArray = stringzToArray;\n\nexport const padStart = (string: string, targetLength: number, padString?: string) => {\n limit(string, targetLength, padString, 'left');\n};\n\nexport const padEnd = (string: string, targetLength: number, padString?: string) => {\n limit(string, targetLength, padString, 'right');\n};\n\nexport const normalize = (string: string, form: 'NFC' | 'NFD' | 'none' = 'NFC') => {\n const upperCaseForm = form.toUpperCase();\n if(upperCaseForm==='NONE')\n {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","stringzIndexOf","stringzSubstring","stringzLength","stringzToArray","padStart","string","targetLength","padEnd","normalize","form","upperCaseForm","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","result","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","matchIndex","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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","x_google_ignoreList":[7,8,10]} \ No newline at end of file +{"version":3,"file":"index.js","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * Finds the Unicode code point at the given index\n *\n * @param {string} string String to index\n * @param {number} index Position of the character to be returned in range of 0 to -length(string)\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > length(string) || index < -length(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * Always indexes string as a sequence of Unicode code points\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, empty string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > length(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to index\n * @param {number} index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {number | undefined} Non-negative integer representing the code point value of the\n * character at the given index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > length(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * Determines whether a string ends with the characters of this string. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Characters to search for at the end of the string\n * @param {number} [endPosition=length(string)] End position where searchString is expected to be\n * found. Default is `length(string)`\n * @returns {boolean} True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = length(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + length(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * Performs a case-sensitive search to determine if searchString is found in string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString String to search for\n * @param {string} [position=0] Position within the string to start searching for searchString.\n * Default is `0`\n * @returns {boolean} True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * Returns the index of the first occurrence of a given string. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The string to search for\n * @param {number} [position=0] Start of searching. Default is `0`\n * @returns {number} Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * Searches this string and returns the index of the last occurrence of the specified substring.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Substring to search for\n * @param {number} [position=+Infinity] The method returns the index of the last occurrence of the\n * specified substring at a position less than or equal to position. . Default is `+Infinity`\n * @returns {number} Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(\n string: string,\n searchString: string,\n position: number = +Infinity,\n): number {\n let validatedPosition = position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= length(string)) {\n validatedPosition = length(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, length(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * Returns the length of a string. This function handles Unicode code points instead of UTF-16\n * character codes.\n *\n * @param {string} string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function length(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * Returns the Unicode Normalization Form of this string.\n *\n * @param {string} string The starting string\n * @param {'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'} [form='NFC'] Form specifying the Unicode\n * Normalization Form. Default is `'NFC'`\n * @returns {string} A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within targetLength, it will be truncated. Default is `\" \"`\n * @returns {string} String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\nfunction correctSliceIndex(stringLength: number, index: number) {\n if (index > stringLength) return stringLength;\n if (index < -stringLength) return 0;\n if (index < 0) return index + stringLength;\n return index;\n}\n\n/**\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The starting string\n * @param {number} indexStart The index of the first character to include in the returned substring.\n * @param {number} indexEnd The index of the first character to exclude from the returned substring.\n * @returns {string} A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const stringLength: number = length(string);\n if (\n indexStart > stringLength ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(\n indexStart > 0 &&\n indexStart < stringLength &&\n indexEnd < 0 &&\n indexEnd > -stringLength\n )) ||\n indexEnd < -stringLength ||\n (indexStart < 0 && indexStart > -stringLength && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(stringLength, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The string to split\n * @param {string | RegExp} separator The pattern describing where each split should occur\n * @param {number} splitLimit Limit on the number of substrings to be included in the array. Splits\n * the string at each occurrence of specified separator, but stops when limit entries have been\n * placed in the array.\n * @returns {string[] | undefined} An array of strings, split at each point where separator occurs\n * in the starting string. Returns undefined if separator is not found in string.\n */\nexport function split(\n string: string,\n separator: string | RegExp,\n splitLimit?: number,\n): string[] | undefined {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !separator.flags.includes('g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return undefined;\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = length(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate. This function handles Unicode code points instead of UTF-16 character\n * codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The characters to be searched for at the start of this string.\n * @param {number} [position=0] The start position at which searchString is expected to be found\n * (the index of searchString's first character). Default is `0`\n * @returns {boolean} True if the given characters are found at the beginning of the string,\n * including when searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * Returns a substring by providing start and length. This function handles Unicode code points\n * instead of UTF-16 character codes. This function is not exported because it is considered\n * deprecated, however it is still useful as a local helper function.\n *\n * @param {string} string String to be divided\n * @param {number} [begin=Start of string] Start position. Default is `Start of string`\n * @param {number} [len=String length minus start parameter] Length of result. Default is `String\n * length minus start parameter`. Default is `String length minus start parameter`\n * @returns {string} Substring from starting string\n */\nfunction substr(string: string, begin: number = 0, len: number = length(string) - begin): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * Returns a substring by providing start and end position. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to be divided\n * @param {string} begin Start position\n * @param {number} [end=End of string] End position. Default is `End of string`\n * @returns {string} Substring from starting string\n */\nexport function substring(\n string: string,\n begin?: number | undefined,\n end: number | undefined = length(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * Converts a string to an array of string characters. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param {string} string String to convert to array\n * @returns {string[]} An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","stringLength","slice","indexStart","indexEnd","newStart","newEnd","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","result","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","matchIndex","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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","x_google_ignoreList":[7,8,10]} \ No newline at end of file diff --git a/lib/platform-bible-utils/src/string-util.test.ts b/lib/platform-bible-utils/src/string-util.test.ts index b708d567c4..1eff6d2872 100644 --- a/lib/platform-bible-utils/src/string-util.test.ts +++ b/lib/platform-bible-utils/src/string-util.test.ts @@ -17,114 +17,136 @@ import { toArray, } from './string-util'; -const SURROGATE_PAIRS_STRING = - 'Look𐐷At🦄All😎These😁Awesome🍕Symbols💩That🚀Are📷Represented😉By🍕Surrogate🔥Pairs💋!🌟'; - const SHORT_SURROGATE_PAIRS_STRING = 'Look𐐷At🦄'; const SHORT_SURROGATE_PAIRS_ARRAY = ['L', 'o', 'o', 'k', '𐐷', 'A', 't', '🦄']; -const SHORTER_SURROGATE_PAIRS_STRING = 'Look𐐷At🦄This𐐷Thing😉Its𐐷Awesome'; -const SHORTER_SURROGATE_PAIRS_ARRAY = ['Look', 'At🦄This', 'Thing😉Its', 'Awesome']; +const MEDIUM_SURROGATE_PAIRS_STRING = 'Look𐐷At🦄This𐐷Thing😉Its𐐷Awesome'; +const MEDIUM_SURROGATE_PAIRS_ARRAY = ['Look', 'At🦄This', 'Thing😉Its', 'Awesome']; + +const LONG_SURROGATE_PAIRS_STRING = + 'Look𐐷At🦄All😎These😁Awesome🍕Symbols💩That🚀Are📷Represented😉By🍕Surrogate🔥Pairs💋!🌟'; const POS_FIRST_PIZZA = 25; const POS_SECOND_PIZZA = 57; const SURROGATE_PAIRS_STRING_LENGTH = 76; const TEN_SPACES = ' '; +const SEVEN_XS = 'XXXXXXX'; const NORMALIZE_STRING = '\u0041\u006d\u00e9\u006c\u0069\u0065'; const NORMALIZE_SURROGATE_PAIRS = '\u0041\u006d\u0065\u0301\u006c\u0069\u0065'; describe('at', () => { test('at with in bounds index', () => { - const result = at(SURROGATE_PAIRS_STRING, 4); + const result = at(LONG_SURROGATE_PAIRS_STRING, 4); expect(result).toEqual('𐐷'); }); test('at with negative index returns last character', () => { - const result = at(SURROGATE_PAIRS_STRING, -1); + const result = at(LONG_SURROGATE_PAIRS_STRING, -1); expect(result).toEqual('🌟'); }); test('at with index greater than length returns undefined', () => { - const result = at(SURROGATE_PAIRS_STRING, length(SURROGATE_PAIRS_STRING) + 10); + const result = at(LONG_SURROGATE_PAIRS_STRING, length(LONG_SURROGATE_PAIRS_STRING) + 10); expect(result).toEqual(undefined); }); }); describe('charAt', () => { - test('charAt', () => { - const result = charAt(SURROGATE_PAIRS_STRING, 7); + test('0 < index < string length', () => { + const result = charAt(MEDIUM_SURROGATE_PAIRS_STRING, 7); expect(result).toEqual('🦄'); }); - // TODO: more tests + test('index < 0', () => { + const result = charAt(MEDIUM_SURROGATE_PAIRS_STRING, -2); + expect(result).toEqual(''); + }); + + test('index > string length', () => { + const result = charAt(MEDIUM_SURROGATE_PAIRS_STRING, 50); + expect(result).toEqual(''); + }); }); describe('codePointAt', () => { - test('codePointAt', () => { - const result = codePointAt(SURROGATE_PAIRS_STRING, 11); - expect(result).toEqual(128526); + test('codePointAt for regular character', () => { + const result = codePointAt(MEDIUM_SURROGATE_PAIRS_STRING, 11); + expect(result).toEqual(115); + }); + + test('codePointAt for surrogate pair', () => { + const result = codePointAt(MEDIUM_SURROGATE_PAIRS_STRING, 7); + expect(result).toEqual(129412); + }); + + test('codePointAt index < 0', () => { + const result = codePointAt(MEDIUM_SURROGATE_PAIRS_STRING, -1); + expect(result).toEqual(undefined); }); - // TODO: more tests + test('codePointAt index > string length', () => { + const result = codePointAt(MEDIUM_SURROGATE_PAIRS_STRING, 50); + expect(result).toEqual(undefined); + }); }); describe('endsWith', () => { test('endsWith without position', () => { - const result = endsWith(SURROGATE_PAIRS_STRING, '💋!🌟'); + const result = endsWith(LONG_SURROGATE_PAIRS_STRING, '💋!🌟'); expect(result).toEqual(true); }); test('endsWith with position', () => { - const result = endsWith(SURROGATE_PAIRS_STRING, 'At🦄', 8); + const result = endsWith(LONG_SURROGATE_PAIRS_STRING, 'At🦄', 8); expect(result).toEqual(true); }); }); describe('includes', () => { test('includes without position', () => { - const result = includes(SURROGATE_PAIRS_STRING, '🍕Symbols💩'); + const result = includes(LONG_SURROGATE_PAIRS_STRING, '🍕Symbols💩'); expect(result).toEqual(true); }); test('includes with position', () => { - const result = includes(SURROGATE_PAIRS_STRING, '🦄All😎', 7); + const result = includes(LONG_SURROGATE_PAIRS_STRING, '🦄All😎', 7); expect(result).toEqual(true); }); test('includes with position that is to high, so no matches are found', () => { - const result = includes(SURROGATE_PAIRS_STRING, '🦄All😎', 10); + const result = includes(LONG_SURROGATE_PAIRS_STRING, '🦄All😎', 10); expect(result).toEqual(false); }); }); describe('indexOf', () => { test('indexOf without position', () => { - const result = indexOf(SURROGATE_PAIRS_STRING, '🍕'); + const result = indexOf(LONG_SURROGATE_PAIRS_STRING, '🍕'); expect(result).toEqual(POS_FIRST_PIZZA); }); test('indexOf with position', () => { - const result = indexOf(SURROGATE_PAIRS_STRING, '🍕', 40); + const result = indexOf(LONG_SURROGATE_PAIRS_STRING, '🍕', 40); expect(result).toEqual(POS_SECOND_PIZZA); }); }); describe('lastIndexOf', () => { test('lastIndexOf without position', () => { - const result = lastIndexOf(SURROGATE_PAIRS_STRING, '🍕'); + const result = lastIndexOf(LONG_SURROGATE_PAIRS_STRING, '🍕'); expect(result).toEqual(POS_SECOND_PIZZA); }); test('lastIndexOf with position', () => { - const result = lastIndexOf(SURROGATE_PAIRS_STRING, '🍕', 5); + const result = lastIndexOf(LONG_SURROGATE_PAIRS_STRING, '🍕', 5); expect(result).toEqual(-1); }); }); describe('length', () => { test('length is correct', () => { - const result = length(SURROGATE_PAIRS_STRING); + const result = length(LONG_SURROGATE_PAIRS_STRING); expect(result).toEqual(SURROGATE_PAIRS_STRING_LENGTH); }); }); @@ -161,11 +183,18 @@ describe('normalize', () => { describe('padEnd', () => { test('padEnd without padString', () => { - const result = padEnd(SURROGATE_PAIRS_STRING, SURROGATE_PAIRS_STRING_LENGTH + 10, undefined); - expect(result).toEqual(SURROGATE_PAIRS_STRING + TEN_SPACES); + const result = padEnd( + LONG_SURROGATE_PAIRS_STRING, + SURROGATE_PAIRS_STRING_LENGTH + 10, + undefined, + ); + expect(result).toEqual(LONG_SURROGATE_PAIRS_STRING + TEN_SPACES); }); - // TODO: test with one character padString + test('padEnd with padString', () => { + const result = padEnd(LONG_SURROGATE_PAIRS_STRING, SURROGATE_PAIRS_STRING_LENGTH + 7, 'X'); + expect(result).toEqual(LONG_SURROGATE_PAIRS_STRING + SEVEN_XS); + }); // Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59 // It expects 10 'ha' but it should only give 5 'ha' because that would be length 10 @@ -178,11 +207,18 @@ describe('padEnd', () => { describe('padStart', () => { test('padStart without padString', () => { - const result = padStart(SURROGATE_PAIRS_STRING, SURROGATE_PAIRS_STRING_LENGTH + 10, undefined); - expect(result).toEqual(TEN_SPACES + SURROGATE_PAIRS_STRING); + const result = padStart( + LONG_SURROGATE_PAIRS_STRING, + SURROGATE_PAIRS_STRING_LENGTH + 10, + undefined, + ); + expect(result).toEqual(TEN_SPACES + LONG_SURROGATE_PAIRS_STRING); }); - // TODO: test with one character padString + test('padStart with padString', () => { + const result = padStart(LONG_SURROGATE_PAIRS_STRING, SURROGATE_PAIRS_STRING_LENGTH + 7, 'X'); + expect(result).toEqual(SEVEN_XS + LONG_SURROGATE_PAIRS_STRING); + }); // Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59 // It expects 10 'ha' but it should only give 5 'ha' because that would be length 10 @@ -194,36 +230,105 @@ describe('padStart', () => { }); describe('slice', () => { - test('slice with with end greater than negative length of string returns empty string', () => { - const result = slice(SHORT_SURROGATE_PAIRS_STRING, 0, -1000); + test('start (-inf)-(-L)', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, -100); + expect(result).toEqual(MEDIUM_SURROGATE_PAIRS_STRING); + }); + test('start (-L)-0', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, -3); + expect(result).toEqual('ome'); + }); + test('start 0-L', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, 3); + expect(result).toEqual('k𐐷At🦄This𐐷Thing😉Its𐐷Awesome'); + }); + test('start L-inf', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, 50); expect(result).toEqual(''); }); - - test('slice with begin greater than negative length of string returns whole string', () => { - const result = slice(SHORT_SURROGATE_PAIRS_STRING, -1000); - expect(result).toEqual(SHORT_SURROGATE_PAIRS_STRING); + test('start (-inf)-(-L) end (-inf)-(-L)', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, -200, -100); + expect(result).toEqual(''); + }); + test('start (-inf)-(-L) end (-L)-0', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, -100, -10); + expect(result).toEqual('Look𐐷At🦄This𐐷Thing😉I'); + }); + test('start (-inf)-(-L) end 0-L', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, -100, 8); + expect(result).toEqual('Look𐐷At🦄'); + }); + test('start (-inf)-(-L) end L-inf', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, -100, 100); + expect(result).toEqual(MEDIUM_SURROGATE_PAIRS_STRING); + }); + test('start (-L)-0 end (-inf)-(-L)', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, -5, -100); + expect(result).toEqual(''); + }); + test('start (-L)-0 end (-L)-0', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, -5, -10); + expect(result).toEqual(''); }); - // Failing receives '' - // test('slice with begin of -1 returns last character', () => { - // const result = slice(SHORT_SURROGATE_PAIRS_STRING, -1); - // expect(result).toEqual('🦄'); - // }); - - test('slice with in bounds begin and end', () => { - const result = slice(SHORT_SURROGATE_PAIRS_STRING, 0, 2); - expect(result).toEqual('Lo'); + test('start (-L)-0 end (-L)-0 and start < end', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, -10, -5); + expect(result).toEqual('ts𐐷Aw'); + }); + test('start (-L)-0 end 0-L', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, -5, 8); + expect(result).toEqual(''); + }); + test('start (-L)-0 end L-inf', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, -5, 100); + expect(result).toEqual(''); + }); + test('start 0-L end (-inf)-(-L)', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, 5, -100); + expect(result).toEqual(''); + }); + test('start 0-L end (-L)-0', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, 5, -10); + expect(result).toEqual('At🦄This𐐷Thing😉I'); + }); + test('start 0-L end 0-L', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, 5, 8); + expect(result).toEqual('At🦄'); + }); + test('start 0-L end 0-L, and start > end', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, 8, 5); + expect(result).toEqual(''); + }); + test('start 0-L end L-inf', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, 5, 100); + expect(result).toEqual('At🦄This𐐷Thing😉Its𐐷Awesome'); + }); + test('start L-inf end (-inf)-(-L)', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, 50, -100); + expect(result).toEqual(''); + }); + test('start L-inf end (-L)-0', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, 50, -10); + expect(result).toEqual(''); + }); + test('start L-inf end 0-L', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, 50, 8); + expect(result).toEqual(''); + }); + test('start L-inf end L-inf', () => { + const result = slice(MEDIUM_SURROGATE_PAIRS_STRING, 50, 100); + expect(result).toEqual(''); }); }); describe('split', () => { test('split without splitLimit', () => { - const result = split(SHORTER_SURROGATE_PAIRS_STRING, '𐐷'); - expect(result).toEqual(SHORTER_SURROGATE_PAIRS_ARRAY); + const result = split(MEDIUM_SURROGATE_PAIRS_STRING, '𐐷'); + expect(result).toEqual(MEDIUM_SURROGATE_PAIRS_ARRAY); }); test('split with splitLimit', () => { - const result = split(SHORTER_SURROGATE_PAIRS_STRING, '𐐷', 2); + const result = split(MEDIUM_SURROGATE_PAIRS_STRING, '𐐷', 2); expect(result).toEqual(['Look', 'At🦄This𐐷Thing😉Its𐐷Awesome']); }); @@ -238,46 +343,46 @@ describe('split', () => { }); test('split with RegExp separator', () => { - const result = split(SHORTER_SURROGATE_PAIRS_STRING, /[A-Z]/); + const result = split(MEDIUM_SURROGATE_PAIRS_STRING, /[A-Z]/); expect(result).toEqual(['', 'ook𐐷', 't🦄', 'his𐐷', 'hing😉', 'ts𐐷', 'wesome']); }); test('split with RegExp separator that contains surrogate pairs', () => { - const result = split(SHORTER_SURROGATE_PAIRS_STRING, /🦄/); + const result = split(MEDIUM_SURROGATE_PAIRS_STRING, /🦄/); expect(result).toEqual(['Look𐐷At', 'This𐐷Thing😉Its𐐷Awesome']); }); }); describe('startsWith', () => { test('startsWith without position', () => { - const result = startsWith(SURROGATE_PAIRS_STRING, 'Look𐐷'); + const result = startsWith(LONG_SURROGATE_PAIRS_STRING, 'Look𐐷'); expect(result).toEqual(true); }); test('startsWith with position, searchString is not the start', () => { - const result = startsWith(SURROGATE_PAIRS_STRING, 'Look𐐷', 5); + const result = startsWith(LONG_SURROGATE_PAIRS_STRING, 'Look𐐷', 5); expect(result).toEqual(false); }); test('startsWith with position, searchString is the start', () => { - const result = startsWith(SURROGATE_PAIRS_STRING, 'At🦄', 5); + const result = startsWith(LONG_SURROGATE_PAIRS_STRING, 'At🦄', 5); expect(result).toEqual(true); }); }); describe('substring', () => { test('substring with begin', () => { - const result = substring(SURROGATE_PAIRS_STRING, POS_FIRST_PIZZA); + const result = substring(LONG_SURROGATE_PAIRS_STRING, POS_FIRST_PIZZA); expect(result).toEqual('🍕Symbols💩That🚀Are📷Represented😉By🍕Surrogate🔥Pairs💋!🌟'); }); test('substring with end', () => { - const result = substring(SURROGATE_PAIRS_STRING, undefined, POS_FIRST_PIZZA); + const result = substring(LONG_SURROGATE_PAIRS_STRING, undefined, POS_FIRST_PIZZA); expect(result).toEqual('Look𐐷At🦄All😎These😁Awesome'); }); test('substring with begin and end', () => { - const result = substring(SURROGATE_PAIRS_STRING, POS_FIRST_PIZZA, POS_SECOND_PIZZA); + const result = substring(LONG_SURROGATE_PAIRS_STRING, POS_FIRST_PIZZA, POS_SECOND_PIZZA); expect(result).toEqual('🍕Symbols💩That🚀Are📷Represented😉By'); }); }); diff --git a/lib/platform-bible-utils/src/string-util.ts b/lib/platform-bible-utils/src/string-util.ts index 9c8286cbe5..70d4f63680 100644 --- a/lib/platform-bible-utils/src/string-util.ts +++ b/lib/platform-bible-utils/src/string-util.ts @@ -199,14 +199,13 @@ export function padStart(string: string, targetLength: number, padString: string return stringzLimit(string, targetLength, padString, 'left'); } -// function validateSliceIndex(string: string, index: number) { -// if (index < -length(string)) return -length(string); -// if (index > length(string)) return length(string); -// if (index < 0) return index + length(string); -// return index; -// } - -// TODO: slice accepts negative and loops include differences +function correctSliceIndex(stringLength: number, index: number) { + if (index > stringLength) return stringLength; + if (index < -stringLength) return 0; + if (index < 0) return index + stringLength; + return index; +} + /** * Extracts a section of this string and returns it as a new string, without modifying the original * string. This function handles Unicode code points instead of UTF-16 character codes. @@ -217,20 +216,26 @@ export function padStart(string: string, targetLength: number, padString: string * @returns {string} A new string containing the extracted section of the string. */ export function slice(string: string, indexStart: number, indexEnd?: number): string { - let newStart = indexStart; - let newEnd = indexEnd || 0; - - if (!newStart) newStart = 0; - if (newStart >= length(string)) return ''; - if (newStart < 0) newStart += length(string); - - if (newEnd >= length(string)) newEnd = length(string) - 1; - if (newEnd < 0) newEnd += length(string); - - // AFTER normalizing negatives - if (newEnd <= newStart) return ''; - - return substr(string, newStart, newEnd - newStart); + const stringLength: number = length(string); + if ( + indexStart > stringLength || + (indexEnd && + ((indexStart > indexEnd && + !( + indexStart > 0 && + indexStart < stringLength && + indexEnd < 0 && + indexEnd > -stringLength + )) || + indexEnd < -stringLength || + (indexStart < 0 && indexStart > -stringLength && indexEnd > 0))) + ) + return ''; + + const newStart = correctSliceIndex(stringLength, indexStart); + const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined; + + return substring(string, newStart, newEnd); } /** From e3d05fed83c3706baa797e297e42c2e98bc632e6 Mon Sep 17 00:00:00 2001 From: Rolf Heij Date: Mon, 19 Feb 2024 14:30:14 -0500 Subject: [PATCH 15/22] Undo usage of strings util in edit.papi-d-ts.ts --- lib/papi-dts/edit-papi-d-ts.ts | 5 +- lib/papi-dts/papi.d.ts | 784 +++++++++++++++++--- lib/platform-bible-utils/dist/index.cjs | 2 +- lib/platform-bible-utils/dist/index.cjs.map | 2 +- lib/platform-bible-utils/dist/index.d.ts | 27 + lib/platform-bible-utils/dist/index.js | 390 +++++----- lib/platform-bible-utils/dist/index.js.map | 2 +- lib/platform-bible-utils/src/index.ts | 16 +- 8 files changed, 913 insertions(+), 315 deletions(-) diff --git a/lib/papi-dts/edit-papi-d-ts.ts b/lib/papi-dts/edit-papi-d-ts.ts index a547ad6356..1dd544071e 100644 --- a/lib/papi-dts/edit-papi-d-ts.ts +++ b/lib/papi-dts/edit-papi-d-ts.ts @@ -4,7 +4,6 @@ import fs from 'fs'; import typescript from 'typescript'; import escapeStringRegexp from 'escape-string-regexp'; import { exit } from 'process'; -import {substring} from 'platform-bible-utils' const start = performance.now(); @@ -144,9 +143,9 @@ if (paths) { const asteriskIndex = path.indexOf('*'); // Get the path alias without the * at the end but with the @ - const pathAlias = substring(path, 0, asteriskIndex); + const pathAlias = path.substring(0, asteriskIndex); // Get the path alias without the @ at the start - const pathAliasNoAt = substring(pathAlias, 1); + const pathAliasNoAt = pathAlias.substring(1); // Regex-escaped path alias without @ to be used in a regex string const pathAliasNoAtRegex = escapeStringRegexp(pathAliasNoAt); diff --git a/lib/papi-dts/papi.d.ts b/lib/papi-dts/papi.d.ts index bed7658673..32a49ecd55 100644 --- a/lib/papi-dts/papi.d.ts +++ b/lib/papi-dts/papi.d.ts @@ -171,7 +171,6 @@ declare module 'shared/models/web-view.model' { */ export type WebViewDefinitionUpdateInfo = Partial; /** - * JSDOC SOURCE UseWebViewStateHook * * A React hook for working with a state object tied to a webview. Returns a WebView state value and * a function to set it. Use similarly to `useState`. @@ -217,7 +216,6 @@ declare module 'shared/models/web-view.model' { resetWebViewState: () => void, ]; /** - * JSDOC SOURCE GetWebViewDefinitionUpdatableProperties * * Gets the updatable properties on this WebView's WebView definition * @@ -228,7 +226,6 @@ declare module 'shared/models/web-view.model' { | WebViewDefinitionUpdatableProperties | undefined; /** - * JSDOC SOURCE UpdateWebViewDefinition * * Updates this WebView with the specified properties * @@ -246,11 +243,67 @@ declare module 'shared/models/web-view.model' { export type UpdateWebViewDefinition = (updateInfo: WebViewDefinitionUpdateInfo) => boolean; /** Props that are passed into the web view itself inside the iframe in the web view tab component */ export type WebViewProps = { - /** JSDOC DESTINATION UseWebViewStateHook */ + /** + * + * A React hook for working with a state object tied to a webview. Returns a WebView state value and + * a function to set it. Use similarly to `useState`. + * + * Only used in WebView iframes. + * + * _@param_ `stateKey` Key of the state value to use. The webview state holds a unique value per + * key. + * + * WARNING: MUST BE STABLE - const or wrapped in useState, useMemo, etc. The reference must not be + * updated every render + * + * _@param_ `defaultStateValue` Value to use if the web view state didn't contain a value for the + * given 'stateKey' + * + * Note: this parameter is internally assigned to a `ref`, so changing it will not cause any hooks + * to re-run with its new value. Running `resetWebViewState()` will always update the state value + * returned to the latest `defaultStateValue`, and changing the `stateKey` will use the latest + * `defaultStateValue`. However, if `defaultStateValue` is changed while a state is + * `defaultStateValue` (meaning it is reset and has no value), the returned state value will not be + * updated to the new `defaultStateValue`. + * + * _@returns_ `[stateValue, setStateValue, resetWebViewState]` + * + * - `webViewStateValue`: The current value for the web view state at the key specified or + * `defaultStateValue` if a state was not found + * - `setWebViewState`: Function to use to update the web view state value at the key specified + * - `resetWebViewState`: Function that removes the web view state and resets the value to + * `defaultStateValue` + * + * _@example_ + * + * ```typescript + * const [lastPersonSeen, setLastPersonSeen] = useWebViewState('lastSeen', 'No one'); + * ``` + */ useWebViewState: UseWebViewStateHook; - /** JSDOC DESTINATION GetWebViewDefinitionUpdatableProperties */ + /** + * + * Gets the updatable properties on this WebView's WebView definition + * + * _@returns_ updatable properties this WebView's WebView definition or undefined if not found for + * some reason + */ getWebViewDefinitionUpdatableProperties: GetWebViewDefinitionUpdatableProperties; - /** JSDOC DESTINATION UpdateWebViewDefinition */ + /** + * + * Updates this WebView with the specified properties + * + * _@param_ `updateInfo` properties to update on the WebView. Any unspecified properties will stay + * the same + * + * _@returns_ true if successfully found the WebView to update; false otherwise + * + * _@example_ + * + * ```typescript + * updateWebViewDefinition({ title: `Hello ${name}` }); + * ``` + */ updateWebViewDefinition: UpdateWebViewDefinition; }; /** Options that affect what `webViews.getWebView` does */ @@ -310,7 +363,43 @@ declare module 'shared/global-this.model' { * in WebView iframes. */ var webViewComponent: FunctionComponent; - /** JSDOC DESTINATION UseWebViewStateHook */ + /** + * + * A React hook for working with a state object tied to a webview. Returns a WebView state value and + * a function to set it. Use similarly to `useState`. + * + * Only used in WebView iframes. + * + * _@param_ `stateKey` Key of the state value to use. The webview state holds a unique value per + * key. + * + * WARNING: MUST BE STABLE - const or wrapped in useState, useMemo, etc. The reference must not be + * updated every render + * + * _@param_ `defaultStateValue` Value to use if the web view state didn't contain a value for the + * given 'stateKey' + * + * Note: this parameter is internally assigned to a `ref`, so changing it will not cause any hooks + * to re-run with its new value. Running `resetWebViewState()` will always update the state value + * returned to the latest `defaultStateValue`, and changing the `stateKey` will use the latest + * `defaultStateValue`. However, if `defaultStateValue` is changed while a state is + * `defaultStateValue` (meaning it is reset and has no value), the returned state value will not be + * updated to the new `defaultStateValue`. + * + * _@returns_ `[stateValue, setStateValue, resetWebViewState]` + * + * - `webViewStateValue`: The current value for the web view state at the key specified or + * `defaultStateValue` if a state was not found + * - `setWebViewState`: Function to use to update the web view state value at the key specified + * - `resetWebViewState`: Function that removes the web view state and resets the value to + * `defaultStateValue` + * + * _@example_ + * + * ```typescript + * const [lastPersonSeen, setLastPersonSeen] = useWebViewState('lastSeen', 'No one'); + * ``` + */ var useWebViewState: UseWebViewStateHook; /** * Retrieve the value from web view state with the given 'stateKey', if it exists. Otherwise @@ -328,9 +417,29 @@ declare module 'shared/global-this.model' { webViewId: string, webViewDefinitionUpdateInfo: WebViewDefinitionUpdateInfo, ) => boolean; - /** JSDOC DESTINATION GetWebViewDefinitionUpdatableProperties */ + /** + * + * Gets the updatable properties on this WebView's WebView definition + * + * _@returns_ updatable properties this WebView's WebView definition or undefined if not found for + * some reason + */ var getWebViewDefinitionUpdatableProperties: GetWebViewDefinitionUpdatableProperties; - /** JSDOC DESTINATION UpdateWebViewDefinition */ + /** + * + * Updates this WebView with the specified properties + * + * _@param_ `updateInfo` properties to update on the WebView. Any unspecified properties will stay + * the same + * + * _@returns_ true if successfully found the WebView to update; false otherwise + * + * _@example_ + * + * ```typescript + * updateWebViewDefinition({ title: `Hello ${name}` }); + * ``` + */ var updateWebViewDefinition: UpdateWebViewDefinition; } /** Type of Paranext process */ @@ -755,7 +864,6 @@ declare module 'shared/services/logger.service' { */ export function formatLog(message: string, serviceName: string, tag?: string): string; /** - * JSDOC SOURCE logger * * All extensions and services should use this logger to provide a unified output of logs */ @@ -777,8 +885,7 @@ declare module 'client/services/web-socket.interface' { declare module 'renderer/services/renderer-web-socket.service' { /** Once our network is running, run this to stop extensions from connecting to it directly */ export const blockWebSocketsToPapiNetwork: () => void; - /** - * JSDOC SOURCE PapiRendererWebSocket This wraps the browser's WebSocket implementation to provide + /** This wraps the browser's WebSocket implementation to provide * better control over internet access. It is isomorphic with the standard WebSocket, so it should * act as a drop-in replacement. * @@ -1333,7 +1440,6 @@ declare module 'shared/services/network.service' { getNetworkEvent: typeof getNetworkEvent; } /** - * JSDOC SOURCE papiNetworkService * * Service that provides a way to send and receive network events */ @@ -2035,7 +2141,6 @@ declare module 'shared/models/data-provider-engine.model' { } from 'shared/models/data-provider.model'; import { NetworkableObject } from 'shared/models/network-object.model'; /** - * JSDOC SOURCE DataProviderEngineNotifyUpdate * * Method to run to send clients updates for a specific data type outside of the `set` * method. papi overwrites this function on the DataProviderEngine itself to emit an update based on @@ -2084,7 +2189,43 @@ declare module 'shared/models/data-provider-engine.model' { * @see {@link IDataProviderEngine} for more information on using this type. */ export type WithNotifyUpdate = { - /** JSDOC DESTINATION DataProviderEngineNotifyUpdate */ + /** + * + * Method to run to send clients updates for a specific data type outside of the `set` + * method. papi overwrites this function on the DataProviderEngine itself to emit an update based on + * the `updateInstructions` and then run the original `notifyUpdateMethod` from the + * `DataProviderEngine`. + * + * _@example_ To run `notifyUpdate` function so it updates the Verse and Heresy data types (in a + * data provider engine): + * + * ```typescript + * this.notifyUpdate(['Verse', 'Heresy']); + * ``` + * + * _@example_ You can log the manual updates in your data provider engine by specifying the + * following `notifyUpdate` function in the data provider engine: + * + * ```typescript + * notifyUpdate(updateInstructions) { + * papi.logger.info(updateInstructions); + * } + * ``` + * + * Note: This function's return is treated the same as the return from `set` + * + * _@param_ `updateInstructions` Information that papi uses to interpret whether to send out + * updates. Defaults to `'*'` (meaning send updates for all data types) if parameter + * `updateInstructions` is not provided or is undefined. Otherwise returns `updateInstructions`. + * papi passes the interpreted update value into this `notifyUpdate` function. For example, running + * `this.notifyUpdate()` will call the data provider engine's `notifyUpdate` with + * `updateInstructions` of `'*'`. + * + * _@see_ {@link DataProviderUpdateInstructions} for more info on the `updateInstructions` parameter + * + * WARNING: Do not update a data type in its `get` method (unless you make a base case)! + * It will create a destructive infinite loop. + */ notifyUpdate: DataProviderEngineNotifyUpdate; }; /** @@ -2160,7 +2301,6 @@ declare module 'shared/models/data-provider-engine.model' { Partial>; export default IDataProviderEngine; /** - * JSDOC SOURCE DataProviderEngine * * Abstract class that provides a placeholder `notifyUpdate` for data provider engine classes. If a * data provider engine class extends this class, it doesn't have to specify its own `notifyUpdate` @@ -2823,7 +2963,6 @@ declare module 'shared/services/command.service' { handler: CommandHandlers[CommandName], ) => Promise; /** - * JSDOC SOURCE commandService * * The command service allows you to exchange messages with other components in the platform. You * can register a command that other services and extensions can send you. You can send commands to @@ -3021,7 +3160,6 @@ declare module 'shared/services/web-view.service-model' { import { AddWebViewEvent, Layout } from 'shared/models/docking-framework.model'; import { PlatformEvent } from 'platform-bible-utils'; /** - * JSDOC SOURCE papiWebViewService * * Service exposing various functions related to using webViews * @@ -3169,7 +3307,6 @@ declare module 'shared/services/web-view-provider.service' { } const webViewProviderService: WebViewProviderService; /** - * JSDOC SOURCE papiWebViewProviderService * * Interface for registering webView providers */ @@ -3183,7 +3320,6 @@ declare module 'shared/services/internet.service' { fetch: typeof papiFetch; } /** - * JSDOC SOURCE internetService * * Service that provides a way to call `fetch` since the original function is not available */ @@ -3204,7 +3340,6 @@ declare module 'shared/services/data-provider.service' { } from 'papi-shared-types'; import IDataProvider, { IDisposableDataProvider } from 'shared/models/data-provider.interface'; /** - * JSDOC SOURCE DataProviderServiceHasKnown * * Indicate if we are aware of an existing data provider with the given name. If a data provider * with the given name is somewhere else on the network, this function won't tell you about it @@ -3212,7 +3347,6 @@ declare module 'shared/services/data-provider.service' { */ function hasKnown(providerName: string): boolean; /** - * JSDOC SOURCE DataProviderServiceDecoratorsIgnore * * Decorator function that marks a data provider engine `set___` or `get___` method to be ignored. * papi will not layer over these methods or consider them to be data type methods @@ -3260,7 +3394,6 @@ declare module 'shared/services/data-provider.service' { */ function ignore(target: object, member: string): void; /** - * JSDOC SOURCE DataProviderServiceDecoratorsDoNotNotify * * Decorator function that marks a data provider engine `set` method not to automatically * emit an update and notify subscribers of a change to the data. papi will still consider the @@ -3310,7 +3443,6 @@ declare module 'shared/services/data-provider.service' { */ function doNotNotify(target: object, member: string): void; /** - * JSDOC SOURCE DataProviderServiceDecorators * * A collection of decorators to be used with the data provider service * @@ -3328,13 +3460,73 @@ declare module 'shared/services/data-provider.service' { * decorator. */ const decorators: { - /** JSDOC DESTINATION DataProviderServiceDecoratorsIgnore */ + /** + * + * Decorator function that marks a data provider engine `set___` or `get___` method to be ignored. + * papi will not layer over these methods or consider them to be data type methods + * + * @example Use this as a decorator on a class's method: + * + * ```typescript + * class MyDataProviderEngine { + * @papi.dataProviders.decorators.ignore + * async getInternal() {} + * } + * ``` + * + * WARNING: Do not copy and paste this example. The `@` symbol does not render correctly in JSDoc + * code blocks, so a different unicode character was used. Please use a normal `@` when using a + * decorator. + * + * OR + * + * @example Call this function signature on an object's method: + * + * ```typescript + * const myDataProviderEngine = { + * async getInternal() {}, + * }; + * papi.dataProviders.decorators.ignore(dataProviderEngine.getInternal); + * ``` + * + * @param method The method to ignore + */ ignore: typeof ignore; - /** JSDOC DESTINATION DataProviderServiceDecoratorsDoNotNotify */ + /** + * + * Decorator function that marks a data provider engine `set` method not to automatically + * emit an update and notify subscribers of a change to the data. papi will still consider the + * `set` method to be a data type method, but it will not layer over it to emit updates. + * + * @example Use this as a decorator on a class's method: + * + * ```typescript + * class MyDataProviderEngine { + * @papi.dataProviders.decorators.doNotNotify + * async setVerse() {} + * } + * ``` + * + * WARNING: Do not copy and paste this example. The `@` symbol does not render correctly in JSDoc + * code blocks, so a different unicode character was used. Please use a normal `@` when using a + * decorator. + * + * OR + * + * @example Call this function signature on an object's method: + * + * ```typescript + * const myDataProviderEngine = { + * async setVerse() {}, + * }; + * papi.dataProviders.decorators.ignore(dataProviderEngine.setVerse); + * ``` + * + * @param method The method not to layer over to send an automatic update + */ doNotNotify: typeof doNotNotify; }; /** - * JSDOC SOURCE DataProviderServiceRegisterEngine * * Creates a data provider to be shared on the network layering over the provided data provider * engine. @@ -3397,7 +3589,6 @@ declare module 'shared/services/data-provider.service' { | undefined, ): Promise>>; /** - * JSDOC SOURCE DataProviderServiceGet * * Get a data provider that has previously been set up * @@ -3423,19 +3614,70 @@ declare module 'shared/services/data-provider.service' { providerName: string, ): Promise; export interface DataProviderService { - /** JSDOC DESTINATION DataProviderServiceHasKnown */ + /** + * + * Indicate if we are aware of an existing data provider with the given name. If a data provider + * with the given name is somewhere else on the network, this function won't tell you about it + * unless something else in the existing process is subscribed to it. + */ hasKnown: typeof hasKnown; - /** JSDOC DESTINATION DataProviderServiceRegisterEngine */ + /** + * + * Creates a data provider to be shared on the network layering over the provided data provider + * engine. + * + * @param providerName Name this data provider should be called on the network + * @param dataProviderEngine The object to layer over with a new data provider object + * @param dataProviderType String to send in a network event to clarify what type of data provider + * is represented by this engine. For generic data providers, the default value of `dataProvider` + * can be used. For data provider types that have multiple instances (e.g., project data + * providers), a unique type name should be used to distinguish from generic data providers. + * @param dataProviderAttributes Optional object that will be sent in a network event to provide + * additional metadata about the data provider represented by this engine. + * + * WARNING: registering a dataProviderEngine mutates the provided object. Its `notifyUpdate` and + * `set` methods are layered over to facilitate data provider subscriptions. + * @returns The data provider including control over disposing of it. Note that this data provider + * is a new object distinct from the data provider engine passed in. + */ registerEngine: typeof registerEngine; - /** JSDOC DESTINATION DataProviderServiceGet */ + /** + * + * Get a data provider that has previously been set up + * + * @param providerName Name of the desired data provider + * @returns The data provider with the given name if one exists, undefined otherwise + */ get: typeof get; - /** JSDOC DESTINATION DataProviderServiceDecorators */ + /** + * + * A collection of decorators to be used with the data provider service + * + * @example To use the `ignore` a decorator on a class's method: + * + * ```typescript + * class MyDataProviderEngine { + * @papi.dataProviders.decorators.ignore + * async getInternal() {} + * } + * ``` + * + * WARNING: Do not copy and paste this example. The `@` symbol does not render correctly in JSDoc + * code blocks, so a different unicode character was used. Please use a normal `@` when using a + * decorator. + */ decorators: typeof decorators; - /** JSDOC DESTINATION DataProviderEngine */ + /** + * + * Abstract class that provides a placeholder `notifyUpdate` for data provider engine classes. If a + * data provider engine class extends this class, it doesn't have to specify its own `notifyUpdate` + * function in order to use `notifyUpdate`. + * + * @see {@link IDataProviderEngine} for more information on extending this class. + */ DataProviderEngine: typeof DataProviderEngine; } /** - * JSDOC SOURCE dataProviderService * * Service that allows extensions to send and receive data to/from other extensions */ @@ -3525,7 +3767,6 @@ declare module 'shared/models/project-data-provider-engine.model' { WithProjectDataProviderEngineSettingMethods & WithProjectDataProviderEngineExtensionDataMethods; /** - * JSDOC SOURCE ProjectDataProviderEngine * * Abstract class that provides default implementations of a number of {@link IProjectDataProvider} * functions including all the `Setting` and `ExtensionData`-related methods. Extensions can create @@ -3638,7 +3879,6 @@ declare module 'shared/models/project-metadata.model' { declare module 'shared/services/project-lookup.service-model' { import { ProjectMetadata } from 'shared/models/project-metadata.model'; /** - * JSDOC SOURCE projectLookupService * * Provides metadata for projects known by the platform */ @@ -3706,7 +3946,6 @@ declare module 'shared/services/project-data-provider.service' { get: typeof get; } /** - * JSDOC SOURCE papiBackendProjectDataProviderService * * Service that registers and gets project data providers */ @@ -3715,7 +3954,6 @@ declare module 'shared/services/project-data-provider.service' { get: typeof get; } /** - * JSDOC SOURCE papiFrontendProjectDataProviderService * * Service that gets project data providers */ @@ -4005,7 +4243,6 @@ declare module 'extension-host/services/extension-storage.service' { deleteUserData: typeof deleteUserData; } /** - * JSDOC SOURCE extensionStorageService * * This service provides extensions in the extension host the ability to read/write data based on * the extension identity and current user (as identified by the OS). This service will not work @@ -4195,7 +4432,6 @@ declare module 'shared/services/dialog.service-model' { import { DialogTabTypes, DialogTypes } from 'renderer/components/dialogs/dialog-definition.model'; import { DialogOptions } from 'shared/models/dialog-options.model'; /** - * JSDOC SOURCE dialogService * * Prompt the user for responses with dialogs */ @@ -4252,7 +4488,6 @@ declare module 'renderer/hooks/papi-hooks/use-dialog-callback.hook' { maximumOpenDialogs?: number; }; /** - * JSDOC SOURCE useDialogCallback * * Enables using `papi.dialogs.showDialog` in React more easily. Returns a callback to run that will * open a dialog with the provided `dialogType` and `options` then run the `resolveCallback` with @@ -4333,7 +4568,74 @@ declare module 'renderer/hooks/papi-hooks/use-dialog-callback.hook' { ) => void, rejectCallback: (error: unknown, dialogType: DialogTabType, options: DialogOptions) => void, ): (optionOverrides?: Partial) => Promise; - /** JSDOC DESTINATION useDialogCallback */ + /** + * + * Enables using `papi.dialogs.showDialog` in React more easily. Returns a callback to run that will + * open a dialog with the provided `dialogType` and `options` then run the `resolveCallback` with + * the dialog response or `rejectCallback` if there is an error. By default, only one dialog can be + * open at a time. + * + * If you need to open multiple dialogs and track which dialog is which, you can set + * `options.shouldOpenMultipleDialogs` to `true` and add a counter to the `options` when calling the + * callback. Then `resolveCallback` will be resolved with that options object including your + * counter. + * + * @type `DialogTabType` The dialog type you are using. Should be inferred by parameters + * @param dialogType Dialog type you want to show on the screen + * + * Note: this parameter is internally assigned to a `ref`, so changing it will not cause any hooks + * to re-run with its new value. This means that updating this parameter will not cause a new + * callback to be returned. However, because of the nature of calling dialogs, this has no adverse + * effect on the functionality of this hook. Calling the callback will always use the latest + * `dialogType`. + * @param options Various options for configuring the dialog that shows and this hook. If an + * `options` parameter is also provided to the returned `showDialog` callback, those + * callback-provided `options` merge over these hook-provided `options` + * + * Note: this parameter is internally assigned to a `ref`, so changing it will not cause any hooks + * to re-run with its new value. This means that updating this parameter will not cause a new + * callback to be returned. However, because of the nature of calling dialogs, this has no adverse + * effect on the functionality of this hook. Calling the callback will always use the latest + * `options`. + * @param resolveCallback `(response, dialogType, options)` The function that will be called if the + * dialog request resolves properly + * + * - `response` - the resolved value of the dialog call. Either the user's response or `undefined` if + * the user cancels + * - `dialogType` - the value of `dialogType` at the time that this dialog was called + * - `options` the `options` provided to the dialog at the time that this dialog was called. This + * consists of the `options` provided to the returned `showDialog` callback merged over the + * `options` provided to the hook and additionally contains {@link UseDialogCallbackOptions} + * properties + * + * Note: this parameter is internally assigned to a `ref`, so changing it will not cause any hooks + * to re-run with its new value. This means that updating this parameter will not cause a new + * callback to be returned. However, because of the nature of calling dialogs, this has no adverse + * effect on the functionality of this hook. When the dialog resolves, it will always call the + * latest `resolveCallback`. + * @param rejectCallback `(error, dialogType, options)` The function that will be called if the + * dialog request throws an error + * + * - `error` - the error thrown while calling the dialog + * - `dialogType` - the value of `dialogType` at the time that this dialog was called + * - `options` the `options` provided to the dialog at the time that this dialog was called. This + * consists of the `options` provided to the returned `showDialog` callback merged over the + * `options` provided to the hook and additionally contains {@link UseDialogCallbackOptions} + * properties + * + * Note: this parameter is internally assigned to a `ref`, so changing it will not cause any hooks + * to re-run with its new value. This means that updating this parameter will not cause a new + * callback to be returned. However, because of the nature of calling dialogs, this has no adverse + * effect on the functionality of this hook. If the dialog throws an error, it will always call + * the latest `rejectCallback`. + * @returns `showDialog(options?)` - callback to run to show the dialog to prompt the user for a + * response + * + * - `optionsOverrides?` - `options` object you may specify that will merge over the `options` you + * provide to the hook before passing to the dialog. All properties are optional, so you may + * specify as many or as few properties here as you want to overwrite the properties in the + * `options` you provide to the hook + */ function useDialogCallback< DialogTabType extends DialogTabTypes, DialogOptions extends DialogTypes[DialogTabType]['options'], @@ -4351,7 +4653,6 @@ declare module 'renderer/hooks/papi-hooks/use-dialog-callback.hook' { declare module 'shared/services/project-settings.service-model' { import { ProjectSettingNames, ProjectSettingTypes, ProjectTypes } from 'papi-shared-types'; /** - * JSDOC SOURCE projectSettingsService * * Provides utility functions that project storage interpreters should call when handling project * settings @@ -4412,7 +4713,7 @@ declare module 'shared/services/project-settings.service-model' { }; export const projectSettingsServiceNetworkObjectName = 'ProjectSettingsService'; } -declare module 'shared/services/papi-core.service' { +declare module '@papi/core' { /** Exporting empty object so people don't have to put 'type' in their import statements */ const core: {}; export default core; @@ -4459,12 +4760,15 @@ declare module 'shared/services/menu-data.service-model' { DataProviderSubscriberOptions, DataProviderUpdateInstructions, } from 'shared/models/data-provider.model'; - import { IDataProvider } from 'shared/services/papi-core.service'; - /** JSDOC DESTINATION menuDataServiceProviderName */ + import { IDataProvider } from '@papi/core'; + /** + * + * This name is used to register the menu data data provider on the papi. You can use this name to + * find the data provider when accessing it using the useData hook + */ export const menuDataServiceProviderName = 'platform.menuDataServiceDataProvider'; export const menuDataServiceObjectToProxy: Readonly<{ /** - * JSDOC SOURCE menuDataServiceProviderName * * This name is used to register the menu data data provider on the papi. You can use this name to * find the data provider when accessing it using the useData hook @@ -4481,13 +4785,11 @@ declare module 'shared/services/menu-data.service-model' { } } /** - * JSDOC SOURCE menuDataService * * Service that allows to get and store menu data */ export type IMenuDataService = { /** - * JSDOC SOURCE getMainMenu * * Get menu content for the main menu * @@ -4495,7 +4797,13 @@ declare module 'shared/services/menu-data.service-model' { * @returns MultiColumnMenu object of main menu content */ getMainMenu(mainMenuType: undefined): Promise; - /** JSDOC DESTINATION getMainMenu */ + /** + * + * Get menu content for the main menu + * + * @param mainMenuType Does not have to be defined + * @returns MultiColumnMenu object of main menu content + */ getMainMenu(): Promise; /** * This data cannot be changed. Trying to use this setter this will always throw @@ -4568,12 +4876,15 @@ declare module 'shared/services/settings.service-model' { DataProviderSubscriberOptions, DataProviderUpdateInstructions, IDataProvider, - } from 'shared/services/papi-core.service'; - /** JSDOC DESTINATION settingsServiceDataProviderName */ + } from '@papi/core'; + /** + * + * This name is used to register the settings service data provider on the papi. You can use this + * name to find the data provider when accessing it using the useData hook + */ export const settingsServiceDataProviderName = 'platform.settingsServiceDataProvider'; export const settingsServiceObjectToProxy: Readonly<{ /** - * JSDOC SOURCE settingsServiceDataProviderName * * This name is used to register the settings service data provider on the papi. You can use this * name to find the data provider when accessing it using the useData hook @@ -4606,7 +4917,7 @@ declare module 'shared/services/settings.service-model' { [settingsServiceDataProviderName]: ISettingsService; } } - /** JSDOC SOURCE settingsService */ + /** */ export type ISettingsService = { /** * Retrieves the value of the specified setting @@ -4665,7 +4976,7 @@ declare module 'shared/services/project-settings.service' { const projectSettingsService: IProjectSettingsService; export default projectSettingsService; } -declare module 'extension-host/services/papi-backend.service' { +declare module '@papi/backend' { /** * Unified module for accessing API features in the extension host. * @@ -4687,77 +4998,213 @@ declare module 'extension-host/services/papi-backend.service' { import { IProjectSettingsService } from 'shared/services/project-settings.service-model'; import { ProjectDataProviderEngine as PapiProjectDataProviderEngine } from 'shared/models/project-data-provider-engine.model'; const papi: { - /** JSDOC DESTINATION DataProviderEngine */ + /** + * + * Abstract class that provides a placeholder `notifyUpdate` for data provider engine classes. If a + * data provider engine class extends this class, it doesn't have to specify its own `notifyUpdate` + * function in order to use `notifyUpdate`. + * + * @see {@link IDataProviderEngine} for more information on extending this class. + */ DataProviderEngine: typeof PapiDataProviderEngine; - /** JSDOC DESTINATION ProjectDataProviderEngine */ + /** + * + * Abstract class that provides default implementations of a number of {@link IProjectDataProvider} + * functions including all the `Setting` and `ExtensionData`-related methods. Extensions can create + * their own Project Data Provider Engine classes and implement this class to meet the requirements + * of {@link MandatoryProjectDataTypes} automatically by passing these calls through to the Project + * Storage Interpreter. This class also subscribes to `Setting` and `ExtensionData` updates from the + * PSI to make sure it keeps its data up-to-date. + * + * This class also provides a placeholder `notifyUpdate` for Project Data Provider Engine classes. + * If a Project Data Provider Engine class extends this class, it doesn't have to specify its own + * `notifyUpdate` function in order to use `notifyUpdate`. + * + * @see {@link IProjectDataProviderEngine} for more information on extending this class. + */ ProjectDataProviderEngine: typeof PapiProjectDataProviderEngine; /** This is just an alias for internet.fetch */ fetch: typeof globalThis.fetch; - /** JSDOC DESTINATION commandService */ + /** + * + * The command service allows you to exchange messages with other components in the platform. You + * can register a command that other services and extensions can send you. You can send commands to + * other services and extensions that have registered commands. + */ commands: typeof commandService; - /** JSDOC DESTINATION papiWebViewService */ + /** + * + * Service exposing various functions related to using webViews + * + * WebViews are iframes in the Platform.Bible UI into which extensions load frontend code, either + * HTML or React components. + */ webViews: WebViewServiceType; - /** JSDOC DESTINATION papiWebViewProviderService */ + /** + * + * Interface for registering webView providers + */ webViewProviders: PapiWebViewProviderService; - /** JSDOC DESTINATION dialogService */ + /** + * + * Prompt the user for responses with dialogs + */ dialogs: DialogService; - /** JSDOC DESTINATION papiNetworkService */ + /** + * + * Service that provides a way to send and receive network events + */ network: PapiNetworkService; - /** JSDOC DESTINATION logger */ + /** + * + * All extensions and services should use this logger to provide a unified output of logs + */ logger: import('electron-log').MainLogger & { default: import('electron-log').MainLogger; }; - /** JSDOC DESTINATION internetService */ + /** + * + * Service that provides a way to call `fetch` since the original function is not available + */ internet: InternetService; - /** JSDOC DESTINATION dataProviderService */ + /** + * + * Service that allows extensions to send and receive data to/from other extensions + */ dataProviders: DataProviderService; - /** JSDOC DESTINATION papiBackendProjectDataProviderService */ + /** + * + * Service that registers and gets project data providers + */ projectDataProviders: PapiBackendProjectDataProviderService; - /** JSDOC DESTINATION projectLookupService */ + /** + * + * Provides metadata for projects known by the platform + */ projectLookup: ProjectLookupServiceType; - /** JSDOC DESTINATION projectSettingsService */ + /** + * + * Provides utility functions that project storage interpreters should call when handling project + * settings + */ projectSettings: IProjectSettingsService; - /** JSDOC DESTINATION extensionStorageService */ + /** + * + * This service provides extensions in the extension host the ability to read/write data based on + * the extension identity and current user (as identified by the OS). This service will not work + * within the renderer. + */ storage: ExtensionStorageService; - /** JSDOC DESTINATION settingsService */ + /** */ settings: ISettingsService; - /** JSDOC DESTINATION menuDataService */ + /** + * + * Service that allows to get and store menu data + */ menuData: IMenuDataService; }; export default papi; - /** JSDOC DESTINATION DataProviderEngine */ + /** + * + * Abstract class that provides a placeholder `notifyUpdate` for data provider engine classes. If a + * data provider engine class extends this class, it doesn't have to specify its own `notifyUpdate` + * function in order to use `notifyUpdate`. + * + * @see {@link IDataProviderEngine} for more information on extending this class. + */ export const DataProviderEngine: typeof PapiDataProviderEngine; - /** JSDOC DESTINATION ProjectDataProviderEngine */ + /** + * + * Abstract class that provides default implementations of a number of {@link IProjectDataProvider} + * functions including all the `Setting` and `ExtensionData`-related methods. Extensions can create + * their own Project Data Provider Engine classes and implement this class to meet the requirements + * of {@link MandatoryProjectDataTypes} automatically by passing these calls through to the Project + * Storage Interpreter. This class also subscribes to `Setting` and `ExtensionData` updates from the + * PSI to make sure it keeps its data up-to-date. + * + * This class also provides a placeholder `notifyUpdate` for Project Data Provider Engine classes. + * If a Project Data Provider Engine class extends this class, it doesn't have to specify its own + * `notifyUpdate` function in order to use `notifyUpdate`. + * + * @see {@link IProjectDataProviderEngine} for more information on extending this class. + */ export const ProjectDataProviderEngine: typeof PapiProjectDataProviderEngine; /** This is just an alias for internet.fetch */ export const fetch: typeof globalThis.fetch; - /** JSDOC DESTINATION commandService */ + /** + * + * The command service allows you to exchange messages with other components in the platform. You + * can register a command that other services and extensions can send you. You can send commands to + * other services and extensions that have registered commands. + */ export const commands: typeof commandService; - /** JSDOC DESTINATION papiWebViewService */ + /** + * + * Service exposing various functions related to using webViews + * + * WebViews are iframes in the Platform.Bible UI into which extensions load frontend code, either + * HTML or React components. + */ export const webViews: WebViewServiceType; - /** JSDOC DESTINATION papiWebViewProviderService */ + /** + * + * Interface for registering webView providers + */ export const webViewProviders: PapiWebViewProviderService; - /** JSDOC DESTINATION dialogService */ + /** + * + * Prompt the user for responses with dialogs + */ export const dialogs: DialogService; - /** JSDOC DESTINATION papiNetworkService */ + /** + * + * Service that provides a way to send and receive network events + */ export const network: PapiNetworkService; - /** JSDOC DESTINATION logger */ + /** + * + * All extensions and services should use this logger to provide a unified output of logs + */ export const logger: import('electron-log').MainLogger & { default: import('electron-log').MainLogger; }; - /** JSDOC DESTINATION internetService */ + /** + * + * Service that provides a way to call `fetch` since the original function is not available + */ export const internet: InternetService; - /** JSDOC DESTINATION dataProviderService */ + /** + * + * Service that allows extensions to send and receive data to/from other extensions + */ export const dataProviders: DataProviderService; - /** JSDOC DESTINATION papiBackendProjectDataProviderService */ + /** + * + * Service that registers and gets project data providers + */ export const projectDataProviders: PapiBackendProjectDataProviderService; - /** JSDOC DESTINATION projectLookupService */ + /** + * + * Provides metadata for projects known by the platform + */ export const projectLookup: ProjectLookupServiceType; - /** JSDOC DESTINATION projectSettingsService */ + /** + * + * Provides utility functions that project storage interpreters should call when handling project + * settings + */ export const projectSettings: IProjectSettingsService; - /** JSDOC DESTINATION extensionStorageService */ + /** + * + * This service provides extensions in the extension host the ability to read/write data based on + * the extension identity and current user (as identified by the OS). This service will not work + * within the renderer. + */ export const storage: ExtensionStorageService; - /** JSDOC DESTINATION menuDataService */ + /** + * + * Service that allows to get and store menu data + */ export const menuData: IMenuDataService; } declare module 'extension-host/extension-types/extension.interface' { @@ -4952,13 +5399,17 @@ declare module 'renderer/hooks/papi-hooks/use-data.hook' { dataProviderSource: DataProviderName | DataProviders[DataProviderName] | undefined, ): { [TDataType in keyof DataProviderTypes[DataProviderName]]: ( + // @ts-ignore TypeScript pretends it can't find `selector`, but it works just fine selector: DataProviderTypes[DataProviderName][TDataType]['selector'], + // @ts-ignore TypeScript pretends it can't find `getData`, but it works just fine defaultValue: DataProviderTypes[DataProviderName][TDataType]['getData'], subscriberOptions?: DataProviderSubscriberOptions, ) => [ + // @ts-ignore TypeScript pretends it can't find `getData`, but it works just fine DataProviderTypes[DataProviderName][TDataType]['getData'], ( | (( + // @ts-ignore TypeScript pretends it can't find `setData`, but it works just fine newData: DataProviderTypes[DataProviderName][TDataType]['setData'], ) => Promise>) | undefined @@ -5118,13 +5569,17 @@ declare module 'renderer/hooks/papi-hooks/use-project-data.hook' { projectDataProviderSource: string | ProjectDataProviders[ProjectType] | undefined, ): { [TDataType in keyof ProjectDataTypes[ProjectType]]: ( + // @ts-ignore TypeScript pretends it can't find `selector`, but it works just fine selector: ProjectDataTypes[ProjectType][TDataType]['selector'], + // @ts-ignore TypeScript pretends it can't find `getData`, but it works just fine defaultValue: ProjectDataTypes[ProjectType][TDataType]['getData'], subscriberOptions?: DataProviderSubscriberOptions, ) => [ + // @ts-ignore TypeScript pretends it can't find `getData`, but it works just fine ProjectDataTypes[ProjectType][TDataType]['getData'], ( | (( + // @ts-ignore TypeScript pretends it can't find `setData`, but it works just fine newData: ProjectDataTypes[ProjectType][TDataType]['setData'], ) => Promise>) | undefined @@ -5314,12 +5769,11 @@ declare module 'renderer/hooks/papi-hooks/index' { export { default as useDialogCallback } from 'renderer/hooks/papi-hooks/use-dialog-callback.hook'; export { default as useDataProviderMulti } from 'renderer/hooks/papi-hooks/use-data-provider-multi.hook'; } -declare module 'renderer/services/papi-frontend-react.service' { +declare module '@papi/frontend/react' { export * from 'renderer/hooks/papi-hooks/index'; } declare module 'renderer/services/renderer-xml-http-request.service' { - /** - * JSDOC SOURCE PapiRendererXMLHttpRequest This wraps the browser's XMLHttpRequest implementation to + /** This wraps the browser's XMLHttpRequest implementation to * provide better control over internet access. It is isomorphic with the standard XMLHttpRequest, * so it should act as a drop-in replacement. * @@ -5377,7 +5831,7 @@ declare module 'renderer/services/renderer-xml-http-request.service' { constructor(); } } -declare module 'renderer/services/papi-frontend.service' { +declare module '@papi/frontend' { /** * Unified module for accessing API features in the renderer. * @@ -5392,80 +5846,172 @@ declare module 'renderer/services/papi-frontend.service' { import { PapiFrontendProjectDataProviderService } from 'shared/services/project-data-provider.service'; import { ISettingsService } from 'shared/services/settings.service-model'; import { DialogService } from 'shared/services/dialog.service-model'; - import * as papiReact from 'renderer/services/papi-frontend-react.service'; + import * as papiReact from '@papi/frontend/react'; import PapiRendererWebSocket from 'renderer/services/renderer-web-socket.service'; import { IMenuDataService } from 'shared/services/menu-data.service-model'; import PapiRendererXMLHttpRequest from 'renderer/services/renderer-xml-http-request.service'; const papi: { /** This is just an alias for internet.fetch */ fetch: typeof globalThis.fetch; - /** JSDOC DESTINATION PapiRendererWebSocket */ + /** This wraps the browser's WebSocket implementation to provide + * better control over internet access. It is isomorphic with the standard WebSocket, so it should + * act as a drop-in replacement. + * + * Note that the Node WebSocket implementation is different and not wrapped here. + */ WebSocket: typeof PapiRendererWebSocket; - /** JSDOC DESTINATION PapiRendererXMLHttpRequest */ + /** This wraps the browser's XMLHttpRequest implementation to + * provide better control over internet access. It is isomorphic with the standard XMLHttpRequest, + * so it should act as a drop-in replacement. + * + * Note that Node doesn't have a native implementation, so this is only for the renderer. + */ XMLHttpRequest: typeof PapiRendererXMLHttpRequest; - /** JSDOC DESTINATION commandService */ + /** + * + * The command service allows you to exchange messages with other components in the platform. You + * can register a command that other services and extensions can send you. You can send commands to + * other services and extensions that have registered commands. + */ commands: typeof commandService; - /** JSDOC DESTINATION papiWebViewService */ + /** + * + * Service exposing various functions related to using webViews + * + * WebViews are iframes in the Platform.Bible UI into which extensions load frontend code, either + * HTML or React components. + */ webViews: WebViewServiceType; - /** JSDOC DESTINATION dialogService */ + /** + * + * Prompt the user for responses with dialogs + */ dialogs: DialogService; - /** JSDOC DESTINATION papiNetworkService */ + /** + * + * Service that provides a way to send and receive network events + */ network: PapiNetworkService; - /** JSDOC DESTINATION logger */ + /** + * + * All extensions and services should use this logger to provide a unified output of logs + */ logger: import('electron-log').MainLogger & { default: import('electron-log').MainLogger; }; - /** JSDOC DESTINATION internetService */ + /** + * + * Service that provides a way to call `fetch` since the original function is not available + */ internet: InternetService; - /** JSDOC DESTINATION dataProviderService */ + /** + * + * Service that allows extensions to send and receive data to/from other extensions + */ dataProviders: DataProviderService; - /** JSDOC DESTINATION papiFrontendProjectDataProviderService */ + /** + * + * Service that gets project data providers + */ projectDataProviders: PapiFrontendProjectDataProviderService; - /** JSDOC DESTINATION projectLookupService */ + /** + * + * Provides metadata for projects known by the platform + */ projectLookup: ProjectLookupServiceType; /** - * JSDOC SOURCE papiReact * * React hooks that enable interacting with the `papi` in React components more easily. */ react: typeof papiReact; - /** JSDOC DESTINATION settingsService */ + /** */ settings: ISettingsService; - /** JSDOC DESTINATION menuDataService */ + /** + * + * Service that allows to get and store menu data + */ menuData: IMenuDataService; }; export default papi; /** This is just an alias for internet.fetch */ export const fetch: typeof globalThis.fetch; - /** JSDOC DESTINATION PapiRendererWebSocket */ + /** This wraps the browser's WebSocket implementation to provide + * better control over internet access. It is isomorphic with the standard WebSocket, so it should + * act as a drop-in replacement. + * + * Note that the Node WebSocket implementation is different and not wrapped here. + */ export const WebSocket: typeof PapiRendererWebSocket; - /** JSDOC DESTINATION PapiRendererXMLHttpRequest */ + /** This wraps the browser's XMLHttpRequest implementation to + * provide better control over internet access. It is isomorphic with the standard XMLHttpRequest, + * so it should act as a drop-in replacement. + * + * Note that Node doesn't have a native implementation, so this is only for the renderer. + */ export const XMLHttpRequest: typeof PapiRendererXMLHttpRequest; - /** JSDOC DESTINATION commandService */ + /** + * + * The command service allows you to exchange messages with other components in the platform. You + * can register a command that other services and extensions can send you. You can send commands to + * other services and extensions that have registered commands. + */ export const commands: typeof commandService; - /** JSDOC DESTINATION papiWebViewService */ + /** + * + * Service exposing various functions related to using webViews + * + * WebViews are iframes in the Platform.Bible UI into which extensions load frontend code, either + * HTML or React components. + */ export const webViews: WebViewServiceType; - /** JSDOC DESTINATION dialogService */ + /** + * + * Prompt the user for responses with dialogs + */ export const dialogs: DialogService; - /** JSDOC DESTINATION papiNetworkService */ + /** + * + * Service that provides a way to send and receive network events + */ export const network: PapiNetworkService; - /** JSDOC DESTINATION logger */ + /** + * + * All extensions and services should use this logger to provide a unified output of logs + */ export const logger: import('electron-log').MainLogger & { default: import('electron-log').MainLogger; }; - /** JSDOC DESTINATION internetService */ + /** + * + * Service that provides a way to call `fetch` since the original function is not available + */ export const internet: InternetService; - /** JSDOC DESTINATION dataProviderService */ + /** + * + * Service that allows extensions to send and receive data to/from other extensions + */ export const dataProviders: DataProviderService; - /** JSDOC DESTINATION papiBackendProjectDataProviderService */ + /** + * + * Service that registers and gets project data providers + */ export const projectDataProviders: PapiFrontendProjectDataProviderService; - /** JSDOC DESTINATION projectLookupService */ + /** + * + * Provides metadata for projects known by the platform + */ export const projectLookup: ProjectLookupServiceType; - /** JSDOC DESTINATION papiReact */ + /** + * + * React hooks that enable interacting with the `papi` in React components more easily. + */ export const react: typeof papiReact; - /** JSDOC DESTINATION settingsService */ + /** */ export const settings: ISettingsService; - /** JSDOC DESTINATION menuDataService */ + /** + * + * Service that allows to get and store menu data + */ export const menuData: IMenuDataService; export type Papi = typeof papi; } diff --git a/lib/platform-bible-utils/dist/index.cjs b/lib/platform-bible-utils/dist/index.cjs index 4a41f1a86f..768bbd121a 100644 --- a/lib/platform-bible-utils/dist/index.cjs +++ b/lib/platform-bible-utils/dist/index.cjs @@ -1,2 +1,2 @@ -"use strict";var fe=Object.defineProperty;var he=(t,e,r)=>e in t?fe(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var p=(t,e,r)=>(he(t,typeof e!="symbol"?e+"":e,r),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class pe{constructor(e,r=1e4){p(this,"variableName");p(this,"promiseToValue");p(this,"resolver");p(this,"rejecter");this.variableName=e,this.promiseToValue=new Promise((s,n)=>{this.resolver=s,this.rejecter=n}),r>0&&setTimeout(()=>{this.rejecter&&(this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`),this.complete())},r),Object.seal(this)}get promise(){return this.promiseToValue}get hasSettled(){return Object.isFrozen(this)}resolveToValue(e,r=!1){if(this.resolver)console.debug(`${this.variableName} is being resolved now`),this.resolver(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent resolution of ${this.variableName}`)}}rejectWithReason(e,r=!1){if(this.rejecter)console.debug(`${this.variableName} is being rejected now`),this.rejecter(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent rejection of ${this.variableName}`)}}complete(){this.resolver=void 0,this.rejecter=void 0,Object.freeze(this)}}function me(){return"00-0-4-1-000".replace(/[^-]/g,t=>((Math.random()+~~t)*65536>>t).toString(16).padStart(4,"0"))}function V(t){return typeof t=="string"||t instanceof String}function E(t){return JSON.parse(JSON.stringify(t))}function de(t,e=300){if(V(t))throw new Error("Tried to debounce a string! Could be XSS");let r;return(...s)=>{clearTimeout(r),r=setTimeout(()=>t(...s),e)}}function be(t,e,r){const s=new Map;return t.forEach(n=>{const o=e(n),a=s.get(o),i=r?r(n,o):n;a?a.push(i):s.set(o,[i])}),s}function Ne(t){return typeof t=="object"&&t!==null&&"message"in t&&typeof t.message=="string"}function ge(t){if(Ne(t))return t;try{return new Error(JSON.stringify(t))}catch{return new Error(String(t))}}function ve(t){return ge(t).message}function F(t){return new Promise(e=>setTimeout(e,t))}function ye(t,e){const r=F(e).then(()=>{});return Promise.any([r,t()])}function we(t,e="obj"){const r=new Set;Object.getOwnPropertyNames(t).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e} due to error: ${o}`)}});let s=Object.getPrototypeOf(t);for(;s&&Object.getPrototypeOf(s);)Object.getOwnPropertyNames(s).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e}'s prototype due to error: ${o}`)}}),s=Object.getPrototypeOf(s);return r}function Ee(t,e={}){return new Proxy(e,{get(r,s){return s in r?r[s]:async(...n)=>(await t())[s](...n)}})}class Oe{constructor(e,r){p(this,"baseDocument");p(this,"contributions",new Map);p(this,"latestOutput");p(this,"options");this.baseDocument=e,this.options=r,this.updateBaseDocument(e)}updateBaseDocument(e){return this.validateStartingDocument(e),this.baseDocument=this.options.copyDocuments?E(e):e,this.rebuild()}addOrUpdateContribution(e,r){this.validateContribution(e,r);const s=this.contributions.get(e),n=this.options.copyDocuments&&r?E(r):r;this.contributions.set(e,n);try{return this.rebuild()}catch(o){throw s?this.contributions.set(e,s):this.contributions.delete(e),new Error(`Error when setting the document named ${e}: ${o}`)}}deleteContribution(e){const r=this.contributions.get(e);if(!r)throw new Error("{documentKey} does not exist");this.contributions.delete(e);try{return this.rebuild()}catch(s){throw this.contributions.set(e,r),new Error(`Error when deleting the document named ${e}: ${s}`)}}rebuild(){if(this.contributions.size===0){let r=E(this.baseDocument);return r=this.transformFinalOutput(r),this.validateOutput(r),this.latestOutput=r,this.latestOutput}let e=this.baseDocument;return this.contributions.forEach(r=>{e=H(e,r,this.options.ignoreDuplicateProperties),this.validateOutput(e)}),e=this.transformFinalOutput(e),this.validateOutput(e),this.latestOutput=e,this.latestOutput}}function $e(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||Array.isArray(r))&&(e=!1)}),e}function Ae(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||!Array.isArray(r))&&(e=!1)}),e}function H(t,e,r){const s=E(t);return e&&Object.keys(e).forEach(n=>{if(Object.hasOwn(t,n)){if($e(t[n],e[n]))s[n]=H(t[n],e[n],r);else if(Ae(t[n],e[n]))s[n]=s[n].concat(e[n]);else if(!r)throw new Error(`Cannot merge objects: key "${n}" already exists in the target object`)}else s[n]=e[n]}),s}class qe{constructor(e="Anonymous"){p(this,"unsubscribers",new Set);this.name=e}add(...e){e.forEach(r=>{"dispose"in r?this.unsubscribers.add(r.dispose):this.unsubscribers.add(r)})}async runAllUnsubscribers(){const e=[...this.unsubscribers].map(s=>s()),r=await Promise.all(e);return this.unsubscribers.clear(),r.every((s,n)=>(s||console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${n} failed!`),s))}}class Se{constructor(){p(this,"subscribe",this.event);p(this,"subscriptions");p(this,"lazyEvent");p(this,"isDisposed",!1);p(this,"dispose",()=>this.disposeFn());p(this,"emit",e=>{this.emitFn(e)})}get event(){return this.assertNotDisposed(),this.lazyEvent||(this.lazyEvent=e=>{if(!e||typeof e!="function")throw new Error("Event handler callback must be a function!");return this.subscriptions||(this.subscriptions=[]),this.subscriptions.push(e),()=>{if(!this.subscriptions)return!1;const r=this.subscriptions.indexOf(e);return r<0?!1:(this.subscriptions.splice(r,1),!0)}}),this.lazyEvent}emitFn(e){var r;this.assertNotDisposed(),(r=this.subscriptions)==null||r.forEach(s=>s(e))}assertNotDisposed(){if(this.isDisposed)throw new Error("Emitter is disposed")}disposeFn(){return this.assertNotDisposed(),this.isDisposed=!0,this.subscriptions=void 0,this.lazyEvent=void 0,Promise.resolve(!0)}}const k=[{shortName:"ERR",fullNames:["ERROR"],chapters:-1},{shortName:"GEN",fullNames:["Genesis"],chapters:50},{shortName:"EXO",fullNames:["Exodus"],chapters:40},{shortName:"LEV",fullNames:["Leviticus"],chapters:27},{shortName:"NUM",fullNames:["Numbers"],chapters:36},{shortName:"DEU",fullNames:["Deuteronomy"],chapters:34},{shortName:"JOS",fullNames:["Joshua"],chapters:24},{shortName:"JDG",fullNames:["Judges"],chapters:21},{shortName:"RUT",fullNames:["Ruth"],chapters:4},{shortName:"1SA",fullNames:["1 Samuel"],chapters:31},{shortName:"2SA",fullNames:["2 Samuel"],chapters:24},{shortName:"1KI",fullNames:["1 Kings"],chapters:22},{shortName:"2KI",fullNames:["2 Kings"],chapters:25},{shortName:"1CH",fullNames:["1 Chronicles"],chapters:29},{shortName:"2CH",fullNames:["2 Chronicles"],chapters:36},{shortName:"EZR",fullNames:["Ezra"],chapters:10},{shortName:"NEH",fullNames:["Nehemiah"],chapters:13},{shortName:"EST",fullNames:["Esther"],chapters:10},{shortName:"JOB",fullNames:["Job"],chapters:42},{shortName:"PSA",fullNames:["Psalm","Psalms"],chapters:150},{shortName:"PRO",fullNames:["Proverbs"],chapters:31},{shortName:"ECC",fullNames:["Ecclesiastes"],chapters:12},{shortName:"SNG",fullNames:["Song of Solomon","Song of Songs"],chapters:8},{shortName:"ISA",fullNames:["Isaiah"],chapters:66},{shortName:"JER",fullNames:["Jeremiah"],chapters:52},{shortName:"LAM",fullNames:["Lamentations"],chapters:5},{shortName:"EZK",fullNames:["Ezekiel"],chapters:48},{shortName:"DAN",fullNames:["Daniel"],chapters:12},{shortName:"HOS",fullNames:["Hosea"],chapters:14},{shortName:"JOL",fullNames:["Joel"],chapters:3},{shortName:"AMO",fullNames:["Amos"],chapters:9},{shortName:"OBA",fullNames:["Obadiah"],chapters:1},{shortName:"JON",fullNames:["Jonah"],chapters:4},{shortName:"MIC",fullNames:["Micah"],chapters:7},{shortName:"NAM",fullNames:["Nahum"],chapters:3},{shortName:"HAB",fullNames:["Habakkuk"],chapters:3},{shortName:"ZEP",fullNames:["Zephaniah"],chapters:3},{shortName:"HAG",fullNames:["Haggai"],chapters:2},{shortName:"ZEC",fullNames:["Zechariah"],chapters:14},{shortName:"MAL",fullNames:["Malachi"],chapters:4},{shortName:"MAT",fullNames:["Matthew"],chapters:28},{shortName:"MRK",fullNames:["Mark"],chapters:16},{shortName:"LUK",fullNames:["Luke"],chapters:24},{shortName:"JHN",fullNames:["John"],chapters:21},{shortName:"ACT",fullNames:["Acts"],chapters:28},{shortName:"ROM",fullNames:["Romans"],chapters:16},{shortName:"1CO",fullNames:["1 Corinthians"],chapters:16},{shortName:"2CO",fullNames:["2 Corinthians"],chapters:13},{shortName:"GAL",fullNames:["Galatians"],chapters:6},{shortName:"EPH",fullNames:["Ephesians"],chapters:6},{shortName:"PHP",fullNames:["Philippians"],chapters:4},{shortName:"COL",fullNames:["Colossians"],chapters:4},{shortName:"1TH",fullNames:["1 Thessalonians"],chapters:5},{shortName:"2TH",fullNames:["2 Thessalonians"],chapters:3},{shortName:"1TI",fullNames:["1 Timothy"],chapters:6},{shortName:"2TI",fullNames:["2 Timothy"],chapters:4},{shortName:"TIT",fullNames:["Titus"],chapters:3},{shortName:"PHM",fullNames:["Philemon"],chapters:1},{shortName:"HEB",fullNames:["Hebrews"],chapters:13},{shortName:"JAS",fullNames:["James"],chapters:5},{shortName:"1PE",fullNames:["1 Peter"],chapters:5},{shortName:"2PE",fullNames:["2 Peter"],chapters:3},{shortName:"1JN",fullNames:["1 John"],chapters:5},{shortName:"2JN",fullNames:["2 John"],chapters:1},{shortName:"3JN",fullNames:["3 John"],chapters:1},{shortName:"JUD",fullNames:["Jude"],chapters:1},{shortName:"REV",fullNames:["Revelation"],chapters:22}],K=1,W=k.length-1,L=1,Z=1,X=t=>{var e;return((e=k[t])==null?void 0:e.chapters)??-1},je=(t,e)=>({bookNum:Math.max(K,Math.min(t.bookNum+e,W)),chapterNum:1,verseNum:1}),Ce=(t,e)=>({...t,chapterNum:Math.min(Math.max(L,t.chapterNum+e),X(t.bookNum)),verseNum:1}),Me=(t,e)=>({...t,verseNum:Math.max(Z,t.verseNum+e)}),Pe=t=>(...e)=>t.map(s=>s(...e)).every(s=>s),Te=t=>async(...e)=>{const r=t.map(async s=>s(...e));return(await Promise.all(r)).every(s=>s)};var R=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},g={},Re=()=>{const t="\\ud800-\\udfff",e="\\u0300-\\u036f",r="\\ufe20-\\ufe2f",s="\\u20d0-\\u20ff",n="\\u1ab0-\\u1aff",o="\\u1dc0-\\u1dff",a=e+r+s+n+o,i="\\ufe0e\\ufe0f",c="\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93",h=`[${t}]`,u=`[${a}]`,l="\\ud83c[\\udffb-\\udfff]",f=`(?:${u}|${l})`,b=`[^${t}]`,m="(?:\\uD83C[\\uDDE6-\\uDDFF]){2}",y="[\\ud800-\\udbff][\\udc00-\\udfff]",q="\\u200d",ae="(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)",ie=`[${c}]`,P=`${f}?`,T=`[${i}]?`,ue=`(?:${q}(?:${[b,m,y].join("|")})${T+P})*`,le=T+P+ue,ce=`(?:${[`${b}${u}?`,u,m,y,h,ie].join("|")})`;return new RegExp(`${ae}|${l}(?=${l})|${ce+le}`,"g")},De=R&&R.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(g,"__esModule",{value:!0});var $=De(Re);function S(t){if(typeof t!="string")throw new Error("A string is expected as input");return t.match($.default())||[]}var Ie=g.toArray=S;function C(t){if(typeof t!="string")throw new Error("Input must be a string");var e=t.match($.default());return e===null?0:e.length}var _e=g.length=C;function Q(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");(typeof e!="number"||e<0)&&(e=0),typeof r=="number"&&r<0&&(r=0);var s=t.match($.default());return s?s.slice(e,r).join(""):""}var ze=g.substring=Q;function Be(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");var s=C(t);if(typeof e!="number"&&(e=parseInt(e,10)),e>=s)return"";e<0&&(e+=s);var n;typeof r>"u"?n=s:(typeof r!="number"&&(r=parseInt(r,10)),n=r>=0?r+e:e);var o=t.match($.default());return o?o.slice(e,n).join(""):""}var Je=g.substr=Be;function xe(t,e,r,s){if(e===void 0&&(e=16),r===void 0&&(r="#"),s===void 0&&(s="right"),typeof t!="string"||typeof e!="number")throw new Error("Invalid arguments specified");if(["left","right"].indexOf(s)===-1)throw new Error("Pad position should be either left or right");typeof r!="string"&&(r=String(r));var n=C(t);if(n>e)return Q(t,0,e);if(n=s.length)return e===""?s.length:-1;if(e==="")return r;var n=S(e),o=!1,a;for(a=r;ad(t)||e<-d(t)))return A(t,e,1)}function Fe(t,e){return e<0||e>d(t)-1?"":A(t,e,1)}function He(t,e){if(!(e<0||e>d(t)-1))return A(t,e,1).codePointAt(0)}function ke(t,e,r=d(t)){const s=te(t,e);return!(s===-1||s+d(e)!==r)}function Ke(t,e,r=0){const s=M(t,r);return ee(s,e)!==-1}function ee(t,e,r=0){return Ue(t,e,r)}function te(t,e,r=1/0){let s=r;s<0?s=0:s>=d(t)&&(s=d(t)-1);for(let n=s;n>=0;n--)if(A(t,n,d(e))===e)return n;return-1}function d(t){return _e(t)}function We(t,e){const r=e.toUpperCase();return r==="NONE"?t:t.normalize(r)}function Le(t,e,r=" "){return e<=d(t)?t:Y(t,e,r,"right")}function Ze(t,e,r=" "){return e<=d(t)?t:Y(t,e,r,"left")}function D(t,e){return e>t?t:e<-t?0:e<0?e+t:e}function Xe(t,e,r){const s=d(t);if(e>s||r&&(e>r&&!(e>0&&e-s)||r<-s||e<0&&e>-s&&r>0))return"";const n=D(s,e),o=r?D(s,r):void 0;return M(t,n,o)}function A(t,e=0,r=d(t)-e){return Je(t,e,r)}function M(t,e,r=d(t)){return ze(t,e,r)}function Qe(t){return Ie(t)}var Ye=Object.getOwnPropertyNames,et=Object.getOwnPropertySymbols,tt=Object.prototype.hasOwnProperty;function I(t,e){return function(s,n,o){return t(s,n,o)&&e(s,n,o)}}function O(t){return function(r,s,n){if(!r||!s||typeof r!="object"||typeof s!="object")return t(r,s,n);var o=n.cache,a=o.get(r),i=o.get(s);if(a&&i)return a===s&&i===r;o.set(r,s),o.set(s,r);var c=t(r,s,n);return o.delete(r),o.delete(s),c}}function _(t){return Ye(t).concat(et(t))}var re=Object.hasOwn||function(t,e){return tt.call(t,e)};function v(t,e){return t||e?t===e:t===e||t!==t&&e!==e}var se="_owner",z=Object.getOwnPropertyDescriptor,B=Object.keys;function rt(t,e,r){var s=t.length;if(e.length!==s)return!1;for(;s-- >0;)if(!r.equals(t[s],e[s],s,s,t,e,r))return!1;return!0}function st(t,e){return v(t.getTime(),e.getTime())}function J(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.entries(),o=0,a,i;(a=n.next())&&!a.done;){for(var c=e.entries(),h=!1,u=0;(i=c.next())&&!i.done;){var l=a.value,f=l[0],b=l[1],m=i.value,y=m[0],q=m[1];!h&&!s[u]&&(h=r.equals(f,y,o,u,t,e,r)&&r.equals(b,q,f,y,t,e,r))&&(s[u]=!0),u++}if(!h)return!1;o++}return!0}function nt(t,e,r){var s=B(t),n=s.length;if(B(e).length!==n)return!1;for(var o;n-- >0;)if(o=s[n],o===se&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!re(e,o)||!r.equals(t[o],e[o],o,o,t,e,r))return!1;return!0}function w(t,e,r){var s=_(t),n=s.length;if(_(e).length!==n)return!1;for(var o,a,i;n-- >0;)if(o=s[n],o===se&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!re(e,o)||!r.equals(t[o],e[o],o,o,t,e,r)||(a=z(t,o),i=z(e,o),(a||i)&&(!a||!i||a.configurable!==i.configurable||a.enumerable!==i.enumerable||a.writable!==i.writable)))return!1;return!0}function ot(t,e){return v(t.valueOf(),e.valueOf())}function at(t,e){return t.source===e.source&&t.flags===e.flags}function x(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.values(),o,a;(o=n.next())&&!o.done;){for(var i=e.values(),c=!1,h=0;(a=i.next())&&!a.done;)!c&&!s[h]&&(c=r.equals(o.value,a.value,o.value,a.value,t,e,r))&&(s[h]=!0),h++;if(!c)return!1}return!0}function it(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}var ut="[object Arguments]",lt="[object Boolean]",ct="[object Date]",ft="[object Map]",ht="[object Number]",pt="[object Object]",mt="[object RegExp]",dt="[object Set]",bt="[object String]",Nt=Array.isArray,G=typeof ArrayBuffer=="function"&&ArrayBuffer.isView?ArrayBuffer.isView:null,U=Object.assign,gt=Object.prototype.toString.call.bind(Object.prototype.toString);function vt(t){var e=t.areArraysEqual,r=t.areDatesEqual,s=t.areMapsEqual,n=t.areObjectsEqual,o=t.arePrimitiveWrappersEqual,a=t.areRegExpsEqual,i=t.areSetsEqual,c=t.areTypedArraysEqual;return function(u,l,f){if(u===l)return!0;if(u==null||l==null||typeof u!="object"||typeof l!="object")return u!==u&&l!==l;var b=u.constructor;if(b!==l.constructor)return!1;if(b===Object)return n(u,l,f);if(Nt(u))return e(u,l,f);if(G!=null&&G(u))return c(u,l,f);if(b===Date)return r(u,l,f);if(b===RegExp)return a(u,l,f);if(b===Map)return s(u,l,f);if(b===Set)return i(u,l,f);var m=gt(u);return m===ct?r(u,l,f):m===mt?a(u,l,f):m===ft?s(u,l,f):m===dt?i(u,l,f):m===pt?typeof u.then!="function"&&typeof l.then!="function"&&n(u,l,f):m===ut?n(u,l,f):m===lt||m===ht||m===bt?o(u,l,f):!1}}function yt(t){var e=t.circular,r=t.createCustomConfig,s=t.strict,n={areArraysEqual:s?w:rt,areDatesEqual:st,areMapsEqual:s?I(J,w):J,areObjectsEqual:s?w:nt,arePrimitiveWrappersEqual:ot,areRegExpsEqual:at,areSetsEqual:s?I(x,w):x,areTypedArraysEqual:s?w:it};if(r&&(n=U({},n,r(n))),e){var o=O(n.areArraysEqual),a=O(n.areMapsEqual),i=O(n.areObjectsEqual),c=O(n.areSetsEqual);n=U({},n,{areArraysEqual:o,areMapsEqual:a,areObjectsEqual:i,areSetsEqual:c})}return n}function wt(t){return function(e,r,s,n,o,a,i){return t(e,r,i)}}function Et(t){var e=t.circular,r=t.comparator,s=t.createState,n=t.equals,o=t.strict;if(s)return function(c,h){var u=s(),l=u.cache,f=l===void 0?e?new WeakMap:void 0:l,b=u.meta;return r(c,h,{cache:f,equals:n,meta:b,strict:o})};if(e)return function(c,h){return r(c,h,{cache:new WeakMap,equals:n,meta:void 0,strict:o})};var a={cache:void 0,equals:n,meta:void 0,strict:o};return function(c,h){return r(c,h,a)}}var Ot=N();N({strict:!0});N({circular:!0});N({circular:!0,strict:!0});N({createInternalComparator:function(){return v}});N({strict:!0,createInternalComparator:function(){return v}});N({circular:!0,createInternalComparator:function(){return v}});N({circular:!0,createInternalComparator:function(){return v},strict:!0});function N(t){t===void 0&&(t={});var e=t.circular,r=e===void 0?!1:e,s=t.createInternalComparator,n=t.createState,o=t.strict,a=o===void 0?!1:o,i=yt(t),c=vt(i),h=s?s(c):wt(c);return Et({circular:r,comparator:c,createState:n,equals:h,strict:a})}function $t(t,e){return Ot(t,e)}function j(t,e,r){return JSON.stringify(t,(n,o)=>{let a=o;return e&&(a=e(n,a)),a===void 0&&(a=null),a},r)}function ne(t,e){function r(n){return Object.keys(n).forEach(o=>{n[o]===null?n[o]=void 0:typeof n[o]=="object"&&(n[o]=r(n[o]))}),n}const s=JSON.parse(t,e);if(s!==null)return typeof s=="object"?r(s):s}function At(t){try{const e=j(t);return e===j(ne(e))}catch{return!1}}const qt=t=>t.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/"),oe={title:"Platform.Bible menus",type:"object",properties:{mainMenu:{description:"Top level menu for the application",$ref:"#/$defs/multiColumnMenu"},defaultWebViewTopMenu:{description:"Default top menu for web views that don't specify their own",$ref:"#/$defs/multiColumnMenu"},defaultWebViewContextMenu:{description:"Default context menu for web views that don't specify their own",$ref:"#/$defs/singleColumnMenu"},webViewMenus:{description:"Menus that apply per web view in the application",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{$ref:"#/$defs/menusForOneWebView"}},additionalProperties:!1}},required:["mainMenu","defaultWebViewTopMenu","defaultWebViewContextMenu","webViewMenus"],additionalProperties:!1,$defs:{localizeKey:{description:"Identifier for a string that will be localized in a menu based on the user's UI language",type:"string",pattern:"^%[\\w\\-\\.]+%$"},referencedItem:{description:"Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)",type:"string",pattern:"^[\\w\\-]+\\.[\\w\\-]+$"},columnsWithHeaders:{description:"Group of columns that can be combined with other columns to form a multi-column menu",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single column with a header string",type:"object",properties:{label:{description:"Header text for this this column in the UI",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},order:{description:"Relative order of this column compared to other columns (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu groups to this column",type:"boolean"}},required:["label","order"],additionalProperties:!1}},properties:{isExtensible:{description:"Defines whether contributions are allowed to add columns to this multi-column menu",type:"boolean"}}},menuGroups:{description:"Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single group that contains menu items",type:"object",oneOf:[{properties:{column:{description:"Column where this group belongs, not required for single column menus",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["order"],additionalProperties:!1},{properties:{menuItem:{description:"Menu item that anchors the submenu where this group belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["menuItem","order"],additionalProperties:!1}]}},additionalProperties:!1},menuItem:{description:"Single item in a menu that can be clicked on to take an action or can be the parent of a submenu",type:"object",oneOf:[{properties:{id:{description:"ID for this menu item that holds a submenu",$ref:"#/$defs/referencedItem"}},required:["id"]},{properties:{command:{description:"Name of the PAPI command to run when this menu item is selected.",$ref:"#/$defs/referencedItem"},iconPathBefore:{description:"Path to the icon to display before the menu text",type:"string"},iconPathAfter:{description:"Path to the icon to display after the menu text",type:"string"}},required:["command"]}],properties:{label:{description:"Key that represents the text of this menu item to display",$ref:"#/$defs/localizeKey"},tooltip:{description:"Key that represents the text to display if a mouse pointer hovers over the menu item",$ref:"#/$defs/localizeKey"},searchTerms:{description:"Key that represents additional words the platform should reference when users are searching for menu items",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},group:{description:"Group to which this menu item belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this menu item compared to other menu items in the same group (sorted ascending)",type:"number"}},required:["label","group","order"],unevaluatedProperties:!1},groupsAndItems:{description:"Core schema for a column",type:"object",properties:{groups:{description:"Groups that belong in this menu",$ref:"#/$defs/menuGroups"},items:{description:"List of menu items that belong in this menu",type:"array",items:{$ref:"#/$defs/menuItem"},uniqueItems:!0}},required:["groups","items"]},singleColumnMenu:{description:"Menu that contains a column without a header",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"}],unevaluatedProperties:!1},multiColumnMenu:{description:"Menu that can contain multiple columns with headers",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"},{properties:{columns:{description:"Columns that belong in this menu",$ref:"#/$defs/columnsWithHeaders"}},required:["columns"]}],unevaluatedProperties:!1},menusForOneWebView:{description:"Set of menus that are associated with a single tab",type:"object",properties:{includeDefaults:{description:"Indicates whether the platform default menus should be included for this webview",type:"boolean"},topMenu:{description:"Menu that opens when you click on the top left corner of a tab",$ref:"#/$defs/multiColumnMenu"},contextMenu:{description:"Menu that opens when you right click on the main body/area of a tab",$ref:"#/$defs/singleColumnMenu"}},additionalProperties:!1}}};Object.freeze(oe);exports.AsyncVariable=pe;exports.DocumentCombinerEngine=Oe;exports.FIRST_SCR_BOOK_NUM=K;exports.FIRST_SCR_CHAPTER_NUM=L;exports.FIRST_SCR_VERSE_NUM=Z;exports.LAST_SCR_BOOK_NUM=W;exports.PlatformEventEmitter=Se;exports.UnsubscriberAsyncList=qe;exports.aggregateUnsubscriberAsyncs=Te;exports.aggregateUnsubscribers=Pe;exports.at=Ve;exports.charAt=Fe;exports.codePointAt=He;exports.createSyncProxyForAsyncObject=Ee;exports.debounce=de;exports.deepClone=E;exports.deepEqual=$t;exports.deserialize=ne;exports.endsWith=ke;exports.getAllObjectFunctionNames=we;exports.getChaptersForBook=X;exports.getErrorMessage=ve;exports.groupBy=be;exports.htmlEncode=qt;exports.includes=Ke;exports.indexOf=ee;exports.isSerializable=At;exports.isString=V;exports.lastIndexOf=te;exports.length=d;exports.menuDocumentSchema=oe;exports.newGuid=me;exports.normalize=We;exports.offsetBook=je;exports.offsetChapter=Ce;exports.offsetVerse=Me;exports.padEnd=Le;exports.padStart=Ze;exports.serialize=j;exports.slice=Xe;exports.substring=M;exports.toArray=Qe;exports.wait=F;exports.waitForDuration=ye; +"use strict";var he=Object.defineProperty;var pe=(t,e,r)=>e in t?he(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var p=(t,e,r)=>(pe(t,typeof e!="symbol"?e+"":e,r),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class me{constructor(e,r=1e4){p(this,"variableName");p(this,"promiseToValue");p(this,"resolver");p(this,"rejecter");this.variableName=e,this.promiseToValue=new Promise((s,n)=>{this.resolver=s,this.rejecter=n}),r>0&&setTimeout(()=>{this.rejecter&&(this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`),this.complete())},r),Object.seal(this)}get promise(){return this.promiseToValue}get hasSettled(){return Object.isFrozen(this)}resolveToValue(e,r=!1){if(this.resolver)console.debug(`${this.variableName} is being resolved now`),this.resolver(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent resolution of ${this.variableName}`)}}rejectWithReason(e,r=!1){if(this.rejecter)console.debug(`${this.variableName} is being rejected now`),this.rejecter(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent rejection of ${this.variableName}`)}}complete(){this.resolver=void 0,this.rejecter=void 0,Object.freeze(this)}}function de(){return"00-0-4-1-000".replace(/[^-]/g,t=>((Math.random()+~~t)*65536>>t).toString(16).padStart(4,"0"))}function F(t){return typeof t=="string"||t instanceof String}function E(t){return JSON.parse(JSON.stringify(t))}function be(t,e=300){if(F(t))throw new Error("Tried to debounce a string! Could be XSS");let r;return(...s)=>{clearTimeout(r),r=setTimeout(()=>t(...s),e)}}function ge(t,e,r){const s=new Map;return t.forEach(n=>{const o=e(n),a=s.get(o),i=r?r(n,o):n;a?a.push(i):s.set(o,[i])}),s}function Ne(t){return typeof t=="object"&&t!==null&&"message"in t&&typeof t.message=="string"}function ve(t){if(Ne(t))return t;try{return new Error(JSON.stringify(t))}catch{return new Error(String(t))}}function ye(t){return ve(t).message}function H(t){return new Promise(e=>setTimeout(e,t))}function we(t,e){const r=H(e).then(()=>{});return Promise.any([r,t()])}function Ee(t,e="obj"){const r=new Set;Object.getOwnPropertyNames(t).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e} due to error: ${o}`)}});let s=Object.getPrototypeOf(t);for(;s&&Object.getPrototypeOf(s);)Object.getOwnPropertyNames(s).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e}'s prototype due to error: ${o}`)}}),s=Object.getPrototypeOf(s);return r}function Oe(t,e={}){return new Proxy(e,{get(r,s){return s in r?r[s]:async(...n)=>(await t())[s](...n)}})}class $e{constructor(e,r){p(this,"baseDocument");p(this,"contributions",new Map);p(this,"latestOutput");p(this,"options");this.baseDocument=e,this.options=r,this.updateBaseDocument(e)}updateBaseDocument(e){return this.validateStartingDocument(e),this.baseDocument=this.options.copyDocuments?E(e):e,this.rebuild()}addOrUpdateContribution(e,r){this.validateContribution(e,r);const s=this.contributions.get(e),n=this.options.copyDocuments&&r?E(r):r;this.contributions.set(e,n);try{return this.rebuild()}catch(o){throw s?this.contributions.set(e,s):this.contributions.delete(e),new Error(`Error when setting the document named ${e}: ${o}`)}}deleteContribution(e){const r=this.contributions.get(e);if(!r)throw new Error("{documentKey} does not exist");this.contributions.delete(e);try{return this.rebuild()}catch(s){throw this.contributions.set(e,r),new Error(`Error when deleting the document named ${e}: ${s}`)}}rebuild(){if(this.contributions.size===0){let r=E(this.baseDocument);return r=this.transformFinalOutput(r),this.validateOutput(r),this.latestOutput=r,this.latestOutput}let e=this.baseDocument;return this.contributions.forEach(r=>{e=k(e,r,this.options.ignoreDuplicateProperties),this.validateOutput(e)}),e=this.transformFinalOutput(e),this.validateOutput(e),this.latestOutput=e,this.latestOutput}}function Ae(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||Array.isArray(r))&&(e=!1)}),e}function Se(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||!Array.isArray(r))&&(e=!1)}),e}function k(t,e,r){const s=E(t);return e&&Object.keys(e).forEach(n=>{if(Object.hasOwn(t,n)){if(Ae(t[n],e[n]))s[n]=k(t[n],e[n],r);else if(Se(t[n],e[n]))s[n]=s[n].concat(e[n]);else if(!r)throw new Error(`Cannot merge objects: key "${n}" already exists in the target object`)}else s[n]=e[n]}),s}class qe{constructor(e="Anonymous"){p(this,"unsubscribers",new Set);this.name=e}add(...e){e.forEach(r=>{"dispose"in r?this.unsubscribers.add(r.dispose):this.unsubscribers.add(r)})}async runAllUnsubscribers(){const e=[...this.unsubscribers].map(s=>s()),r=await Promise.all(e);return this.unsubscribers.clear(),r.every((s,n)=>(s||console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${n} failed!`),s))}}class je{constructor(){p(this,"subscribe",this.event);p(this,"subscriptions");p(this,"lazyEvent");p(this,"isDisposed",!1);p(this,"dispose",()=>this.disposeFn());p(this,"emit",e=>{this.emitFn(e)})}get event(){return this.assertNotDisposed(),this.lazyEvent||(this.lazyEvent=e=>{if(!e||typeof e!="function")throw new Error("Event handler callback must be a function!");return this.subscriptions||(this.subscriptions=[]),this.subscriptions.push(e),()=>{if(!this.subscriptions)return!1;const r=this.subscriptions.indexOf(e);return r<0?!1:(this.subscriptions.splice(r,1),!0)}}),this.lazyEvent}emitFn(e){var r;this.assertNotDisposed(),(r=this.subscriptions)==null||r.forEach(s=>s(e))}assertNotDisposed(){if(this.isDisposed)throw new Error("Emitter is disposed")}disposeFn(){return this.assertNotDisposed(),this.isDisposed=!0,this.subscriptions=void 0,this.lazyEvent=void 0,Promise.resolve(!0)}}const W=[{shortName:"ERR",fullNames:["ERROR"],chapters:-1},{shortName:"GEN",fullNames:["Genesis"],chapters:50},{shortName:"EXO",fullNames:["Exodus"],chapters:40},{shortName:"LEV",fullNames:["Leviticus"],chapters:27},{shortName:"NUM",fullNames:["Numbers"],chapters:36},{shortName:"DEU",fullNames:["Deuteronomy"],chapters:34},{shortName:"JOS",fullNames:["Joshua"],chapters:24},{shortName:"JDG",fullNames:["Judges"],chapters:21},{shortName:"RUT",fullNames:["Ruth"],chapters:4},{shortName:"1SA",fullNames:["1 Samuel"],chapters:31},{shortName:"2SA",fullNames:["2 Samuel"],chapters:24},{shortName:"1KI",fullNames:["1 Kings"],chapters:22},{shortName:"2KI",fullNames:["2 Kings"],chapters:25},{shortName:"1CH",fullNames:["1 Chronicles"],chapters:29},{shortName:"2CH",fullNames:["2 Chronicles"],chapters:36},{shortName:"EZR",fullNames:["Ezra"],chapters:10},{shortName:"NEH",fullNames:["Nehemiah"],chapters:13},{shortName:"EST",fullNames:["Esther"],chapters:10},{shortName:"JOB",fullNames:["Job"],chapters:42},{shortName:"PSA",fullNames:["Psalm","Psalms"],chapters:150},{shortName:"PRO",fullNames:["Proverbs"],chapters:31},{shortName:"ECC",fullNames:["Ecclesiastes"],chapters:12},{shortName:"SNG",fullNames:["Song of Solomon","Song of Songs"],chapters:8},{shortName:"ISA",fullNames:["Isaiah"],chapters:66},{shortName:"JER",fullNames:["Jeremiah"],chapters:52},{shortName:"LAM",fullNames:["Lamentations"],chapters:5},{shortName:"EZK",fullNames:["Ezekiel"],chapters:48},{shortName:"DAN",fullNames:["Daniel"],chapters:12},{shortName:"HOS",fullNames:["Hosea"],chapters:14},{shortName:"JOL",fullNames:["Joel"],chapters:3},{shortName:"AMO",fullNames:["Amos"],chapters:9},{shortName:"OBA",fullNames:["Obadiah"],chapters:1},{shortName:"JON",fullNames:["Jonah"],chapters:4},{shortName:"MIC",fullNames:["Micah"],chapters:7},{shortName:"NAM",fullNames:["Nahum"],chapters:3},{shortName:"HAB",fullNames:["Habakkuk"],chapters:3},{shortName:"ZEP",fullNames:["Zephaniah"],chapters:3},{shortName:"HAG",fullNames:["Haggai"],chapters:2},{shortName:"ZEC",fullNames:["Zechariah"],chapters:14},{shortName:"MAL",fullNames:["Malachi"],chapters:4},{shortName:"MAT",fullNames:["Matthew"],chapters:28},{shortName:"MRK",fullNames:["Mark"],chapters:16},{shortName:"LUK",fullNames:["Luke"],chapters:24},{shortName:"JHN",fullNames:["John"],chapters:21},{shortName:"ACT",fullNames:["Acts"],chapters:28},{shortName:"ROM",fullNames:["Romans"],chapters:16},{shortName:"1CO",fullNames:["1 Corinthians"],chapters:16},{shortName:"2CO",fullNames:["2 Corinthians"],chapters:13},{shortName:"GAL",fullNames:["Galatians"],chapters:6},{shortName:"EPH",fullNames:["Ephesians"],chapters:6},{shortName:"PHP",fullNames:["Philippians"],chapters:4},{shortName:"COL",fullNames:["Colossians"],chapters:4},{shortName:"1TH",fullNames:["1 Thessalonians"],chapters:5},{shortName:"2TH",fullNames:["2 Thessalonians"],chapters:3},{shortName:"1TI",fullNames:["1 Timothy"],chapters:6},{shortName:"2TI",fullNames:["2 Timothy"],chapters:4},{shortName:"TIT",fullNames:["Titus"],chapters:3},{shortName:"PHM",fullNames:["Philemon"],chapters:1},{shortName:"HEB",fullNames:["Hebrews"],chapters:13},{shortName:"JAS",fullNames:["James"],chapters:5},{shortName:"1PE",fullNames:["1 Peter"],chapters:5},{shortName:"2PE",fullNames:["2 Peter"],chapters:3},{shortName:"1JN",fullNames:["1 John"],chapters:5},{shortName:"2JN",fullNames:["2 John"],chapters:1},{shortName:"3JN",fullNames:["3 John"],chapters:1},{shortName:"JUD",fullNames:["Jude"],chapters:1},{shortName:"REV",fullNames:["Revelation"],chapters:22}],K=1,L=W.length-1,Z=1,X=1,Q=t=>{var e;return((e=W[t])==null?void 0:e.chapters)??-1},Ce=(t,e)=>({bookNum:Math.max(K,Math.min(t.bookNum+e,L)),chapterNum:1,verseNum:1}),Me=(t,e)=>({...t,chapterNum:Math.min(Math.max(Z,t.chapterNum+e),Q(t.bookNum)),verseNum:1}),Pe=(t,e)=>({...t,verseNum:Math.max(X,t.verseNum+e)}),Te=t=>(...e)=>t.map(s=>s(...e)).every(s=>s),Re=t=>async(...e)=>{const r=t.map(async s=>s(...e));return(await Promise.all(r)).every(s=>s)};var D=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},N={},De=()=>{const t="\\ud800-\\udfff",e="\\u0300-\\u036f",r="\\ufe20-\\ufe2f",s="\\u20d0-\\u20ff",n="\\u1ab0-\\u1aff",o="\\u1dc0-\\u1dff",a=e+r+s+n+o,i="\\ufe0e\\ufe0f",c="\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93",h=`[${t}]`,u=`[${a}]`,l="\\ud83c[\\udffb-\\udfff]",f=`(?:${u}|${l})`,b=`[^${t}]`,d="(?:\\uD83C[\\uDDE6-\\uDDFF]){2}",y="[\\ud800-\\udbff][\\udc00-\\udfff]",j="\\u200d",ie="(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)",ue=`[${c}]`,T=`${f}?`,R=`[${i}]?`,le=`(?:${j}(?:${[b,d,y].join("|")})${R+T})*`,ce=R+T+le,fe=`(?:${[`${b}${u}?`,u,d,y,h,ue].join("|")})`;return new RegExp(`${ie}|${l}(?=${l})|${fe+ce}`,"g")},Ie=D&&D.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(N,"__esModule",{value:!0});var A=Ie(De);function C(t){if(typeof t!="string")throw new Error("A string is expected as input");return t.match(A.default())||[]}var _e=N.toArray=C;function P(t){if(typeof t!="string")throw new Error("Input must be a string");var e=t.match(A.default());return e===null?0:e.length}var xe=N.length=P;function Y(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");(typeof e!="number"||e<0)&&(e=0),typeof r=="number"&&r<0&&(r=0);var s=t.match(A.default());return s?s.slice(e,r).join(""):""}var ze=N.substring=Y;function Be(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");var s=P(t);if(typeof e!="number"&&(e=parseInt(e,10)),e>=s)return"";e<0&&(e+=s);var n;typeof r>"u"?n=s:(typeof r!="number"&&(r=parseInt(r,10)),n=r>=0?r+e:e);var o=t.match(A.default());return o?o.slice(e,n).join(""):""}var Je=N.substr=Be;function Ge(t,e,r,s){if(e===void 0&&(e=16),r===void 0&&(r="#"),s===void 0&&(s="right"),typeof t!="string"||typeof e!="number")throw new Error("Invalid arguments specified");if(["left","right"].indexOf(s)===-1)throw new Error("Pad position should be either left or right");typeof r!="string"&&(r=String(r));var n=P(t);if(n>e)return Y(t,0,e);if(n=s.length)return e===""?s.length:-1;if(e==="")return r;var n=C(e),o=!1,a;for(a=r;am(t)||e<-m(t)))return q(t,e,1)}function He(t,e){return e<0||e>m(t)-1?"":q(t,e,1)}function ke(t,e){if(!(e<0||e>m(t)-1))return q(t,e,1).codePointAt(0)}function We(t,e,r=m(t)){const s=te(t,e);return!(s===-1||s+m(e)!==r)}function Ke(t,e,r=0){const s=O(t,r);return S(s,e)!==-1}function S(t,e,r=0){return Ve(t,e,r)}function te(t,e,r=1/0){let s=r;s<0?s=0:s>=m(t)&&(s=m(t)-1);for(let n=s;n>=0;n--)if(q(t,n,m(e))===e)return n;return-1}function m(t){return xe(t)}function Le(t,e){const r=e.toUpperCase();return r==="NONE"?t:t.normalize(r)}function Ze(t,e,r=" "){return e<=m(t)?t:ee(t,e,r,"right")}function Xe(t,e,r=" "){return e<=m(t)?t:ee(t,e,r,"left")}function I(t,e){return e>t?t:e<-t?0:e<0?e+t:e}function Qe(t,e,r){const s=m(t);if(e>s||r&&(e>r&&!(e>0&&e-s)||r<-s||e<0&&e>-s&&r>0))return"";const n=I(s,e),o=r?I(s,r):void 0;return O(t,n,o)}function Ye(t,e,r){const s=[];if(r!==void 0&&r<=0)return[t];if(e==="")return re(t).slice(0,r);let n=e;(typeof e=="string"||e instanceof RegExp&&!e.flags.includes("g"))&&(n=new RegExp(e,"g"));const o=t.match(n);let a=0;if(o){for(let i=0;i<(r?r-1:o.length);i++){const c=S(t,o[i],a),h=m(o[i]);if(s.push(O(t,a,c)),a=c+h,r!==void 0&&s.length===r)break}return s.push(O(t,a)),s}}function et(t,e,r=0){return S(t,e,r)===r}function q(t,e=0,r=m(t)-e){return Je(t,e,r)}function O(t,e,r=m(t)){return ze(t,e,r)}function re(t){return _e(t)}var tt=Object.getOwnPropertyNames,rt=Object.getOwnPropertySymbols,st=Object.prototype.hasOwnProperty;function _(t,e){return function(s,n,o){return t(s,n,o)&&e(s,n,o)}}function $(t){return function(r,s,n){if(!r||!s||typeof r!="object"||typeof s!="object")return t(r,s,n);var o=n.cache,a=o.get(r),i=o.get(s);if(a&&i)return a===s&&i===r;o.set(r,s),o.set(s,r);var c=t(r,s,n);return o.delete(r),o.delete(s),c}}function x(t){return tt(t).concat(rt(t))}var se=Object.hasOwn||function(t,e){return st.call(t,e)};function v(t,e){return t||e?t===e:t===e||t!==t&&e!==e}var ne="_owner",z=Object.getOwnPropertyDescriptor,B=Object.keys;function nt(t,e,r){var s=t.length;if(e.length!==s)return!1;for(;s-- >0;)if(!r.equals(t[s],e[s],s,s,t,e,r))return!1;return!0}function ot(t,e){return v(t.getTime(),e.getTime())}function J(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.entries(),o=0,a,i;(a=n.next())&&!a.done;){for(var c=e.entries(),h=!1,u=0;(i=c.next())&&!i.done;){var l=a.value,f=l[0],b=l[1],d=i.value,y=d[0],j=d[1];!h&&!s[u]&&(h=r.equals(f,y,o,u,t,e,r)&&r.equals(b,j,f,y,t,e,r))&&(s[u]=!0),u++}if(!h)return!1;o++}return!0}function at(t,e,r){var s=B(t),n=s.length;if(B(e).length!==n)return!1;for(var o;n-- >0;)if(o=s[n],o===ne&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!se(e,o)||!r.equals(t[o],e[o],o,o,t,e,r))return!1;return!0}function w(t,e,r){var s=x(t),n=s.length;if(x(e).length!==n)return!1;for(var o,a,i;n-- >0;)if(o=s[n],o===ne&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!se(e,o)||!r.equals(t[o],e[o],o,o,t,e,r)||(a=z(t,o),i=z(e,o),(a||i)&&(!a||!i||a.configurable!==i.configurable||a.enumerable!==i.enumerable||a.writable!==i.writable)))return!1;return!0}function it(t,e){return v(t.valueOf(),e.valueOf())}function ut(t,e){return t.source===e.source&&t.flags===e.flags}function G(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.values(),o,a;(o=n.next())&&!o.done;){for(var i=e.values(),c=!1,h=0;(a=i.next())&&!a.done;)!c&&!s[h]&&(c=r.equals(o.value,a.value,o.value,a.value,t,e,r))&&(s[h]=!0),h++;if(!c)return!1}return!0}function lt(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}var ct="[object Arguments]",ft="[object Boolean]",ht="[object Date]",pt="[object Map]",mt="[object Number]",dt="[object Object]",bt="[object RegExp]",gt="[object Set]",Nt="[object String]",vt=Array.isArray,U=typeof ArrayBuffer=="function"&&ArrayBuffer.isView?ArrayBuffer.isView:null,V=Object.assign,yt=Object.prototype.toString.call.bind(Object.prototype.toString);function wt(t){var e=t.areArraysEqual,r=t.areDatesEqual,s=t.areMapsEqual,n=t.areObjectsEqual,o=t.arePrimitiveWrappersEqual,a=t.areRegExpsEqual,i=t.areSetsEqual,c=t.areTypedArraysEqual;return function(u,l,f){if(u===l)return!0;if(u==null||l==null||typeof u!="object"||typeof l!="object")return u!==u&&l!==l;var b=u.constructor;if(b!==l.constructor)return!1;if(b===Object)return n(u,l,f);if(vt(u))return e(u,l,f);if(U!=null&&U(u))return c(u,l,f);if(b===Date)return r(u,l,f);if(b===RegExp)return a(u,l,f);if(b===Map)return s(u,l,f);if(b===Set)return i(u,l,f);var d=yt(u);return d===ht?r(u,l,f):d===bt?a(u,l,f):d===pt?s(u,l,f):d===gt?i(u,l,f):d===dt?typeof u.then!="function"&&typeof l.then!="function"&&n(u,l,f):d===ct?n(u,l,f):d===ft||d===mt||d===Nt?o(u,l,f):!1}}function Et(t){var e=t.circular,r=t.createCustomConfig,s=t.strict,n={areArraysEqual:s?w:nt,areDatesEqual:ot,areMapsEqual:s?_(J,w):J,areObjectsEqual:s?w:at,arePrimitiveWrappersEqual:it,areRegExpsEqual:ut,areSetsEqual:s?_(G,w):G,areTypedArraysEqual:s?w:lt};if(r&&(n=V({},n,r(n))),e){var o=$(n.areArraysEqual),a=$(n.areMapsEqual),i=$(n.areObjectsEqual),c=$(n.areSetsEqual);n=V({},n,{areArraysEqual:o,areMapsEqual:a,areObjectsEqual:i,areSetsEqual:c})}return n}function Ot(t){return function(e,r,s,n,o,a,i){return t(e,r,i)}}function $t(t){var e=t.circular,r=t.comparator,s=t.createState,n=t.equals,o=t.strict;if(s)return function(c,h){var u=s(),l=u.cache,f=l===void 0?e?new WeakMap:void 0:l,b=u.meta;return r(c,h,{cache:f,equals:n,meta:b,strict:o})};if(e)return function(c,h){return r(c,h,{cache:new WeakMap,equals:n,meta:void 0,strict:o})};var a={cache:void 0,equals:n,meta:void 0,strict:o};return function(c,h){return r(c,h,a)}}var At=g();g({strict:!0});g({circular:!0});g({circular:!0,strict:!0});g({createInternalComparator:function(){return v}});g({strict:!0,createInternalComparator:function(){return v}});g({circular:!0,createInternalComparator:function(){return v}});g({circular:!0,createInternalComparator:function(){return v},strict:!0});function g(t){t===void 0&&(t={});var e=t.circular,r=e===void 0?!1:e,s=t.createInternalComparator,n=t.createState,o=t.strict,a=o===void 0?!1:o,i=Et(t),c=wt(i),h=s?s(c):Ot(c);return $t({circular:r,comparator:c,createState:n,equals:h,strict:a})}function St(t,e){return At(t,e)}function M(t,e,r){return JSON.stringify(t,(n,o)=>{let a=o;return e&&(a=e(n,a)),a===void 0&&(a=null),a},r)}function oe(t,e){function r(n){return Object.keys(n).forEach(o=>{n[o]===null?n[o]=void 0:typeof n[o]=="object"&&(n[o]=r(n[o]))}),n}const s=JSON.parse(t,e);if(s!==null)return typeof s=="object"?r(s):s}function qt(t){try{const e=M(t);return e===M(oe(e))}catch{return!1}}const jt=t=>t.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/"),ae={title:"Platform.Bible menus",type:"object",properties:{mainMenu:{description:"Top level menu for the application",$ref:"#/$defs/multiColumnMenu"},defaultWebViewTopMenu:{description:"Default top menu for web views that don't specify their own",$ref:"#/$defs/multiColumnMenu"},defaultWebViewContextMenu:{description:"Default context menu for web views that don't specify their own",$ref:"#/$defs/singleColumnMenu"},webViewMenus:{description:"Menus that apply per web view in the application",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{$ref:"#/$defs/menusForOneWebView"}},additionalProperties:!1}},required:["mainMenu","defaultWebViewTopMenu","defaultWebViewContextMenu","webViewMenus"],additionalProperties:!1,$defs:{localizeKey:{description:"Identifier for a string that will be localized in a menu based on the user's UI language",type:"string",pattern:"^%[\\w\\-\\.]+%$"},referencedItem:{description:"Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)",type:"string",pattern:"^[\\w\\-]+\\.[\\w\\-]+$"},columnsWithHeaders:{description:"Group of columns that can be combined with other columns to form a multi-column menu",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single column with a header string",type:"object",properties:{label:{description:"Header text for this this column in the UI",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},order:{description:"Relative order of this column compared to other columns (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu groups to this column",type:"boolean"}},required:["label","order"],additionalProperties:!1}},properties:{isExtensible:{description:"Defines whether contributions are allowed to add columns to this multi-column menu",type:"boolean"}}},menuGroups:{description:"Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single group that contains menu items",type:"object",oneOf:[{properties:{column:{description:"Column where this group belongs, not required for single column menus",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["order"],additionalProperties:!1},{properties:{menuItem:{description:"Menu item that anchors the submenu where this group belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["menuItem","order"],additionalProperties:!1}]}},additionalProperties:!1},menuItem:{description:"Single item in a menu that can be clicked on to take an action or can be the parent of a submenu",type:"object",oneOf:[{properties:{id:{description:"ID for this menu item that holds a submenu",$ref:"#/$defs/referencedItem"}},required:["id"]},{properties:{command:{description:"Name of the PAPI command to run when this menu item is selected.",$ref:"#/$defs/referencedItem"},iconPathBefore:{description:"Path to the icon to display before the menu text",type:"string"},iconPathAfter:{description:"Path to the icon to display after the menu text",type:"string"}},required:["command"]}],properties:{label:{description:"Key that represents the text of this menu item to display",$ref:"#/$defs/localizeKey"},tooltip:{description:"Key that represents the text to display if a mouse pointer hovers over the menu item",$ref:"#/$defs/localizeKey"},searchTerms:{description:"Key that represents additional words the platform should reference when users are searching for menu items",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},group:{description:"Group to which this menu item belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this menu item compared to other menu items in the same group (sorted ascending)",type:"number"}},required:["label","group","order"],unevaluatedProperties:!1},groupsAndItems:{description:"Core schema for a column",type:"object",properties:{groups:{description:"Groups that belong in this menu",$ref:"#/$defs/menuGroups"},items:{description:"List of menu items that belong in this menu",type:"array",items:{$ref:"#/$defs/menuItem"},uniqueItems:!0}},required:["groups","items"]},singleColumnMenu:{description:"Menu that contains a column without a header",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"}],unevaluatedProperties:!1},multiColumnMenu:{description:"Menu that can contain multiple columns with headers",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"},{properties:{columns:{description:"Columns that belong in this menu",$ref:"#/$defs/columnsWithHeaders"}},required:["columns"]}],unevaluatedProperties:!1},menusForOneWebView:{description:"Set of menus that are associated with a single tab",type:"object",properties:{includeDefaults:{description:"Indicates whether the platform default menus should be included for this webview",type:"boolean"},topMenu:{description:"Menu that opens when you click on the top left corner of a tab",$ref:"#/$defs/multiColumnMenu"},contextMenu:{description:"Menu that opens when you right click on the main body/area of a tab",$ref:"#/$defs/singleColumnMenu"}},additionalProperties:!1}}};Object.freeze(ae);exports.AsyncVariable=me;exports.DocumentCombinerEngine=$e;exports.FIRST_SCR_BOOK_NUM=K;exports.FIRST_SCR_CHAPTER_NUM=Z;exports.FIRST_SCR_VERSE_NUM=X;exports.LAST_SCR_BOOK_NUM=L;exports.PlatformEventEmitter=je;exports.UnsubscriberAsyncList=qe;exports.aggregateUnsubscriberAsyncs=Re;exports.aggregateUnsubscribers=Te;exports.at=Fe;exports.charAt=He;exports.codePointAt=ke;exports.createSyncProxyForAsyncObject=Oe;exports.debounce=be;exports.deepClone=E;exports.deepEqual=St;exports.deserialize=oe;exports.endsWith=We;exports.getAllObjectFunctionNames=Ee;exports.getChaptersForBook=Q;exports.getErrorMessage=ye;exports.groupBy=ge;exports.htmlEncode=jt;exports.includes=Ke;exports.indexOf=S;exports.isSerializable=qt;exports.isString=F;exports.lastIndexOf=te;exports.length=m;exports.menuDocumentSchema=ae;exports.newGuid=de;exports.normalize=Le;exports.offsetBook=Ce;exports.offsetChapter=Me;exports.offsetVerse=Pe;exports.padEnd=Ze;exports.padStart=Xe;exports.serialize=M;exports.slice=Qe;exports.split=Ye;exports.startsWith=et;exports.substring=O;exports.toArray=re;exports.wait=H;exports.waitForDuration=we; //# sourceMappingURL=index.cjs.map diff --git a/lib/platform-bible-utils/dist/index.cjs.map b/lib/platform-bible-utils/dist/index.cjs.map index 2a1792717d..9d7d7063c5 100644 --- a/lib/platform-bible-utils/dist/index.cjs.map +++ b/lib/platform-bible-utils/dist/index.cjs.map @@ -1 +1 @@ -{"version":3,"file":"index.cjs","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * Finds the Unicode code point at the given index\n *\n * @param {string} string String to index\n * @param {number} index Position of the character to be returned in range of 0 to -length(string)\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > length(string) || index < -length(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * Always indexes string as a sequence of Unicode code points\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, empty string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > length(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to index\n * @param {number} index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {number | undefined} Non-negative integer representing the code point value of the\n * character at the given index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > length(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * Determines whether a string ends with the characters of this string. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Characters to search for at the end of the string\n * @param {number} [endPosition=length(string)] End position where searchString is expected to be\n * found. Default is `length(string)`\n * @returns {boolean} True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = length(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + length(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * Performs a case-sensitive search to determine if searchString is found in string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString String to search for\n * @param {string} [position=0] Position within the string to start searching for searchString.\n * Default is `0`\n * @returns {boolean} True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * Returns the index of the first occurrence of a given string. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The string to search for\n * @param {number} [position=0] Start of searching. Default is `0`\n * @returns {number} Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * Searches this string and returns the index of the last occurrence of the specified substring.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Substring to search for\n * @param {number} [position=+Infinity] The method returns the index of the last occurrence of the\n * specified substring at a position less than or equal to position. . Default is `+Infinity`\n * @returns {number} Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(\n string: string,\n searchString: string,\n position: number = +Infinity,\n): number {\n let validatedPosition = position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= length(string)) {\n validatedPosition = length(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, length(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * Returns the length of a string. This function handles Unicode code points instead of UTF-16\n * character codes.\n *\n * @param {string} string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function length(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * Returns the Unicode Normalization Form of this string.\n *\n * @param {string} string The starting string\n * @param {'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'} [form='NFC'] Form specifying the Unicode\n * Normalization Form. Default is `'NFC'`\n * @returns {string} A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within targetLength, it will be truncated. Default is `\" \"`\n * @returns {string} String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\nfunction correctSliceIndex(stringLength: number, index: number) {\n if (index > stringLength) return stringLength;\n if (index < -stringLength) return 0;\n if (index < 0) return index + stringLength;\n return index;\n}\n\n/**\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The starting string\n * @param {number} indexStart The index of the first character to include in the returned substring.\n * @param {number} indexEnd The index of the first character to exclude from the returned substring.\n * @returns {string} A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const stringLength: number = length(string);\n if (\n indexStart > stringLength ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(\n indexStart > 0 &&\n indexStart < stringLength &&\n indexEnd < 0 &&\n indexEnd > -stringLength\n )) ||\n indexEnd < -stringLength ||\n (indexStart < 0 && indexStart > -stringLength && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(stringLength, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The string to split\n * @param {string | RegExp} separator The pattern describing where each split should occur\n * @param {number} splitLimit Limit on the number of substrings to be included in the array. Splits\n * the string at each occurrence of specified separator, but stops when limit entries have been\n * placed in the array.\n * @returns {string[] | undefined} An array of strings, split at each point where separator occurs\n * in the starting string. Returns undefined if separator is not found in string.\n */\nexport function split(\n string: string,\n separator: string | RegExp,\n splitLimit?: number,\n): string[] | undefined {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !separator.flags.includes('g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return undefined;\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = length(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate. This function handles Unicode code points instead of UTF-16 character\n * codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The characters to be searched for at the start of this string.\n * @param {number} [position=0] The start position at which searchString is expected to be found\n * (the index of searchString's first character). Default is `0`\n * @returns {boolean} True if the given characters are found at the beginning of the string,\n * including when searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * Returns a substring by providing start and length. This function handles Unicode code points\n * instead of UTF-16 character codes. This function is not exported because it is considered\n * deprecated, however it is still useful as a local helper function.\n *\n * @param {string} string String to be divided\n * @param {number} [begin=Start of string] Start position. Default is `Start of string`\n * @param {number} [len=String length minus start parameter] Length of result. Default is `String\n * length minus start parameter`. Default is `String length minus start parameter`\n * @returns {string} Substring from starting string\n */\nfunction substr(string: string, begin: number = 0, len: number = length(string) - begin): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * Returns a substring by providing start and end position. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to be divided\n * @param {string} begin Start position\n * @param {number} [end=End of string] End position. Default is `End of string`\n * @returns {string} Substring from starting string\n */\nexport function substring(\n string: string,\n begin?: number | undefined,\n end: number | undefined = length(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * Converts a string to an array of string characters. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param {string} string String to convert to array\n * @returns {string[]} An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","stringLength","slice","indexStart","indexEnd","newStart","newEnd","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","result","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","matchIndex","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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,CACE,WAAY,CACV,OAAQ,CACN,YACE,wEACF,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,OAAO,EAClB,qBAAsB,EACxB,EACA,CACE,WAAY,CACV,SAAU,CACR,YAAa,8DACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,WAAY,OAAO,EAC9B,qBAAsB,EACxB,CACF,CACF,CACF,EACA,qBAAsB,EACxB,EACA,SAAU,CACR,YACE,mGACF,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,GAAI,CACF,YAAa,6CACb,KAAM,wBACR,CACF,EACA,SAAU,CAAC,IAAI,CACjB,EACA,CACE,WAAY,CACV,QAAS,CACP,YAAa,mEACb,KAAM,wBACR,EACA,eAAgB,CACd,YAAa,mDACb,KAAM,QACR,EACA,cAAe,CACb,YAAa,kDACb,KAAM,QACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,WAAY,CACV,MAAO,CACL,YAAa,4DACb,KAAM,qBACR,EACA,QAAS,CACP,YACE,uFACF,KAAM,qBACR,EACA,YAAa,CACX,YACE,6GACF,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YAAa,wCACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,qGACF,KAAM,QACR,CACF,EACA,SAAU,CAAC,QAAS,QAAS,OAAO,EACpC,sBAAuB,EACzB,EACA,eAAgB,CACd,YAAa,2BACb,KAAM,SACN,WAAY,CACV,OAAQ,CACN,YAAa,kCACb,KAAM,oBACR,EACA,MAAO,CACL,YAAa,8CACb,KAAM,QACN,MAAO,CAAE,KAAM,kBAAmB,EAClC,YAAa,EACf,CACF,EACA,SAAU,CAAC,SAAU,OAAO,CAC9B,EACA,iBAAkB,CAChB,YAAa,+CACb,KAAM,SACN,MAAO,CAAC,CAAE,KAAM,yBAA0B,EAC1C,sBAAuB,EACzB,EACA,gBAAiB,CACf,YAAa,sDACb,KAAM,SACN,MAAO,CACL,CAAE,KAAM,wBAAyB,EACjC,CACE,WAAY,CACV,QAAS,CACP,YAAa,mCACb,KAAM,4BACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,sBAAuB,EACzB,EACA,mBAAoB,CAClB,YAAa,qDACb,KAAM,SACN,WAAY,CACV,gBAAiB,CACf,YACE,mFACF,KAAM,SACR,EACA,QAAS,CACP,YAAa,iEACb,KAAM,yBACR,EACA,YAAa,CACX,YAAa,sEACb,KAAM,0BACR,CACF,EACA,qBAAsB,EACxB,CACF,CACF,EAEA,OAAO,OAAOA,EAAkB","x_google_ignoreList":[7,8,10]} \ No newline at end of file +{"version":3,"file":"index.cjs","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * Finds the Unicode code point at the given index\n *\n * @param {string} string String to index\n * @param {number} index Position of the character to be returned in range of 0 to -length(string)\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > length(string) || index < -length(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * Always indexes string as a sequence of Unicode code points\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, empty string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > length(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to index\n * @param {number} index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {number | undefined} Non-negative integer representing the code point value of the\n * character at the given index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > length(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * Determines whether a string ends with the characters of this string. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Characters to search for at the end of the string\n * @param {number} [endPosition=length(string)] End position where searchString is expected to be\n * found. Default is `length(string)`\n * @returns {boolean} True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = length(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + length(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * Performs a case-sensitive search to determine if searchString is found in string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString String to search for\n * @param {string} [position=0] Position within the string to start searching for searchString.\n * Default is `0`\n * @returns {boolean} True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * Returns the index of the first occurrence of a given string. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The string to search for\n * @param {number} [position=0] Start of searching. Default is `0`\n * @returns {number} Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * Searches this string and returns the index of the last occurrence of the specified substring.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Substring to search for\n * @param {number} [position=+Infinity] The method returns the index of the last occurrence of the\n * specified substring at a position less than or equal to position. . Default is `+Infinity`\n * @returns {number} Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(\n string: string,\n searchString: string,\n position: number = +Infinity,\n): number {\n let validatedPosition = position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= length(string)) {\n validatedPosition = length(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, length(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * Returns the length of a string. This function handles Unicode code points instead of UTF-16\n * character codes.\n *\n * @param {string} string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function length(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * Returns the Unicode Normalization Form of this string.\n *\n * @param {string} string The starting string\n * @param {'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'} [form='NFC'] Form specifying the Unicode\n * Normalization Form. Default is `'NFC'`\n * @returns {string} A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within targetLength, it will be truncated. Default is `\" \"`\n * @returns {string} String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\nfunction correctSliceIndex(stringLength: number, index: number) {\n if (index > stringLength) return stringLength;\n if (index < -stringLength) return 0;\n if (index < 0) return index + stringLength;\n return index;\n}\n\n/**\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The starting string\n * @param {number} indexStart The index of the first character to include in the returned substring.\n * @param {number} indexEnd The index of the first character to exclude from the returned substring.\n * @returns {string} A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const stringLength: number = length(string);\n if (\n indexStart > stringLength ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(\n indexStart > 0 &&\n indexStart < stringLength &&\n indexEnd < 0 &&\n indexEnd > -stringLength\n )) ||\n indexEnd < -stringLength ||\n (indexStart < 0 && indexStart > -stringLength && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(stringLength, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The string to split\n * @param {string | RegExp} separator The pattern describing where each split should occur\n * @param {number} splitLimit Limit on the number of substrings to be included in the array. Splits\n * the string at each occurrence of specified separator, but stops when limit entries have been\n * placed in the array.\n * @returns {string[] | undefined} An array of strings, split at each point where separator occurs\n * in the starting string. Returns undefined if separator is not found in string.\n */\nexport function split(\n string: string,\n separator: string | RegExp,\n splitLimit?: number,\n): string[] | undefined {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !separator.flags.includes('g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return undefined;\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = length(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate. This function handles Unicode code points instead of UTF-16 character\n * codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The characters to be searched for at the start of this string.\n * @param {number} [position=0] The start position at which searchString is expected to be found\n * (the index of searchString's first character). Default is `0`\n * @returns {boolean} True if the given characters are found at the beginning of the string,\n * including when searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * Returns a substring by providing start and length. This function handles Unicode code points\n * instead of UTF-16 character codes. This function is not exported because it is considered\n * deprecated, however it is still useful as a local helper function.\n *\n * @param {string} string String to be divided\n * @param {number} [begin=Start of string] Start position. Default is `Start of string`\n * @param {number} [len=String length minus start parameter] Length of result. Default is `String\n * length minus start parameter`. Default is `String length minus start parameter`\n * @returns {string} Substring from starting string\n */\nfunction substr(string: string, begin: number = 0, len: number = length(string) - begin): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * Returns a substring by providing start and end position. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to be divided\n * @param {string} begin Start position\n * @param {number} [end=End of string] End position. Default is `End of string`\n * @returns {string} Substring from starting string\n */\nexport function substring(\n string: string,\n begin?: number | undefined,\n end: number | undefined = length(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * Converts a string to an array of string characters. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param {string} string String to convert to array\n * @returns {string[]} An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","stringLength","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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,KAAM,yBACR,EACA,sBAAuB,CACrB,YAAa,8DACb,KAAM,yBACR,EACA,0BAA2B,CACzB,YAAa,kEACb,KAAM,0BACR,EACA,aAAc,CACZ,YAAa,mDACb,KAAM,SACN,kBAAmB,CACjB,0BAA2B,CACzB,KAAM,4BACR,CACF,EACA,qBAAsB,EACxB,CACF,EACA,SAAU,CAAC,WAAY,wBAAyB,4BAA6B,cAAc,EAC3F,qBAAsB,GACtB,MAAO,CACL,YAAa,CACX,YACE,2FACF,KAAM,SACN,QAAS,kBACX,EACA,eAAgB,CACd,YACE,oGACF,KAAM,SACN,QAAS,yBACX,EACA,mBAAoB,CAClB,YACE,uFACF,KAAM,SACN,kBAAmB,CACjB,0BAA2B,CACzB,YAAa,qCACb,KAAM,SACN,WAAY,CACV,MAAO,CACL,YAAa,6CACb,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YACE,6EACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,8EACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,QAAS,OAAO,EAC3B,qBAAsB,EACxB,CACF,EACA,WAAY,CACV,aAAc,CACZ,YACE,qFACF,KAAM,SACR,CACF,CACF,EACA,WAAY,CACV,YACE,uJACF,KAAM,SACN,kBAAmB,CACjB,0BAA2B,CACzB,YAAa,wCACb,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,OAAQ,CACN,YACE,wEACF,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,OAAO,EAClB,qBAAsB,EACxB,EACA,CACE,WAAY,CACV,SAAU,CACR,YAAa,8DACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,WAAY,OAAO,EAC9B,qBAAsB,EACxB,CACF,CACF,CACF,EACA,qBAAsB,EACxB,EACA,SAAU,CACR,YACE,mGACF,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,GAAI,CACF,YAAa,6CACb,KAAM,wBACR,CACF,EACA,SAAU,CAAC,IAAI,CACjB,EACA,CACE,WAAY,CACV,QAAS,CACP,YAAa,mEACb,KAAM,wBACR,EACA,eAAgB,CACd,YAAa,mDACb,KAAM,QACR,EACA,cAAe,CACb,YAAa,kDACb,KAAM,QACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,WAAY,CACV,MAAO,CACL,YAAa,4DACb,KAAM,qBACR,EACA,QAAS,CACP,YACE,uFACF,KAAM,qBACR,EACA,YAAa,CACX,YACE,6GACF,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YAAa,wCACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,qGACF,KAAM,QACR,CACF,EACA,SAAU,CAAC,QAAS,QAAS,OAAO,EACpC,sBAAuB,EACzB,EACA,eAAgB,CACd,YAAa,2BACb,KAAM,SACN,WAAY,CACV,OAAQ,CACN,YAAa,kCACb,KAAM,oBACR,EACA,MAAO,CACL,YAAa,8CACb,KAAM,QACN,MAAO,CAAE,KAAM,kBAAmB,EAClC,YAAa,EACf,CACF,EACA,SAAU,CAAC,SAAU,OAAO,CAC9B,EACA,iBAAkB,CAChB,YAAa,+CACb,KAAM,SACN,MAAO,CAAC,CAAE,KAAM,yBAA0B,EAC1C,sBAAuB,EACzB,EACA,gBAAiB,CACf,YAAa,sDACb,KAAM,SACN,MAAO,CACL,CAAE,KAAM,wBAAyB,EACjC,CACE,WAAY,CACV,QAAS,CACP,YAAa,mCACb,KAAM,4BACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,sBAAuB,EACzB,EACA,mBAAoB,CAClB,YAAa,qDACb,KAAM,SACN,WAAY,CACV,gBAAiB,CACf,YACE,mFACF,KAAM,SACR,EACA,QAAS,CACP,YAAa,iEACb,KAAM,yBACR,EACA,YAAa,CACX,YAAa,sEACb,KAAM,0BACR,CACF,EACA,qBAAsB,EACxB,CACF,CACF,EAEA,OAAO,OAAOA,EAAkB","x_google_ignoreList":[7,8,10]} \ No newline at end of file diff --git a/lib/platform-bible-utils/dist/index.d.ts b/lib/platform-bible-utils/dist/index.d.ts index 4284645a03..1223435544 100644 --- a/lib/platform-bible-utils/dist/index.d.ts +++ b/lib/platform-bible-utils/dist/index.d.ts @@ -491,6 +491,33 @@ export declare function padStart(string: string, targetLength: number, padString * @returns {string} A new string containing the extracted section of the string. */ export declare function slice(string: string, indexStart: number, indexEnd?: number): string; +/** + * Takes a pattern and divides the string into an ordered list of substrings by searching for the + * pattern, puts these substrings into an array, and returns the array. This function handles + * Unicode code points instead of UTF-16 character codes. + * + * @param {string} string The string to split + * @param {string | RegExp} separator The pattern describing where each split should occur + * @param {number} splitLimit Limit on the number of substrings to be included in the array. Splits + * the string at each occurrence of specified separator, but stops when limit entries have been + * placed in the array. + * @returns {string[] | undefined} An array of strings, split at each point where separator occurs + * in the starting string. Returns undefined if separator is not found in string. + */ +export declare function split(string: string, separator: string | RegExp, splitLimit?: number): string[] | undefined; +/** + * Determines whether the string begins with the characters of a specified string, returning true or + * false as appropriate. This function handles Unicode code points instead of UTF-16 character + * codes. + * + * @param {string} string String to search through + * @param {string} searchString The characters to be searched for at the start of this string. + * @param {number} [position=0] The start position at which searchString is expected to be found + * (the index of searchString's first character). Default is `0` + * @returns {boolean} True if the given characters are found at the beginning of the string, + * including when searchString is an empty string; otherwise, false. + */ +export declare function startsWith(string: string, searchString: string, position?: number): boolean; /** * Returns a substring by providing start and end position. This function handles Unicode code * points instead of UTF-16 character codes. diff --git a/lib/platform-bible-utils/dist/index.js b/lib/platform-bible-utils/dist/index.js index 8ee64aed3b..0856c1dcf2 100644 --- a/lib/platform-bible-utils/dist/index.js +++ b/lib/platform-bible-utils/dist/index.js @@ -1,7 +1,7 @@ -var ee = Object.defineProperty; -var te = (t, e, r) => e in t ? ee(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r; -var p = (t, e, r) => (te(t, typeof e != "symbol" ? e + "" : e, r), r); -class et { +var te = Object.defineProperty; +var re = (t, e, r) => e in t ? te(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r; +var p = (t, e, r) => (re(t, typeof e != "symbol" ? e + "" : e, r), r); +class tt { /** * Creates an instance of the class * @@ -75,7 +75,7 @@ class et { this.resolver = void 0, this.rejecter = void 0, Object.freeze(this); } } -function tt() { +function rt() { return "00-0-4-1-000".replace( /[^-]/g, (t) => ( @@ -85,36 +85,36 @@ function tt() { ) ); } -function re(t) { +function se(t) { return typeof t == "string" || t instanceof String; } function O(t) { return JSON.parse(JSON.stringify(t)); } -function rt(t, e = 300) { - if (re(t)) +function st(t, e = 300) { + if (se(t)) throw new Error("Tried to debounce a string! Could be XSS"); let r; return (...s) => { clearTimeout(r), r = setTimeout(() => t(...s), e); }; } -function st(t, e, r) { +function nt(t, e, r) { const s = /* @__PURE__ */ new Map(); return t.forEach((n) => { const o = e(n), a = s.get(o), i = r ? r(n, o) : n; a ? a.push(i) : s.set(o, [i]); }), s; } -function se(t) { +function ne(t) { return typeof t == "object" && // We're potentially dealing with objects we didn't create, so they might contain `null` // eslint-disable-next-line no-null/no-null t !== null && "message" in t && // Type assert `error` to check it's `message`. // eslint-disable-next-line no-type-assertion/no-type-assertion typeof t.message == "string"; } -function ne(t) { - if (se(t)) +function oe(t) { + if (ne(t)) return t; try { return new Error(JSON.stringify(t)); @@ -122,18 +122,18 @@ function ne(t) { return new Error(String(t)); } } -function nt(t) { - return ne(t).message; +function ot(t) { + return oe(t).message; } -function oe(t) { +function ae(t) { return new Promise((e) => setTimeout(e, t)); } -function ot(t, e) { - const r = oe(e).then(() => { +function at(t, e) { + const r = ae(e).then(() => { }); return Promise.any([r, t()]); } -function at(t, e = "obj") { +function it(t, e = "obj") { const r = /* @__PURE__ */ new Set(); Object.getOwnPropertyNames(t).forEach((n) => { try { @@ -153,14 +153,14 @@ function at(t, e = "obj") { }), s = Object.getPrototypeOf(s); return r; } -function it(t, e = {}) { +function ut(t, e = {}) { return new Proxy(e, { get(r, s) { return s in r ? r[s] : async (...n) => (await t())[s](...n); } }); } -class ut { +class lt { /** * Create a DocumentCombinerEngine instance * @@ -231,7 +231,7 @@ class ut { } let e = this.baseDocument; return this.contributions.forEach((r) => { - e = V( + e = U( e, r, this.options.ignoreDuplicateProperties @@ -239,24 +239,24 @@ class ut { }), e = this.transformFinalOutput(e), this.validateOutput(e), this.latestOutput = e, this.latestOutput; } } -function ae(...t) { +function ie(...t) { let e = !0; return t.forEach((r) => { (!r || typeof r != "object" || Array.isArray(r)) && (e = !1); }), e; } -function ie(...t) { +function ue(...t) { let e = !0; return t.forEach((r) => { (!r || typeof r != "object" || !Array.isArray(r)) && (e = !1); }), e; } -function V(t, e, r) { +function U(t, e, r) { const s = O(t); return e && Object.keys(e).forEach((n) => { if (Object.hasOwn(t, n)) { - if (ae(t[n], e[n])) - s[n] = V( + if (ie(t[n], e[n])) + s[n] = U( // We know these are objects from the `if` check /* eslint-disable no-type-assertion/no-type-assertion */ t[n], @@ -264,7 +264,7 @@ function V(t, e, r) { r /* eslint-enable no-type-assertion/no-type-assertion */ ); - else if (ie(t[n], e[n])) + else if (ue(t[n], e[n])) s[n] = s[n].concat(e[n]); else if (!r) throw new Error(`Cannot merge objects: key "${n}" already exists in the target object`); @@ -272,7 +272,7 @@ function V(t, e, r) { s[n] = e[n]; }), s; } -class lt { +class ct { constructor(e = "Anonymous") { p(this, "unsubscribers", /* @__PURE__ */ new Set()); this.name = e; @@ -297,7 +297,7 @@ class lt { return this.unsubscribers.clear(), r.every((s, n) => (s || console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${n} failed!`), s)); } } -class ct { +class ft { constructor() { /** * Subscribes a function to run when this event is emitted. @@ -366,7 +366,7 @@ class ct { return this.assertNotDisposed(), this.isDisposed = !0, this.subscriptions = void 0, this.lazyEvent = void 0, Promise.resolve(!0); } } -const H = [ +const k = [ { shortName: "ERR", fullNames: ["ERROR"], chapters: -1 }, { shortName: "GEN", fullNames: ["Genesis"], chapters: 50 }, { shortName: "EXO", fullNames: ["Exodus"], chapters: 40 }, @@ -434,56 +434,56 @@ const H = [ { shortName: "3JN", fullNames: ["3 John"], chapters: 1 }, { shortName: "JUD", fullNames: ["Jude"], chapters: 1 }, { shortName: "REV", fullNames: ["Revelation"], chapters: 22 } -], ue = 1, le = H.length - 1, ce = 1, fe = 1, he = (t) => { +], le = 1, ce = k.length - 1, fe = 1, he = 1, pe = (t) => { var e; - return ((e = H[t]) == null ? void 0 : e.chapters) ?? -1; -}, ft = (t, e) => ({ - bookNum: Math.max(ue, Math.min(t.bookNum + e, le)), + return ((e = k[t]) == null ? void 0 : e.chapters) ?? -1; +}, ht = (t, e) => ({ + bookNum: Math.max(le, Math.min(t.bookNum + e, ce)), chapterNum: 1, verseNum: 1 -}), ht = (t, e) => ({ +}), pt = (t, e) => ({ ...t, chapterNum: Math.min( - Math.max(ce, t.chapterNum + e), - he(t.bookNum) + Math.max(fe, t.chapterNum + e), + pe(t.bookNum) ), verseNum: 1 -}), pt = (t, e) => ({ +}), mt = (t, e) => ({ ...t, - verseNum: Math.max(fe, t.verseNum + e) -}), mt = (t) => (...e) => t.map((s) => s(...e)).every((s) => s), dt = (t) => async (...e) => { + verseNum: Math.max(he, t.verseNum + e) +}), dt = (t) => (...e) => t.map((s) => s(...e)).every((s) => s), bt = (t) => async (...e) => { const r = t.map(async (s) => s(...e)); return (await Promise.all(r)).every((s) => s); }; -var S = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}, v = {}, pe = () => { - const t = "\\ud800-\\udfff", e = "\\u0300-\\u036f", r = "\\ufe20-\\ufe2f", s = "\\u20d0-\\u20ff", n = "\\u1ab0-\\u1aff", o = "\\u1dc0-\\u1dff", a = e + r + s + n + o, i = "\\ufe0e\\ufe0f", c = "\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93", h = `[${t}]`, u = `[${a}]`, l = "\\ud83c[\\udffb-\\udfff]", f = `(?:${u}|${l})`, b = `[^${t}]`, m = "(?:\\uD83C[\\uDDE6-\\uDDFF]){2}", y = "[\\ud800-\\udbff][\\udc00-\\udfff]", q = "\\u200d", L = "(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)", Z = `[${c}]`, M = `${f}?`, P = `[${i}]?`, X = `(?:${q}(?:${[b, m, y].join("|")})${P + M})*`, Q = P + M + X, Y = `(?:${[`${b}${u}?`, u, m, y, h, Z].join("|")})`; - return new RegExp(`${L}|${l}(?=${l})|${Y + Q}`, "g"); -}, me = S && S.__importDefault || function(t) { +var D = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}, g = {}, me = () => { + const t = "\\ud800-\\udfff", e = "\\u0300-\\u036f", r = "\\ufe20-\\ufe2f", s = "\\u20d0-\\u20ff", n = "\\u1ab0-\\u1aff", o = "\\u1dc0-\\u1dff", a = e + r + s + n + o, i = "\\ufe0e\\ufe0f", c = "\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93", h = `[${t}]`, u = `[${a}]`, l = "\\ud83c[\\udffb-\\udfff]", f = `(?:${u}|${l})`, b = `[^${t}]`, m = "(?:\\uD83C[\\uDDE6-\\uDDFF]){2}", y = "[\\ud800-\\udbff][\\udc00-\\udfff]", j = "\\u200d", Z = "(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)", X = `[${c}]`, P = `${f}?`, T = `[${i}]?`, Q = `(?:${j}(?:${[b, m, y].join("|")})${T + P})*`, Y = T + P + Q, ee = `(?:${[`${b}${u}?`, u, m, y, h, X].join("|")})`; + return new RegExp(`${Z}|${l}(?=${l})|${ee + Y}`, "g"); +}, de = D && D.__importDefault || function(t) { return t && t.__esModule ? t : { default: t }; }; -Object.defineProperty(v, "__esModule", { value: !0 }); -var $ = me(pe); -function j(t) { +Object.defineProperty(g, "__esModule", { value: !0 }); +var A = de(me); +function S(t) { if (typeof t != "string") throw new Error("A string is expected as input"); - return t.match($.default()) || []; + return t.match(A.default()) || []; } -var de = v.toArray = j; +var be = g.toArray = S; function C(t) { if (typeof t != "string") throw new Error("Input must be a string"); - var e = t.match($.default()); + var e = t.match(A.default()); return e === null ? 0 : e.length; } -var be = v.length = C; -function U(t, e, r) { +var Ne = g.length = C; +function F(t, e, r) { if (e === void 0 && (e = 0), typeof t != "string") throw new Error("Input must be a string"); (typeof e != "number" || e < 0) && (e = 0), typeof r == "number" && r < 0 && (r = 0); - var s = t.match($.default()); + var s = t.match(A.default()); return s ? s.slice(e, r).join("") : ""; } -var Ne = v.substring = U; +var ge = g.substring = F; function ve(t, e, r) { if (e === void 0 && (e = 0), typeof t != "string") throw new Error("Input must be a string"); @@ -493,11 +493,11 @@ function ve(t, e, r) { e < 0 && (e += s); var n; typeof r > "u" ? n = s : (typeof r != "number" && (r = parseInt(r, 10)), n = r >= 0 ? r + e : e); - var o = t.match($.default()); + var o = t.match(A.default()); return o ? o.slice(e, n).join("") : ""; } -var ge = v.substr = ve; -function ye(t, e, r, s) { +var ye = g.substr = ve; +function we(t, e, r, s) { if (e === void 0 && (e = 16), r === void 0 && (r = "#"), s === void 0 && (s = "right"), typeof t != "string" || typeof e != "number") throw new Error("Invalid arguments specified"); if (["left", "right"].indexOf(s) === -1) @@ -505,26 +505,26 @@ function ye(t, e, r, s) { typeof r != "string" && (r = String(r)); var n = C(t); if (n > e) - return U(t, 0, e); + return F(t, 0, e); if (n < e) { var o = r.repeat(e - n); return s === "left" ? o + t : t + o; } return t; } -var F = v.limit = ye; -function we(t, e, r) { +var W = g.limit = we; +function Ee(t, e, r) { if (r === void 0 && (r = 0), typeof t != "string") throw new Error("Input must be a string"); if (t === "") return e === "" ? 0 : -1; r = Number(r), r = isNaN(r) ? 0 : r, e = String(e); - var s = j(t); + var s = S(t); if (r >= s.length) return e === "" ? s.length : -1; if (e === "") return r; - var n = j(e), o = !1, a; + var n = S(e), o = !1, a; for (a = r; a < s.length; a += 1) { for (var i = 0; i < n.length && n[i] === s[a + i]; ) i += 1; @@ -535,71 +535,93 @@ function we(t, e, r) { } return o ? a : -1; } -var Ee = v.indexOf = we; -function bt(t, e) { +var Oe = g.indexOf = Ee; +function Nt(t, e) { if (!(e > d(t) || e < -d(t))) - return A(t, e, 1); + return q(t, e, 1); } -function Nt(t, e) { - return e < 0 || e > d(t) - 1 ? "" : A(t, e, 1); +function gt(t, e) { + return e < 0 || e > d(t) - 1 ? "" : q(t, e, 1); } function vt(t, e) { if (!(e < 0 || e > d(t) - 1)) - return A(t, e, 1).codePointAt(0); + return q(t, e, 1).codePointAt(0); } -function gt(t, e, r = d(t)) { +function yt(t, e, r = d(t)) { const s = $e(t, e); return !(s === -1 || s + d(e) !== r); } -function yt(t, e, r = 0) { - const s = k(t, r); - return Oe(s, e) !== -1; +function wt(t, e, r = 0) { + const s = $(t, r); + return M(s, e) !== -1; } -function Oe(t, e, r = 0) { - return Ee(t, e, r); +function M(t, e, r = 0) { + return Oe(t, e, r); } function $e(t, e, r = 1 / 0) { let s = r; s < 0 ? s = 0 : s >= d(t) && (s = d(t) - 1); for (let n = s; n >= 0; n--) - if (A(t, n, d(e)) === e) + if (q(t, n, d(e)) === e) return n; return -1; } function d(t) { - return be(t); + return Ne(t); } -function wt(t, e) { +function Et(t, e) { const r = e.toUpperCase(); return r === "NONE" ? t : t.normalize(r); } -function Et(t, e, r = " ") { - return e <= d(t) ? t : F(t, e, r, "right"); -} function Ot(t, e, r = " ") { - return e <= d(t) ? t : F(t, e, r, "left"); + return e <= d(t) ? t : W(t, e, r, "right"); +} +function $t(t, e, r = " ") { + return e <= d(t) ? t : W(t, e, r, "left"); } -function T(t, e) { +function R(t, e) { return e > t ? t : e < -t ? 0 : e < 0 ? e + t : e; } -function $t(t, e, r) { +function At(t, e, r) { const s = d(t); if (e > s || r && (e > r && !(e > 0 && e < s && r < 0 && r > -s) || r < -s || e < 0 && e > -s && r > 0)) return ""; - const n = T(s, e), o = r ? T(s, r) : void 0; - return k(t, n, o); + const n = R(s, e), o = r ? R(s, r) : void 0; + return $(t, n, o); } -function A(t, e = 0, r = d(t) - e) { - return ge(t, e, r); +function qt(t, e, r) { + const s = []; + if (r !== void 0 && r <= 0) + return [t]; + if (e === "") + return Ae(t).slice(0, r); + let n = e; + (typeof e == "string" || e instanceof RegExp && !e.flags.includes("g")) && (n = new RegExp(e, "g")); + const o = t.match(n); + let a = 0; + if (o) { + for (let i = 0; i < (r ? r - 1 : o.length); i++) { + const c = M(t, o[i], a), h = d(o[i]); + if (s.push($(t, a, c)), a = c + h, r !== void 0 && s.length === r) + break; + } + return s.push($(t, a)), s; + } } -function k(t, e, r = d(t)) { - return Ne(t, e, r); +function jt(t, e, r = 0) { + return M(t, e, r) === r; } -function At(t) { - return de(t); +function q(t, e = 0, r = d(t) - e) { + return ye(t, e, r); } -var Ae = Object.getOwnPropertyNames, qe = Object.getOwnPropertySymbols, je = Object.prototype.hasOwnProperty; -function D(t, e) { +function $(t, e, r = d(t)) { + return ge(t, e, r); +} +function Ae(t) { + return be(t); +} +var qe = Object.getOwnPropertyNames, je = Object.getOwnPropertySymbols, Se = Object.prototype.hasOwnProperty; +function I(t, e) { return function(s, n, o) { return t(s, n, o) && e(s, n, o); }; @@ -616,16 +638,16 @@ function E(t) { return o.delete(r), o.delete(s), c; }; } -function R(t) { - return Ae(t).concat(qe(t)); +function x(t) { + return qe(t).concat(je(t)); } var K = Object.hasOwn || function(t, e) { - return je.call(t, e); + return Se.call(t, e); }; -function g(t, e) { +function v(t, e) { return t || e ? t === e : t === e || t !== t && e !== e; } -var W = "_owner", I = Object.getOwnPropertyDescriptor, z = Object.keys; +var L = "_owner", z = Object.getOwnPropertyDescriptor, _ = Object.keys; function Ce(t, e, r) { var s = t.length; if (e.length !== s) @@ -636,15 +658,15 @@ function Ce(t, e, r) { return !0; } function Me(t, e) { - return g(t.getTime(), e.getTime()); + return v(t.getTime(), e.getTime()); } -function _(t, e, r) { +function J(t, e, r) { if (t.size !== e.size) return !1; for (var s = {}, n = t.entries(), o = 0, a, i; (a = n.next()) && !a.done; ) { for (var c = e.entries(), h = !1, u = 0; (i = c.next()) && !i.done; ) { - var l = a.value, f = l[0], b = l[1], m = i.value, y = m[0], q = m[1]; - !h && !s[u] && (h = r.equals(f, y, o, u, t, e, r) && r.equals(b, q, f, y, t, e, r)) && (s[u] = !0), u++; + var l = a.value, f = l[0], b = l[1], m = i.value, y = m[0], j = m[1]; + !h && !s[u] && (h = r.equals(f, y, o, u, t, e, r) && r.equals(b, j, f, y, t, e, r)) && (s[u] = !0), u++; } if (!h) return !1; @@ -653,30 +675,30 @@ function _(t, e, r) { return !0; } function Pe(t, e, r) { - var s = z(t), n = s.length; - if (z(e).length !== n) + var s = _(t), n = s.length; + if (_(e).length !== n) return !1; for (var o; n-- > 0; ) - if (o = s[n], o === W && (t.$$typeof || e.$$typeof) && t.$$typeof !== e.$$typeof || !K(e, o) || !r.equals(t[o], e[o], o, o, t, e, r)) + if (o = s[n], o === L && (t.$$typeof || e.$$typeof) && t.$$typeof !== e.$$typeof || !K(e, o) || !r.equals(t[o], e[o], o, o, t, e, r)) return !1; return !0; } function w(t, e, r) { - var s = R(t), n = s.length; - if (R(e).length !== n) + var s = x(t), n = s.length; + if (x(e).length !== n) return !1; for (var o, a, i; n-- > 0; ) - if (o = s[n], o === W && (t.$$typeof || e.$$typeof) && t.$$typeof !== e.$$typeof || !K(e, o) || !r.equals(t[o], e[o], o, o, t, e, r) || (a = I(t, o), i = I(e, o), (a || i) && (!a || !i || a.configurable !== i.configurable || a.enumerable !== i.enumerable || a.writable !== i.writable))) + if (o = s[n], o === L && (t.$$typeof || e.$$typeof) && t.$$typeof !== e.$$typeof || !K(e, o) || !r.equals(t[o], e[o], o, o, t, e, r) || (a = z(t, o), i = z(e, o), (a || i) && (!a || !i || a.configurable !== i.configurable || a.enumerable !== i.enumerable || a.writable !== i.writable))) return !1; return !0; } -function Se(t, e) { - return g(t.valueOf(), e.valueOf()); -} function Te(t, e) { + return v(t.valueOf(), e.valueOf()); +} +function De(t, e) { return t.source === e.source && t.flags === e.flags; } -function J(t, e, r) { +function G(t, e, r) { if (t.size !== e.size) return !1; for (var s = {}, n = t.values(), o, a; (o = n.next()) && !o.done; ) { @@ -687,7 +709,7 @@ function J(t, e, r) { } return !0; } -function De(t, e) { +function Re(t, e) { var r = t.length; if (e.length !== r) return !1; @@ -696,7 +718,7 @@ function De(t, e) { return !1; return !0; } -var Re = "[object Arguments]", Ie = "[object Boolean]", ze = "[object Date]", _e = "[object Map]", Je = "[object Number]", Ge = "[object Object]", xe = "[object RegExp]", Be = "[object Set]", Ve = "[object String]", He = Array.isArray, G = typeof ArrayBuffer == "function" && ArrayBuffer.isView ? ArrayBuffer.isView : null, x = Object.assign, Ue = Object.prototype.toString.call.bind(Object.prototype.toString); +var Ie = "[object Arguments]", xe = "[object Boolean]", ze = "[object Date]", _e = "[object Map]", Je = "[object Number]", Ge = "[object Object]", Be = "[object RegExp]", Ve = "[object Set]", He = "[object String]", Ue = Array.isArray, B = typeof ArrayBuffer == "function" && ArrayBuffer.isView ? ArrayBuffer.isView : null, V = Object.assign, ke = Object.prototype.toString.call.bind(Object.prototype.toString); function Fe(t) { var e = t.areArraysEqual, r = t.areDatesEqual, s = t.areMapsEqual, n = t.areObjectsEqual, o = t.arePrimitiveWrappersEqual, a = t.areRegExpsEqual, i = t.areSetsEqual, c = t.areTypedArraysEqual; return function(u, l, f) { @@ -709,9 +731,9 @@ function Fe(t) { return !1; if (b === Object) return n(u, l, f); - if (He(u)) + if (Ue(u)) return e(u, l, f); - if (G != null && G(u)) + if (B != null && B(u)) return c(u, l, f); if (b === Date) return r(u, l, f); @@ -721,24 +743,24 @@ function Fe(t) { return s(u, l, f); if (b === Set) return i(u, l, f); - var m = Ue(u); - return m === ze ? r(u, l, f) : m === xe ? a(u, l, f) : m === _e ? s(u, l, f) : m === Be ? i(u, l, f) : m === Ge ? typeof u.then != "function" && typeof l.then != "function" && n(u, l, f) : m === Re ? n(u, l, f) : m === Ie || m === Je || m === Ve ? o(u, l, f) : !1; + var m = ke(u); + return m === ze ? r(u, l, f) : m === Be ? a(u, l, f) : m === _e ? s(u, l, f) : m === Ve ? i(u, l, f) : m === Ge ? typeof u.then != "function" && typeof l.then != "function" && n(u, l, f) : m === Ie ? n(u, l, f) : m === xe || m === Je || m === He ? o(u, l, f) : !1; }; } -function ke(t) { +function We(t) { var e = t.circular, r = t.createCustomConfig, s = t.strict, n = { areArraysEqual: s ? w : Ce, areDatesEqual: Me, - areMapsEqual: s ? D(_, w) : _, + areMapsEqual: s ? I(J, w) : J, areObjectsEqual: s ? w : Pe, - arePrimitiveWrappersEqual: Se, - areRegExpsEqual: Te, - areSetsEqual: s ? D(J, w) : J, - areTypedArraysEqual: s ? w : De + arePrimitiveWrappersEqual: Te, + areRegExpsEqual: De, + areSetsEqual: s ? I(G, w) : G, + areTypedArraysEqual: s ? w : Re }; - if (r && (n = x({}, n, r(n))), e) { + if (r && (n = V({}, n, r(n))), e) { var o = E(n.areArraysEqual), a = E(n.areMapsEqual), i = E(n.areObjectsEqual), c = E(n.areSetsEqual); - n = x({}, n, { + n = V({}, n, { areArraysEqual: o, areMapsEqual: a, areObjectsEqual: i, @@ -752,7 +774,7 @@ function Ke(t) { return t(e, r, i); }; } -function We(t) { +function Le(t) { var e = t.circular, r = t.comparator, s = t.createState, n = t.equals, o = t.strict; if (s) return function(c, h) { @@ -783,7 +805,7 @@ function We(t) { return r(c, h, a); }; } -var Le = N(); +var Ze = N(); N({ strict: !0 }); N({ circular: !0 }); N({ @@ -792,43 +814,43 @@ N({ }); N({ createInternalComparator: function() { - return g; + return v; } }); N({ strict: !0, createInternalComparator: function() { - return g; + return v; } }); N({ circular: !0, createInternalComparator: function() { - return g; + return v; } }); N({ circular: !0, createInternalComparator: function() { - return g; + return v; }, strict: !0 }); function N(t) { t === void 0 && (t = {}); - var e = t.circular, r = e === void 0 ? !1 : e, s = t.createInternalComparator, n = t.createState, o = t.strict, a = o === void 0 ? !1 : o, i = ke(t), c = Fe(i), h = s ? s(c) : Ke(c); - return We({ circular: r, comparator: c, createState: n, equals: h, strict: a }); + var e = t.circular, r = e === void 0 ? !1 : e, s = t.createInternalComparator, n = t.createState, o = t.strict, a = o === void 0 ? !1 : o, i = We(t), c = Fe(i), h = s ? s(c) : Ke(c); + return Le({ circular: r, comparator: c, createState: n, equals: h, strict: a }); } -function qt(t, e) { - return Le(t, e); +function St(t, e) { + return Ze(t, e); } -function B(t, e, r) { +function H(t, e, r) { return JSON.stringify(t, (n, o) => { let a = o; return e && (a = e(n, a)), a === void 0 && (a = null), a; }, r); } -function Ze(t, e) { +function Xe(t, e) { function r(n) { return Object.keys(n).forEach((o) => { n[o] === null ? n[o] = void 0 : typeof n[o] == "object" && (n[o] = r(n[o])); @@ -838,15 +860,15 @@ function Ze(t, e) { if (s !== null) return typeof s == "object" ? r(s) : s; } -function jt(t) { +function Ct(t) { try { - const e = B(t); - return e === B(Ze(e)); + const e = H(t); + return e === H(Xe(e)); } catch { return !1; } } -const Ct = (t) => t.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'").replace(/\//g, "/"), Xe = { +const Mt = (t) => t.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'").replace(/\//g, "/"), Qe = { title: "Platform.Bible menus", type: "object", properties: { @@ -1092,51 +1114,53 @@ const Ct = (t) => t.replace(/&/g, "&").replace(//g, " } } }; -Object.freeze(Xe); +Object.freeze(Qe); export { - et as AsyncVariable, - ut as DocumentCombinerEngine, - ue as FIRST_SCR_BOOK_NUM, - ce as FIRST_SCR_CHAPTER_NUM, - fe as FIRST_SCR_VERSE_NUM, - le as LAST_SCR_BOOK_NUM, - ct as PlatformEventEmitter, - lt as UnsubscriberAsyncList, - dt as aggregateUnsubscriberAsyncs, - mt as aggregateUnsubscribers, - bt as at, - Nt as charAt, + tt as AsyncVariable, + lt as DocumentCombinerEngine, + le as FIRST_SCR_BOOK_NUM, + fe as FIRST_SCR_CHAPTER_NUM, + he as FIRST_SCR_VERSE_NUM, + ce as LAST_SCR_BOOK_NUM, + ft as PlatformEventEmitter, + ct as UnsubscriberAsyncList, + bt as aggregateUnsubscriberAsyncs, + dt as aggregateUnsubscribers, + Nt as at, + gt as charAt, vt as codePointAt, - it as createSyncProxyForAsyncObject, - rt as debounce, + ut as createSyncProxyForAsyncObject, + st as debounce, O as deepClone, - qt as deepEqual, - Ze as deserialize, - gt as endsWith, - at as getAllObjectFunctionNames, - he as getChaptersForBook, - nt as getErrorMessage, - st as groupBy, - Ct as htmlEncode, - yt as includes, - Oe as indexOf, - jt as isSerializable, - re as isString, + St as deepEqual, + Xe as deserialize, + yt as endsWith, + it as getAllObjectFunctionNames, + pe as getChaptersForBook, + ot as getErrorMessage, + nt as groupBy, + Mt as htmlEncode, + wt as includes, + M as indexOf, + Ct as isSerializable, + se as isString, $e as lastIndexOf, d as length, - Xe as menuDocumentSchema, - tt as newGuid, - wt as normalize, - ft as offsetBook, - ht as offsetChapter, - pt as offsetVerse, - Et as padEnd, - Ot as padStart, - B as serialize, - $t as slice, - k as substring, - At as toArray, - oe as wait, - ot as waitForDuration + Qe as menuDocumentSchema, + rt as newGuid, + Et as normalize, + ht as offsetBook, + pt as offsetChapter, + mt as offsetVerse, + Ot as padEnd, + $t as padStart, + H as serialize, + At as slice, + qt as split, + jt as startsWith, + $ as substring, + Ae as toArray, + ae as wait, + at as waitForDuration }; //# sourceMappingURL=index.js.map diff --git a/lib/platform-bible-utils/dist/index.js.map b/lib/platform-bible-utils/dist/index.js.map index 4aa3369fd7..bc03f2537d 100644 --- a/lib/platform-bible-utils/dist/index.js.map +++ b/lib/platform-bible-utils/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * Finds the Unicode code point at the given index\n *\n * @param {string} string String to index\n * @param {number} index Position of the character to be returned in range of 0 to -length(string)\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > length(string) || index < -length(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * Always indexes string as a sequence of Unicode code points\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, empty string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > length(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to index\n * @param {number} index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {number | undefined} Non-negative integer representing the code point value of the\n * character at the given index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > length(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * Determines whether a string ends with the characters of this string. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Characters to search for at the end of the string\n * @param {number} [endPosition=length(string)] End position where searchString is expected to be\n * found. Default is `length(string)`\n * @returns {boolean} True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = length(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + length(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * Performs a case-sensitive search to determine if searchString is found in string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString String to search for\n * @param {string} [position=0] Position within the string to start searching for searchString.\n * Default is `0`\n * @returns {boolean} True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * Returns the index of the first occurrence of a given string. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The string to search for\n * @param {number} [position=0] Start of searching. Default is `0`\n * @returns {number} Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * Searches this string and returns the index of the last occurrence of the specified substring.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Substring to search for\n * @param {number} [position=+Infinity] The method returns the index of the last occurrence of the\n * specified substring at a position less than or equal to position. . Default is `+Infinity`\n * @returns {number} Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(\n string: string,\n searchString: string,\n position: number = +Infinity,\n): number {\n let validatedPosition = position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= length(string)) {\n validatedPosition = length(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, length(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * Returns the length of a string. This function handles Unicode code points instead of UTF-16\n * character codes.\n *\n * @param {string} string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function length(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * Returns the Unicode Normalization Form of this string.\n *\n * @param {string} string The starting string\n * @param {'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'} [form='NFC'] Form specifying the Unicode\n * Normalization Form. Default is `'NFC'`\n * @returns {string} A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within targetLength, it will be truncated. Default is `\" \"`\n * @returns {string} String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\nfunction correctSliceIndex(stringLength: number, index: number) {\n if (index > stringLength) return stringLength;\n if (index < -stringLength) return 0;\n if (index < 0) return index + stringLength;\n return index;\n}\n\n/**\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The starting string\n * @param {number} indexStart The index of the first character to include in the returned substring.\n * @param {number} indexEnd The index of the first character to exclude from the returned substring.\n * @returns {string} A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const stringLength: number = length(string);\n if (\n indexStart > stringLength ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(\n indexStart > 0 &&\n indexStart < stringLength &&\n indexEnd < 0 &&\n indexEnd > -stringLength\n )) ||\n indexEnd < -stringLength ||\n (indexStart < 0 && indexStart > -stringLength && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(stringLength, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The string to split\n * @param {string | RegExp} separator The pattern describing where each split should occur\n * @param {number} splitLimit Limit on the number of substrings to be included in the array. Splits\n * the string at each occurrence of specified separator, but stops when limit entries have been\n * placed in the array.\n * @returns {string[] | undefined} An array of strings, split at each point where separator occurs\n * in the starting string. Returns undefined if separator is not found in string.\n */\nexport function split(\n string: string,\n separator: string | RegExp,\n splitLimit?: number,\n): string[] | undefined {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !separator.flags.includes('g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return undefined;\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = length(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate. This function handles Unicode code points instead of UTF-16 character\n * codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The characters to be searched for at the start of this string.\n * @param {number} [position=0] The start position at which searchString is expected to be found\n * (the index of searchString's first character). Default is `0`\n * @returns {boolean} True if the given characters are found at the beginning of the string,\n * including when searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * Returns a substring by providing start and length. This function handles Unicode code points\n * instead of UTF-16 character codes. This function is not exported because it is considered\n * deprecated, however it is still useful as a local helper function.\n *\n * @param {string} string String to be divided\n * @param {number} [begin=Start of string] Start position. Default is `Start of string`\n * @param {number} [len=String length minus start parameter] Length of result. Default is `String\n * length minus start parameter`. Default is `String length minus start parameter`\n * @returns {string} Substring from starting string\n */\nfunction substr(string: string, begin: number = 0, len: number = length(string) - begin): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * Returns a substring by providing start and end position. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to be divided\n * @param {string} begin Start position\n * @param {number} [end=End of string] End position. Default is `End of string`\n * @returns {string} Substring from starting string\n */\nexport function substring(\n string: string,\n begin?: number | undefined,\n end: number | undefined = length(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * Converts a string to an array of string characters. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param {string} string String to convert to array\n * @returns {string[]} An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","stringLength","slice","indexStart","indexEnd","newStart","newEnd","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","result","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","matchIndex","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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","x_google_ignoreList":[7,8,10]} \ No newline at end of file +{"version":3,"file":"index.js","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * Finds the Unicode code point at the given index\n *\n * @param {string} string String to index\n * @param {number} index Position of the character to be returned in range of 0 to -length(string)\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > length(string) || index < -length(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * Always indexes string as a sequence of Unicode code points\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, empty string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > length(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to index\n * @param {number} index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {number | undefined} Non-negative integer representing the code point value of the\n * character at the given index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > length(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * Determines whether a string ends with the characters of this string. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Characters to search for at the end of the string\n * @param {number} [endPosition=length(string)] End position where searchString is expected to be\n * found. Default is `length(string)`\n * @returns {boolean} True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = length(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + length(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * Performs a case-sensitive search to determine if searchString is found in string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString String to search for\n * @param {string} [position=0] Position within the string to start searching for searchString.\n * Default is `0`\n * @returns {boolean} True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * Returns the index of the first occurrence of a given string. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The string to search for\n * @param {number} [position=0] Start of searching. Default is `0`\n * @returns {number} Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * Searches this string and returns the index of the last occurrence of the specified substring.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Substring to search for\n * @param {number} [position=+Infinity] The method returns the index of the last occurrence of the\n * specified substring at a position less than or equal to position. . Default is `+Infinity`\n * @returns {number} Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(\n string: string,\n searchString: string,\n position: number = +Infinity,\n): number {\n let validatedPosition = position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= length(string)) {\n validatedPosition = length(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, length(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * Returns the length of a string. This function handles Unicode code points instead of UTF-16\n * character codes.\n *\n * @param {string} string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function length(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * Returns the Unicode Normalization Form of this string.\n *\n * @param {string} string The starting string\n * @param {'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'} [form='NFC'] Form specifying the Unicode\n * Normalization Form. Default is `'NFC'`\n * @returns {string} A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within targetLength, it will be truncated. Default is `\" \"`\n * @returns {string} String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\nfunction correctSliceIndex(stringLength: number, index: number) {\n if (index > stringLength) return stringLength;\n if (index < -stringLength) return 0;\n if (index < 0) return index + stringLength;\n return index;\n}\n\n/**\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The starting string\n * @param {number} indexStart The index of the first character to include in the returned substring.\n * @param {number} indexEnd The index of the first character to exclude from the returned substring.\n * @returns {string} A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const stringLength: number = length(string);\n if (\n indexStart > stringLength ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(\n indexStart > 0 &&\n indexStart < stringLength &&\n indexEnd < 0 &&\n indexEnd > -stringLength\n )) ||\n indexEnd < -stringLength ||\n (indexStart < 0 && indexStart > -stringLength && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(stringLength, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The string to split\n * @param {string | RegExp} separator The pattern describing where each split should occur\n * @param {number} splitLimit Limit on the number of substrings to be included in the array. Splits\n * the string at each occurrence of specified separator, but stops when limit entries have been\n * placed in the array.\n * @returns {string[] | undefined} An array of strings, split at each point where separator occurs\n * in the starting string. Returns undefined if separator is not found in string.\n */\nexport function split(\n string: string,\n separator: string | RegExp,\n splitLimit?: number,\n): string[] | undefined {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !separator.flags.includes('g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return undefined;\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = length(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate. This function handles Unicode code points instead of UTF-16 character\n * codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The characters to be searched for at the start of this string.\n * @param {number} [position=0] The start position at which searchString is expected to be found\n * (the index of searchString's first character). Default is `0`\n * @returns {boolean} True if the given characters are found at the beginning of the string,\n * including when searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * Returns a substring by providing start and length. This function handles Unicode code points\n * instead of UTF-16 character codes. This function is not exported because it is considered\n * deprecated, however it is still useful as a local helper function.\n *\n * @param {string} string String to be divided\n * @param {number} [begin=Start of string] Start position. Default is `Start of string`\n * @param {number} [len=String length minus start parameter] Length of result. Default is `String\n * length minus start parameter`. Default is `String length minus start parameter`\n * @returns {string} Substring from starting string\n */\nfunction substr(string: string, begin: number = 0, len: number = length(string) - begin): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * Returns a substring by providing start and end position. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to be divided\n * @param {string} begin Start position\n * @param {number} [end=End of string] End position. Default is `End of string`\n * @returns {string} Substring from starting string\n */\nexport function substring(\n string: string,\n begin?: number | undefined,\n end: number | undefined = length(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * Converts a string to an array of string characters. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param {string} string String to convert to array\n * @returns {string[]} An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","stringLength","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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","x_google_ignoreList":[7,8,10]} \ No newline at end of file diff --git a/lib/platform-bible-utils/src/index.ts b/lib/platform-bible-utils/src/index.ts index e6c94f4935..8ec1e7e7a7 100644 --- a/lib/platform-bible-utils/src/index.ts +++ b/lib/platform-bible-utils/src/index.ts @@ -31,20 +31,22 @@ export { createSyncProxyForAsyncObject, } from './util'; export { - indexOf, - substring, - length, - toArray, - padStart, - padEnd, - normalize, at, charAt, codePointAt, endsWith, includes, + indexOf, lastIndexOf, + length, + normalize, + padEnd, + padStart, slice, + split, + startsWith, + substring, + toArray, } from './string-util'; export { default as deepEqual } from './equality-checking'; export { serialize, deserialize, isSerializable, htmlEncode } from './serialization'; From 6c5b5f8885b1a9d3f78b4408faa01a26532b242a Mon Sep 17 00:00:00 2001 From: Rolf Heij Date: Mon, 19 Feb 2024 15:42:45 -0500 Subject: [PATCH 16/22] Changes usages of String.Prototype to string util --- lib/papi-dts/edit-papi-d-ts.ts | 8 ++++---- .../services/asset-retrieval.service.ts | 3 ++- .../services/extension-storage.service.ts | 3 ++- src/extension-host/services/extension.service.ts | 13 ++++++++----- .../services/extension-asset-protocol.service.ts | 6 +++--- src/main/services/extension-host.service.ts | 2 +- src/node/models/execution-token.model.ts | 3 ++- src/node/services/execution-token.service.ts | 5 +++-- src/node/utils/command-line.util.ts | 6 ++++-- src/node/utils/util.ts | 2 +- src/renderer/services/web-view.service-host.ts | 3 ++- src/shared/models/data-provider.model.ts | 12 +++++++++--- src/shared/services/data-provider.service.ts | 11 ++++++----- src/shared/services/logger.service.ts | 2 +- src/shared/services/network-object.service.ts | 7 ++++--- src/shared/services/network.service.ts | 3 ++- src/shared/utils/menu-document-combiner.ts | 13 +++++++------ src/shared/utils/util.ts | 6 +++--- 18 files changed, 64 insertions(+), 44 deletions(-) diff --git a/lib/papi-dts/edit-papi-d-ts.ts b/lib/papi-dts/edit-papi-d-ts.ts index 1dd544071e..6a6bce68b4 100644 --- a/lib/papi-dts/edit-papi-d-ts.ts +++ b/lib/papi-dts/edit-papi-d-ts.ts @@ -139,13 +139,13 @@ Record = tsconfig; // Replace all dynamic imports for @ path aliases with the path alias without @ if (paths) { Object.keys(paths).forEach((path) => { - if (!path.startsWith('@')) return; + if (!path.startsWith('@')) return; // TODO: Change startsWith? - const asteriskIndex = path.indexOf('*'); + const asteriskIndex = path.indexOf('*'); // TODO: Change indexOf? // Get the path alias without the * at the end but with the @ - const pathAlias = path.substring(0, asteriskIndex); + const pathAlias = path.substring(0, asteriskIndex); // TODO: Change substring? // Get the path alias without the @ at the start - const pathAliasNoAt = pathAlias.substring(1); + const pathAliasNoAt = pathAlias.substring(1); // TODO: Change substring? // Regex-escaped path alias without @ to be used in a regex string const pathAliasNoAtRegex = escapeStringRegexp(pathAliasNoAt); diff --git a/src/extension-host/services/asset-retrieval.service.ts b/src/extension-host/services/asset-retrieval.service.ts index 7ccbb13de8..e69fc9ac9f 100644 --- a/src/extension-host/services/asset-retrieval.service.ts +++ b/src/extension-host/services/asset-retrieval.service.ts @@ -1,10 +1,11 @@ import { readFileBinary } from '@node/services/node-file-system.service'; import { buildExtensionPathFromName } from '@extension-host/services/extension-storage.service'; +import { startsWith } from 'platform-bible-utils'; export type GetAsset = typeof getAsset; export default async function getAsset(extensionName: string, assetName: string): Promise { - if (!assetName.startsWith('assets/') && !assetName.startsWith('assets\\')) { + if (!startsWith(assetName, 'assets/') && !startsWith(assetName, 'assets\\')) { throw Error('Requests are limited to files in the "assets" directory'); } const pathToAsset = buildExtensionPathFromName(extensionName, assetName); diff --git a/src/extension-host/services/extension-storage.service.ts b/src/extension-host/services/extension-storage.service.ts index fc395af602..4038a00ada 100644 --- a/src/extension-host/services/extension-storage.service.ts +++ b/src/extension-host/services/extension-storage.service.ts @@ -8,6 +8,7 @@ import { import { ExecutionToken } from '@node/models/execution-token.model'; import executionTokenService from '@node/services/execution-token.service'; import { Buffer } from 'buffer'; +import { length } from 'platform-bible-utils'; // #region Functions that need to be called by other services to initialize this service @@ -66,7 +67,7 @@ export function buildExtensionPathFromName(extensionName: string, fileName: stri function buildUserDataPath(token: ExecutionToken, key: string): string { if (!executionTokenService.tokenIsValid(token)) throw new Error('Invalid token'); const subDir: string = sanitizeDirectoryName(token.name); - if (!subDir || subDir.length === 0) throw new Error('Bad extension name'); + if (!subDir || length(subDir) === 0) throw new Error('Bad extension name'); // From https://base64.guru/standards/base64url, the purpose of "base64url" encoding is // "the ability to use the encoding result as filename or URL address" diff --git a/src/extension-host/services/extension.service.ts b/src/extension-host/services/extension.service.ts index 55dc02c5bf..e7f5f83b02 100644 --- a/src/extension-host/services/extension.service.ts +++ b/src/extension-host/services/extension.service.ts @@ -21,6 +21,9 @@ import { UnsubscriberAsync, UnsubscriberAsyncList, deserialize, + length, + startsWith, + slice, } from 'platform-bible-utils'; import LogError from '@shared/log-error.model'; import { ExtensionManifest } from '@extension-host/extension-types/extension-manifest.model'; @@ -117,7 +120,7 @@ function parseManifest(extensionManifestJson: string): ExtensionManifest { throw new Error('Extension name must not include `..`!'); // Replace ts with js so people can list their source code ts name but run the transpiled js if (extensionManifest.main && extensionManifest.main.toLowerCase().endsWith('.ts')) - extensionManifest.main = `${extensionManifest.main.slice(0, -3)}.js`; + extensionManifest.main = `${slice(extensionManifest.main, 0, -3)}.js`; return extensionManifest; } @@ -228,7 +231,7 @@ async function getExtensionUrisToLoad(): Promise { const extensionFolderPromises = commandLineExtensionDirectories .map((extensionDirPath) => { const extensionFolder = extensionDirPath.endsWith(MANIFEST_FILE_NAME) - ? extensionDirPath.slice(0, -MANIFEST_FILE_NAME.length) + ? slice(extensionDirPath, 0, -length(MANIFEST_FILE_NAME)) : extensionDirPath; return extensionFolder; }) @@ -456,7 +459,7 @@ async function cacheExtensionTypeDeclarations(extensionInfos: ExtensionInfo[]) { // with version number or something if (!extensionDtsInfo) extensionDtsInfo = dtsInfos.find((dtsInfo) => - dtsInfo.base.startsWith(extensionInfo.name), + startsWith(dtsInfo.base, extensionInfo.name), ); // Try using a dts file whose name is `index.d.ts` @@ -473,7 +476,7 @@ async function cacheExtensionTypeDeclarations(extensionInfos: ExtensionInfo[]) { // If the dts file has stuff after the extension name, we want to use it so they can suffix a // version number or something - if (extensionDtsInfo.base.startsWith(extensionInfo.name)) + if (startsWith(extensionDtsInfo.base, extensionInfo.name)) extensionDtsBaseDestination = extensionDtsInfo.base; // Put the extension's dts in the types cache in its own folder @@ -486,7 +489,7 @@ async function cacheExtensionTypeDeclarations(extensionInfos: ExtensionInfo[]) { userExtensionTypesCacheUri, // Folder name must match module name which we are assuming is the same as the name of the // .d.ts file, so get the .d.ts file's name and use it as the folder name - extensionDtsBaseDestination.slice(0, -'.d.ts'.length), + slice(extensionDtsBaseDestination, 0, -length('.d.ts')), 'index.d.ts', ); diff --git a/src/main/services/extension-asset-protocol.service.ts b/src/main/services/extension-asset-protocol.service.ts index 7f58a89ca3..f75d540551 100644 --- a/src/main/services/extension-asset-protocol.service.ts +++ b/src/main/services/extension-asset-protocol.service.ts @@ -1,7 +1,7 @@ import { protocol } from 'electron'; import { StatusCodes } from 'http-status-codes'; import extensionAssetService from '@shared/services/extension-asset.service'; -import { indexOf, substring } from 'platform-bible-utils'; +import { indexOf, length, substring } from 'platform-bible-utils'; /** Here some of the most common MIME types that we expect to handle */ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types @@ -68,7 +68,7 @@ const initialize = () => { // 2) Use request headers to pass along the extension name so extension code doesn't have to embed its name in URLs. // Remove "papi-extension://" from the front of the URL - const uri: string = substring(request.url, `${protocolName}://`.length); + const uri: string = substring(request.url, length(`${protocolName}://`)); // There have to be at least 2 parts to the URI divided by a slash if (!uri.includes('/')) { @@ -86,7 +86,7 @@ const initialize = () => { // allowed in URLs. So let's decode both of them before passing them to the extension host. extension = decodeURIComponent(extension); asset = decodeURIComponent(asset); - if (extension.length > 100 || asset.length > 100) { + if (length(extension) > 100 || length(asset) > 100) { return errorResponse(request.url, StatusCodes.BAD_REQUEST); } diff --git a/src/main/services/extension-host.service.ts b/src/main/services/extension-host.service.ts index e89d94c915..3b099d95ec 100644 --- a/src/main/services/extension-host.service.ts +++ b/src/main/services/extension-host.service.ts @@ -26,7 +26,7 @@ const closePromise: Promise = new Promise((resolve) => { function logProcessError(message: unknown) { let msg = message?.toString() || ''; if (msg.includes(WARN_TAG)) { - msg = msg.split(WARN_TAG).join(''); + msg = msg.split(WARN_TAG).join(''); // TODO: Can't use our new split here for some reason logger.warn(formatLog(msg, EXTENSION_HOST_NAME, 'warning')); } else logger.error(formatLog(msg, EXTENSION_HOST_NAME, 'error')); } diff --git a/src/node/models/execution-token.model.ts b/src/node/models/execution-token.model.ts index ab3744257b..9914bbb9dc 100644 --- a/src/node/models/execution-token.model.ts +++ b/src/node/models/execution-token.model.ts @@ -1,5 +1,6 @@ import crypto from 'crypto'; import { createNonce } from '@node/utils/crypto-util'; +import { length } from 'platform-bible-utils'; /** For now this is just for extensions, but maybe we will want to expand this in the future */ export type ExecutionTokenType = 'extension'; @@ -12,7 +13,7 @@ export class ExecutionToken { constructor(tokenType: ExecutionTokenType, name: string) { if (!tokenType) throw new Error('token type must be defined'); - if (!name || name.length < 1) throw new Error('name must be a string of length > 0'); + if (!name || length(name) < 1) throw new Error('name must be a string of length > 0'); this.type = tokenType; this.name = name; diff --git a/src/node/services/execution-token.service.ts b/src/node/services/execution-token.service.ts index 70fcfcb25c..cae94fb62d 100644 --- a/src/node/services/execution-token.service.ts +++ b/src/node/services/execution-token.service.ts @@ -1,10 +1,11 @@ import { ExecutionToken, ExecutionTokenType } from '@node/models/execution-token.model'; +import { length } from 'platform-bible-utils'; const tokenMap = new Map(); function getMapKey(name: string, tokenType: ExecutionTokenType = 'extension'): string { - if (!name || name.length < 1) throw new Error('name must be defined'); - if (!tokenType || tokenType.length < 1) throw new Error('type must be defined'); + if (!name || length(name) < 1) throw new Error('name must be defined'); + if (!tokenType || length(tokenType) < 1) throw new Error('type must be defined'); return `${tokenType}:${name}`; } diff --git a/src/node/utils/command-line.util.ts b/src/node/utils/command-line.util.ts index 71bddefecd..07f7183bcc 100644 --- a/src/node/utils/command-line.util.ts +++ b/src/node/utils/command-line.util.ts @@ -1,4 +1,6 @@ -/** All command line arguments mapped from argument type to array of aliases for the argument */ +import { startsWith } from 'platform-bible-utils'; + +/** All command line arguments mapped from argument type to array of aliases for the argument */ type CommandLineArgumentAliases = { [argument in COMMAND_LINE_ARGS]: string[]; }; @@ -39,7 +41,7 @@ export const commandLineArgumentsAliases: CommandLineArgumentAliases = { export function findNextCommandLineArgumentIndex(currentArgIndex: number) { let endOfExtensionsIndex = process.argv.length; for (let i = currentArgIndex + 1; i < process.argv.length; i++) - if (process.argv[i].startsWith('-')) { + if (startsWith(process.argv[i], '-')) { endOfExtensionsIndex = i; break; } diff --git a/src/node/utils/util.ts b/src/node/utils/util.ts index b30f60c287..6f4438ebbc 100644 --- a/src/node/utils/util.ts +++ b/src/node/utils/util.ts @@ -62,7 +62,7 @@ function getPathInfoFromUri(uri: Uri): { scheme: string; uriPath: string } { // Add app scheme to the uri if it doesn't have one const fullUri = uri.includes(PROTOCOL_PART) ? uri : `${APP_SCHEME}${PROTOCOL_PART}${uri}`; - const [scheme, uriPath] = fullUri.split(PROTOCOL_PART); + const [scheme, uriPath] = fullUri.split(PROTOCOL_PART); // TODO: Our new split doesn't support this return return { scheme, uriPath, diff --git a/src/renderer/services/web-view.service-host.ts b/src/renderer/services/web-view.service-host.ts index 4b053b1dd7..d2cabf8b87 100644 --- a/src/renderer/services/web-view.service-host.ts +++ b/src/renderer/services/web-view.service-host.ts @@ -14,6 +14,7 @@ import { newGuid, indexOf, substring, + startsWith, } from 'platform-bible-utils'; import { newNonce } from '@shared/utils/util'; import { createNetworkEventEmitter } from '@shared/services/network.service'; @@ -822,7 +823,7 @@ export const getWebView = async ( let { allowedFrameSources } = webView; if (contentType !== WebViewContentType.URL && allowedFrameSources) allowedFrameSources = allowedFrameSources.filter( - (hostValue) => hostValue.startsWith('https:') || hostValue.startsWith('papi-extension:'), + (hostValue) => startsWith(hostValue, 'https:') || startsWith(hostValue, 'papi-extension:'), ); // Validate the WebViewDefinition to make sure it is acceptable diff --git a/src/shared/models/data-provider.model.ts b/src/shared/models/data-provider.model.ts index e54f787f7b..5693936d8f 100644 --- a/src/shared/models/data-provider.model.ts +++ b/src/shared/models/data-provider.model.ts @@ -1,4 +1,10 @@ -import { UnsubscriberAsync, PlatformEventHandler, substring } from 'platform-bible-utils'; +import { + length, + UnsubscriberAsync, + PlatformEventHandler, + substring, + startsWith, +} from 'platform-bible-utils'; import { NetworkableObject } from '@shared/models/network-object.model'; /** Various options to adjust how the data provider subscriber emits updates */ @@ -230,12 +236,12 @@ const dataProviderFunctionPrefixes = ['set', 'get', 'subscribe']; export function getDataProviderDataTypeFromFunctionName< TDataTypes extends DataProviderDataTypes = DataProviderDataTypes, >(fnName: string) { - const fnPrefix = dataProviderFunctionPrefixes.find((prefix) => fnName.startsWith(prefix)); + const fnPrefix = dataProviderFunctionPrefixes.find((prefix) => startsWith(fnName, prefix)); if (!fnPrefix) throw new Error(`${fnName} is not a data provider data type function`); // Assert the expected return type. // eslint-disable-next-line no-type-assertion/no-type-assertion - return substring(fnName, fnPrefix.length) as DataTypeNames; + return substring(fnName, length(fnPrefix)) as DataTypeNames; } export default DataProviderInternal; diff --git a/src/shared/services/data-provider.service.ts b/src/shared/services/data-provider.service.ts index 7bb158c582..7e12465401 100644 --- a/src/shared/services/data-provider.service.ts +++ b/src/shared/services/data-provider.service.ts @@ -21,6 +21,7 @@ import { isString, CannotHaveOnDidDispose, AsyncVariable, + startsWith, } from 'platform-bible-utils'; import * as networkService from '@shared/services/network.service'; import { serializeRequestType } from '@shared/utils/util'; @@ -264,7 +265,7 @@ function createDataProviderProxy( DataProviderInternal[any] | undefined; // If they want a subscriber, build a subscribe function specific to the data type used - if (isString(prop) && prop.startsWith('subscribe')) { + if (isString(prop) && startsWith(prop, 'subscribe')) { const dataType = getDataProviderDataTypeFromFunctionName(prop); // Subscribe to run the callback when data changes. Also immediately calls callback with the current value @@ -312,7 +313,7 @@ function createDataProviderProxy( // These request functions should not have to change after they're set for the first time. if ( isString(prop) && - (prop.startsWith('get') || prop.startsWith('subscribe') || prop === 'notifyUpdate') && + (startsWith(prop, 'get') || startsWith(prop, 'subscribe') || prop === 'notifyUpdate') && (prop in obj || prop in dataProviderInternal) ) return false; @@ -328,7 +329,7 @@ function createDataProviderProxy( has(obj, prop) { if (prop in dataProviderInternal) return true; // This proxy provides subscribe methods, so make sure they seem to exist - if (isString(prop) && prop.startsWith('subscribe')) return true; + if (isString(prop) && startsWith(prop, 'subscribe')) return true; return prop in obj; }, }, @@ -554,8 +555,8 @@ function buildDataProvider( // If the function was decorated with @ignore, do not consider it a special function if (dataProviderEngineUntyped[fnName].isIgnored) return 'other'; - if (fnName.startsWith('get')) return 'get'; - if (fnName.startsWith('set')) return 'set'; + if (startsWith(fnName, 'get')) return 'get'; + if (startsWith(fnName, 'set')) return 'set'; return 'other'; }, (fnName, fnType) => { diff --git a/src/shared/services/logger.service.ts b/src/shared/services/logger.service.ts index 1db42be1f1..7977bc0354 100644 --- a/src/shared/services/logger.service.ts +++ b/src/shared/services/logger.service.ts @@ -66,7 +66,7 @@ function identifyCaller(): string | undefined { const { stack } = new Error(); if (!stack) return undefined; let details: parsedErrorLine; - const lines = stack.split('\n'); + const lines = stack.split('\n'); // TODO: Our new split doesn't work here // Start at 3 to skip the "Error" line, this function's stack frame, and this function's caller for (let lineNumber = 3; lineNumber < lines.length; lineNumber += 1) { // Skip over all logging library frames to get to the real call diff --git a/src/shared/services/network-object.service.ts b/src/shared/services/network-object.service.ts index cdc28bc2bb..36e250faf5 100644 --- a/src/shared/services/network-object.service.ts +++ b/src/shared/services/network-object.service.ts @@ -13,6 +13,7 @@ import { isString, CanHaveOnDidDispose, MutexMap, + startsWith, } from 'platform-bible-utils'; import { NetworkObject, @@ -198,7 +199,7 @@ const createRemoteProxy = ( // If the prop requested is a symbol, that doesn't work over the network. Reject if (!isString(key)) return undefined; // Don't create remote proxies for events - if (key.startsWith('on')) return undefined; + if (startsWith(key, 'on')) return undefined; // If the local network object doesn't have the property, build a request for it const requestFunction = (...args: unknown[]) => @@ -247,7 +248,7 @@ const createLocalProxy = ( // Block access to constructors and dispose if (key === 'constructor' || key === 'dispose') return undefined; // Don't proxy events - if (isString(key) && key.startsWith('on')) return undefined; + if (isString(key) && startsWith(key, 'on')) return undefined; return Reflect.get(target, key, objectBeingSet); }, @@ -267,7 +268,7 @@ function createNetworkObjectDetails( objectFunctionNames.delete('dispose'); objectFunctionNames.forEach((functionName) => { // If we come up with some better way to identify events, we can remove this and related checks - if (functionName.startsWith('on')) objectFunctionNames.delete(functionName); + if (startsWith(functionName, 'on')) objectFunctionNames.delete(functionName); }); return { id, diff --git a/src/shared/services/network.service.ts b/src/shared/services/network.service.ts index e512ec206a..e02b0b6b28 100644 --- a/src/shared/services/network.service.ts +++ b/src/shared/services/network.service.ts @@ -15,6 +15,7 @@ import { } from '@shared/data/internal-connection.model'; import { aggregateUnsubscriberAsyncs, + length, UnsubscriberAsync, getErrorMessage, wait, @@ -148,7 +149,7 @@ function validateCommandFormatting(commandName: string) { throw new Error( `Invalid command name ${commandName}: must have non-empty string before a period`, ); - if (periodIndex >= commandName.length - 1) + if (periodIndex >= length(commandName) - 1) throw new Error( `Invalid command name ${commandName}: must have a non-empty string after a period`, ); diff --git a/src/shared/utils/menu-document-combiner.ts b/src/shared/utils/menu-document-combiner.ts index 8ce812c6d7..0901759371 100644 --- a/src/shared/utils/menu-document-combiner.ts +++ b/src/shared/utils/menu-document-combiner.ts @@ -14,6 +14,7 @@ import { ReferencedItem, LocalizeKey, menuDocumentSchema, + startsWith, } from 'platform-bible-utils'; import Ajv2020 from 'ajv/dist/2020'; import localizationService from '@shared/services/localization.service'; @@ -49,7 +50,7 @@ function checkNewColumns( if (!newColumns) return; Object.getOwnPropertyNames(newColumns).forEach((columnName: string) => { if (!columnName) return; - if (!columnName.startsWith(namePrefix)) + if (!startsWith(columnName, namePrefix)) throw new Error(`Column name ${columnName} does not start with ${namePrefix}`); if (!!currentColumns && currentColumns.isExtensible !== true) throw new Error(`Cannot add new column ${columnName} because isExtensible is not set`); @@ -67,7 +68,7 @@ function checkNewGroups( // eslint-disable-next-line no-type-assertion/no-type-assertion const group = newGroups[groupName as ReferencedItem]; if (!group) return; - if (!groupName.startsWith(namePrefix)) + if (!startsWith(groupName, namePrefix)) throw new Error(`Group name ${groupName} does not start with ${namePrefix}`); if ('column' in group && group.column) { if (!currentColumns) return; @@ -76,7 +77,7 @@ function checkNewGroups( throw new Error(`Cannot add new group ${groupName} because isExtensible is not set`); } else if ('menuItem' in group && group.menuItem) { const targetMenuItemName = group.menuItem; - if (!targetMenuItemName.startsWith(namePrefix)) + if (!startsWith(targetMenuItemName, namePrefix)) throw new Error(`Cannot add new group ${groupName} to a submenu owned by something else`); } }); @@ -90,10 +91,10 @@ function checkNewMenuItems( if (!newMenuItems) return; newMenuItems.forEach((menuItem) => { if (!menuItem) return; - if ('id' in menuItem && menuItem.id && !menuItem.id.startsWith(namePrefix)) + if ('id' in menuItem && menuItem.id && !startsWith(menuItem.id, namePrefix)) throw new Error(`Menu item ID ${menuItem.id} does not start with ${namePrefix}`); const targetGroupName = menuItem.group; - if (targetGroupName && !targetGroupName.startsWith(namePrefix)) { + if (targetGroupName && !startsWith(targetGroupName, namePrefix)) { if (!currentGroups) return; const targetGroup = currentGroups[targetGroupName]; if (targetGroup.isExtensible !== true) @@ -314,7 +315,7 @@ export default class MenuDocumentCombiner extends DocumentCombinerEngine { const currentWebView = currentMenus?.webViewMenus[webViewName as ReferencedItem]; /* eslint-enable no-type-assertion/no-type-assertion */ - if (!currentWebView && !webViewName.startsWith(namePrefix)) + if (!currentWebView && !startsWith(webViewName, namePrefix)) throw new Error(`Cannot add a new web view unless it starts with ${namePrefix}`); checkNewColumns(newWebView?.topMenu?.columns, namePrefix, currentWebView?.topMenu?.columns); diff --git a/src/shared/utils/util.ts b/src/shared/utils/util.ts index 33f793c9fe..5608381224 100644 --- a/src/shared/utils/util.ts +++ b/src/shared/utils/util.ts @@ -1,8 +1,8 @@ import { ProcessType } from '@shared/global-this.model'; -import { UnsubscriberAsync, indexOf, isString, substring } from 'platform-bible-utils'; +import { UnsubscriberAsync, indexOf, isString, length, substring } from 'platform-bible-utils'; const NONCE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; -const NONCE_CHARS_LENGTH = NONCE_CHARS.length; +const NONCE_CHARS_LENGTH = length(NONCE_CHARS); /** * Create a nonce that is at least 128 bits long and should be (is not currently) cryptographically * random. See nonce spec at https://w3c.github.io/webappsec-csp/#security-nonces @@ -175,7 +175,7 @@ export function deserializeRequestType(requestType: SerializedRequestType): Requ if (!requestType) throw new Error('deserializeRequestType: must be a non-empty string'); const colonIndex = indexOf(requestType, REQUEST_TYPE_SEPARATOR); - if (colonIndex <= 0 || colonIndex >= requestType.length - 1) + if (colonIndex <= 0 || colonIndex >= length(requestType) - 1) throw new Error( `deserializeRequestType: Must have two parts divided by a ${REQUEST_TYPE_SEPARATOR} (${requestType})`, ); From ef9c325a03a66989cfa8c87dada01ed24f3512e7 Mon Sep 17 00:00:00 2001 From: Jolie Rabideau Date: Mon, 19 Feb 2024 16:18:11 -0500 Subject: [PATCH 17/22] change uses of string.prototype to new string utils --- extensions/lib/add-remotes.ts | 5 +- extensions/lib/update-from-templates.ts | 11 +- lib/platform-bible-utils/dist/index.cjs | 2 +- lib/platform-bible-utils/dist/index.cjs.map | 2 +- lib/platform-bible-utils/dist/index.js | 166 +++++++++--------- lib/platform-bible-utils/dist/index.js.map | 2 +- lib/platform-bible-utils/src/string-util.ts | 2 +- .../services/extension-storage.service.ts | 4 +- .../services/extension.service.ts | 14 +- .../services/project-lookup.service-host.ts | 4 +- .../extension-asset-protocol.service.ts | 6 +- src/main/services/extension-host.service.ts | 4 +- src/node/utils/util.ts | 3 +- src/shared/services/data-provider.service.ts | 3 +- src/shared/services/logger.service.ts | 5 +- src/shared/utils/util.ts | 11 +- stop-processes.mjs | 9 +- 17 files changed, 133 insertions(+), 120 deletions(-) diff --git a/extensions/lib/add-remotes.ts b/extensions/lib/add-remotes.ts index 1c69a5455d..769ff092b9 100644 --- a/extensions/lib/add-remotes.ts +++ b/extensions/lib/add-remotes.ts @@ -1,3 +1,4 @@ +import { includes } from 'platform-bible-utils'; import { ERROR_STRINGS, MULTI_TEMPLATE_NAME, @@ -13,7 +14,7 @@ import { try { await execGitCommand(`git remote add ${MULTI_TEMPLATE_NAME} ${MULTI_TEMPLATE_URL}`); } catch (e) { - if (e.toString().toLowerCase().includes(ERROR_STRINGS.multiRemoteExists.toLowerCase())) + if (includes(e.toString().toLowerCase(), ERROR_STRINGS.multiRemoteExists.toLowerCase())) console.log(`Remote ${MULTI_TEMPLATE_NAME} already exists. This is likely not a problem.`); else { console.error(`Error on adding remote ${MULTI_TEMPLATE_NAME}: ${e}`); @@ -25,7 +26,7 @@ import { try { await execGitCommand(`git remote add ${SINGLE_TEMPLATE_NAME} ${SINGLE_TEMPLATE_URL}`); } catch (e) { - if (e.toString().toLowerCase().includes(ERROR_STRINGS.singleRemoteExists.toLowerCase())) + if (includes(e.toString().toLowerCase(), ERROR_STRINGS.singleRemoteExists.toLowerCase())) console.log(`Remote ${SINGLE_TEMPLATE_NAME} already exists. This is likely not a problem.`); else { console.error(`Error on adding remote ${SINGLE_TEMPLATE_NAME}: ${e}`); diff --git a/extensions/lib/update-from-templates.ts b/extensions/lib/update-from-templates.ts index 2ea3c9dfe5..49983019b6 100644 --- a/extensions/lib/update-from-templates.ts +++ b/extensions/lib/update-from-templates.ts @@ -1,3 +1,4 @@ +import { includes } from 'platform-bible-utils'; import { ERROR_STRINGS, MULTI_TEMPLATE_BRANCH, @@ -62,12 +63,10 @@ import { ExtensionInfo, getExtensions, subtreeRootFolder } from '../webpack/webp extensionsBasedOnTemplate.push(ext); } catch (e) { if ( - e - .toString() - .toLowerCase() - .includes( - ERROR_STRINGS.subtreeNeverAdded.replace('{0}', ext.dirPathOSIndependent).toLowerCase(), - ) + includes( + e.toString().toLowerCase(), + ERROR_STRINGS.subtreeNeverAdded.replace('{0}', ext.dirPathOSIndependent).toLowerCase(), + ) ) // If this folder isn't a subtree, it may be intentionally not based on the template. Continue console.warn( diff --git a/lib/platform-bible-utils/dist/index.cjs b/lib/platform-bible-utils/dist/index.cjs index 6db422b9d5..fad4d40069 100644 --- a/lib/platform-bible-utils/dist/index.cjs +++ b/lib/platform-bible-utils/dist/index.cjs @@ -1,2 +1,2 @@ -"use strict";var pe=Object.defineProperty;var me=(t,e,r)=>e in t?pe(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var p=(t,e,r)=>(me(t,typeof e!="symbol"?e+"":e,r),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const de=require("async-mutex");class be{constructor(e,r=1e4){p(this,"variableName");p(this,"promiseToValue");p(this,"resolver");p(this,"rejecter");this.variableName=e,this.promiseToValue=new Promise((s,n)=>{this.resolver=s,this.rejecter=n}),r>0&&setTimeout(()=>{this.rejecter&&(this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`),this.complete())},r),Object.seal(this)}get promise(){return this.promiseToValue}get hasSettled(){return Object.isFrozen(this)}resolveToValue(e,r=!1){if(this.resolver)console.debug(`${this.variableName} is being resolved now`),this.resolver(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent resolution of ${this.variableName}`)}}rejectWithReason(e,r=!1){if(this.rejecter)console.debug(`${this.variableName} is being rejected now`),this.rejecter(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent rejection of ${this.variableName}`)}}complete(){this.resolver=void 0,this.rejecter=void 0,Object.freeze(this)}}function ge(){return"00-0-4-1-000".replace(/[^-]/g,t=>((Math.random()+~~t)*65536>>t).toString(16).padStart(4,"0"))}function F(t){return typeof t=="string"||t instanceof String}function E(t){return JSON.parse(JSON.stringify(t))}function Ne(t,e=300){if(F(t))throw new Error("Tried to debounce a string! Could be XSS");let r;return(...s)=>{clearTimeout(r),r=setTimeout(()=>t(...s),e)}}function ve(t,e,r){const s=new Map;return t.forEach(n=>{const o=e(n),a=s.get(o),i=r?r(n,o):n;a?a.push(i):s.set(o,[i])}),s}function ye(t){return typeof t=="object"&&t!==null&&"message"in t&&typeof t.message=="string"}function we(t){if(ye(t))return t;try{return new Error(JSON.stringify(t))}catch{return new Error(String(t))}}function Ee(t){return we(t).message}function H(t){return new Promise(e=>setTimeout(e,t))}function Oe(t,e){const r=H(e).then(()=>{});return Promise.any([r,t()])}function $e(t,e="obj"){const r=new Set;Object.getOwnPropertyNames(t).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e} due to error: ${o}`)}});let s=Object.getPrototypeOf(t);for(;s&&Object.getPrototypeOf(s);)Object.getOwnPropertyNames(s).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e}'s prototype due to error: ${o}`)}}),s=Object.getPrototypeOf(s);return r}function Ae(t,e={}){return new Proxy(e,{get(r,s){return s in r?r[s]:async(...n)=>(await t())[s](...n)}})}class Se{constructor(e,r){p(this,"baseDocument");p(this,"contributions",new Map);p(this,"latestOutput");p(this,"options");this.baseDocument=e,this.options=r,this.updateBaseDocument(e)}updateBaseDocument(e){return this.validateStartingDocument(e),this.baseDocument=this.options.copyDocuments?E(e):e,this.rebuild()}addOrUpdateContribution(e,r){this.validateContribution(e,r);const s=this.contributions.get(e),n=this.options.copyDocuments&&r?E(r):r;this.contributions.set(e,n);try{return this.rebuild()}catch(o){throw s?this.contributions.set(e,s):this.contributions.delete(e),new Error(`Error when setting the document named ${e}: ${o}`)}}deleteContribution(e){const r=this.contributions.get(e);if(!r)throw new Error("{documentKey} does not exist");this.contributions.delete(e);try{return this.rebuild()}catch(s){throw this.contributions.set(e,r),new Error(`Error when deleting the document named ${e}: ${s}`)}}rebuild(){if(this.contributions.size===0){let r=E(this.baseDocument);return r=this.transformFinalOutput(r),this.validateOutput(r),this.latestOutput=r,this.latestOutput}let e=this.baseDocument;return this.contributions.forEach(r=>{e=k(e,r,this.options.ignoreDuplicateProperties),this.validateOutput(e)}),e=this.transformFinalOutput(e),this.validateOutput(e),this.latestOutput=e,this.latestOutput}}function Me(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||Array.isArray(r))&&(e=!1)}),e}function qe(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||!Array.isArray(r))&&(e=!1)}),e}function k(t,e,r){const s=E(t);return e&&Object.keys(e).forEach(n=>{if(Object.hasOwn(t,n)){if(Me(t[n],e[n]))s[n]=k(t[n],e[n],r);else if(qe(t[n],e[n]))s[n]=s[n].concat(e[n]);else if(!r)throw new Error(`Cannot merge objects: key "${n}" already exists in the target object`)}else s[n]=e[n]}),s}class je{constructor(e="Anonymous"){p(this,"unsubscribers",new Set);this.name=e}add(...e){e.forEach(r=>{"dispose"in r?this.unsubscribers.add(r.dispose):this.unsubscribers.add(r)})}async runAllUnsubscribers(){const e=[...this.unsubscribers].map(s=>s()),r=await Promise.all(e);return this.unsubscribers.clear(),r.every((s,n)=>(s||console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${n} failed!`),s))}}class Ce{constructor(){p(this,"subscribe",this.event);p(this,"subscriptions");p(this,"lazyEvent");p(this,"isDisposed",!1);p(this,"dispose",()=>this.disposeFn());p(this,"emit",e=>{this.emitFn(e)})}get event(){return this.assertNotDisposed(),this.lazyEvent||(this.lazyEvent=e=>{if(!e||typeof e!="function")throw new Error("Event handler callback must be a function!");return this.subscriptions||(this.subscriptions=[]),this.subscriptions.push(e),()=>{if(!this.subscriptions)return!1;const r=this.subscriptions.indexOf(e);return r<0?!1:(this.subscriptions.splice(r,1),!0)}}),this.lazyEvent}emitFn(e){var r;this.assertNotDisposed(),(r=this.subscriptions)==null||r.forEach(s=>s(e))}assertNotDisposed(){if(this.isDisposed)throw new Error("Emitter is disposed")}disposeFn(){return this.assertNotDisposed(),this.isDisposed=!0,this.subscriptions=void 0,this.lazyEvent=void 0,Promise.resolve(!0)}}class W extends de.Mutex{}class Pe{constructor(){p(this,"mutexesByID",new Map)}get(e){let r=this.mutexesByID.get(e);return r||(r=new W,this.mutexesByID.set(e,r),r)}}const K=[{shortName:"ERR",fullNames:["ERROR"],chapters:-1},{shortName:"GEN",fullNames:["Genesis"],chapters:50},{shortName:"EXO",fullNames:["Exodus"],chapters:40},{shortName:"LEV",fullNames:["Leviticus"],chapters:27},{shortName:"NUM",fullNames:["Numbers"],chapters:36},{shortName:"DEU",fullNames:["Deuteronomy"],chapters:34},{shortName:"JOS",fullNames:["Joshua"],chapters:24},{shortName:"JDG",fullNames:["Judges"],chapters:21},{shortName:"RUT",fullNames:["Ruth"],chapters:4},{shortName:"1SA",fullNames:["1 Samuel"],chapters:31},{shortName:"2SA",fullNames:["2 Samuel"],chapters:24},{shortName:"1KI",fullNames:["1 Kings"],chapters:22},{shortName:"2KI",fullNames:["2 Kings"],chapters:25},{shortName:"1CH",fullNames:["1 Chronicles"],chapters:29},{shortName:"2CH",fullNames:["2 Chronicles"],chapters:36},{shortName:"EZR",fullNames:["Ezra"],chapters:10},{shortName:"NEH",fullNames:["Nehemiah"],chapters:13},{shortName:"EST",fullNames:["Esther"],chapters:10},{shortName:"JOB",fullNames:["Job"],chapters:42},{shortName:"PSA",fullNames:["Psalm","Psalms"],chapters:150},{shortName:"PRO",fullNames:["Proverbs"],chapters:31},{shortName:"ECC",fullNames:["Ecclesiastes"],chapters:12},{shortName:"SNG",fullNames:["Song of Solomon","Song of Songs"],chapters:8},{shortName:"ISA",fullNames:["Isaiah"],chapters:66},{shortName:"JER",fullNames:["Jeremiah"],chapters:52},{shortName:"LAM",fullNames:["Lamentations"],chapters:5},{shortName:"EZK",fullNames:["Ezekiel"],chapters:48},{shortName:"DAN",fullNames:["Daniel"],chapters:12},{shortName:"HOS",fullNames:["Hosea"],chapters:14},{shortName:"JOL",fullNames:["Joel"],chapters:3},{shortName:"AMO",fullNames:["Amos"],chapters:9},{shortName:"OBA",fullNames:["Obadiah"],chapters:1},{shortName:"JON",fullNames:["Jonah"],chapters:4},{shortName:"MIC",fullNames:["Micah"],chapters:7},{shortName:"NAM",fullNames:["Nahum"],chapters:3},{shortName:"HAB",fullNames:["Habakkuk"],chapters:3},{shortName:"ZEP",fullNames:["Zephaniah"],chapters:3},{shortName:"HAG",fullNames:["Haggai"],chapters:2},{shortName:"ZEC",fullNames:["Zechariah"],chapters:14},{shortName:"MAL",fullNames:["Malachi"],chapters:4},{shortName:"MAT",fullNames:["Matthew"],chapters:28},{shortName:"MRK",fullNames:["Mark"],chapters:16},{shortName:"LUK",fullNames:["Luke"],chapters:24},{shortName:"JHN",fullNames:["John"],chapters:21},{shortName:"ACT",fullNames:["Acts"],chapters:28},{shortName:"ROM",fullNames:["Romans"],chapters:16},{shortName:"1CO",fullNames:["1 Corinthians"],chapters:16},{shortName:"2CO",fullNames:["2 Corinthians"],chapters:13},{shortName:"GAL",fullNames:["Galatians"],chapters:6},{shortName:"EPH",fullNames:["Ephesians"],chapters:6},{shortName:"PHP",fullNames:["Philippians"],chapters:4},{shortName:"COL",fullNames:["Colossians"],chapters:4},{shortName:"1TH",fullNames:["1 Thessalonians"],chapters:5},{shortName:"2TH",fullNames:["2 Thessalonians"],chapters:3},{shortName:"1TI",fullNames:["1 Timothy"],chapters:6},{shortName:"2TI",fullNames:["2 Timothy"],chapters:4},{shortName:"TIT",fullNames:["Titus"],chapters:3},{shortName:"PHM",fullNames:["Philemon"],chapters:1},{shortName:"HEB",fullNames:["Hebrews"],chapters:13},{shortName:"JAS",fullNames:["James"],chapters:5},{shortName:"1PE",fullNames:["1 Peter"],chapters:5},{shortName:"2PE",fullNames:["2 Peter"],chapters:3},{shortName:"1JN",fullNames:["1 John"],chapters:5},{shortName:"2JN",fullNames:["2 John"],chapters:1},{shortName:"3JN",fullNames:["3 John"],chapters:1},{shortName:"JUD",fullNames:["Jude"],chapters:1},{shortName:"REV",fullNames:["Revelation"],chapters:22}],L=1,Z=K.length-1,X=1,Q=1,Y=t=>{var e;return((e=K[t])==null?void 0:e.chapters)??-1},Te=(t,e)=>({bookNum:Math.max(L,Math.min(t.bookNum+e,Z)),chapterNum:1,verseNum:1}),Re=(t,e)=>({...t,chapterNum:Math.min(Math.max(X,t.chapterNum+e),Y(t.bookNum)),verseNum:1}),De=(t,e)=>({...t,verseNum:Math.max(Q,t.verseNum+e)}),Ie=t=>(...e)=>t.map(s=>s(...e)).every(s=>s),xe=t=>async(...e)=>{const r=t.map(async s=>s(...e));return(await Promise.all(r)).every(s=>s)};var D=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},N={},_e=()=>{const t="\\ud800-\\udfff",e="\\u0300-\\u036f",r="\\ufe20-\\ufe2f",s="\\u20d0-\\u20ff",n="\\u1ab0-\\u1aff",o="\\u1dc0-\\u1dff",a=e+r+s+n+o,i="\\ufe0e\\ufe0f",c="\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93",h=`[${t}]`,u=`[${a}]`,l="\\ud83c[\\udffb-\\udfff]",f=`(?:${u}|${l})`,b=`[^${t}]`,d="(?:\\uD83C[\\uDDE6-\\uDDFF]){2}",y="[\\ud800-\\udbff][\\udc00-\\udfff]",q="\\u200d",ue="(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)",le=`[${c}]`,T=`${f}?`,R=`[${i}]?`,ce=`(?:${q}(?:${[b,d,y].join("|")})${R+T})*`,fe=R+T+ce,he=`(?:${[`${b}${u}?`,u,d,y,h,le].join("|")})`;return new RegExp(`${ue}|${l}(?=${l})|${he+fe}`,"g")},ze=D&&D.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(N,"__esModule",{value:!0});var A=ze(_e);function j(t){if(typeof t!="string")throw new Error("A string is expected as input");return t.match(A.default())||[]}var Be=N.toArray=j;function P(t){if(typeof t!="string")throw new Error("Input must be a string");var e=t.match(A.default());return e===null?0:e.length}var Je=N.length=P;function ee(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");(typeof e!="number"||e<0)&&(e=0),typeof r=="number"&&r<0&&(r=0);var s=t.match(A.default());return s?s.slice(e,r).join(""):""}var Ge=N.substring=ee;function Ue(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");var s=P(t);if(typeof e!="number"&&(e=parseInt(e,10)),e>=s)return"";e<0&&(e+=s);var n;typeof r>"u"?n=s:(typeof r!="number"&&(r=parseInt(r,10)),n=r>=0?r+e:e);var o=t.match(A.default());return o?o.slice(e,n).join(""):""}var Ve=N.substr=Ue;function Fe(t,e,r,s){if(e===void 0&&(e=16),r===void 0&&(r="#"),s===void 0&&(s="right"),typeof t!="string"||typeof e!="number")throw new Error("Invalid arguments specified");if(["left","right"].indexOf(s)===-1)throw new Error("Pad position should be either left or right");typeof r!="string"&&(r=String(r));var n=P(t);if(n>e)return ee(t,0,e);if(n=s.length)return e===""?s.length:-1;if(e==="")return r;var n=j(e),o=!1,a;for(a=r;am(t)||e<-m(t)))return M(t,e,1)}function Ke(t,e){return e<0||e>m(t)-1?"":M(t,e,1)}function Le(t,e){if(!(e<0||e>m(t)-1))return M(t,e,1).codePointAt(0)}function Ze(t,e,r=m(t)){const s=re(t,e);return!(s===-1||s+m(e)!==r)}function Xe(t,e,r=0){const s=O(t,r);return S(s,e)!==-1}function S(t,e,r=0){return ke(t,e,r)}function re(t,e,r=1/0){let s=r;s<0?s=0:s>=m(t)&&(s=m(t)-1);for(let n=s;n>=0;n--)if(M(t,n,m(e))===e)return n;return-1}function m(t){return Je(t)}function Qe(t,e){const r=e.toUpperCase();return r==="NONE"?t:t.normalize(r)}function Ye(t,e,r=" "){return e<=m(t)?t:te(t,e,r,"right")}function et(t,e,r=" "){return e<=m(t)?t:te(t,e,r,"left")}function I(t,e){return e>t?t:e<-t?0:e<0?e+t:e}function tt(t,e,r){const s=m(t);if(e>s||r&&(e>r&&!(e>0&&e-s)||r<-s||e<0&&e>-s&&r>0))return"";const n=I(s,e),o=r?I(s,r):void 0;return O(t,n,o)}function rt(t,e,r){const s=[];if(r!==void 0&&r<=0)return[t];if(e==="")return se(t).slice(0,r);let n=e;(typeof e=="string"||e instanceof RegExp&&!e.flags.includes("g"))&&(n=new RegExp(e,"g"));const o=t.match(n);let a=0;if(o){for(let i=0;i<(r?r-1:o.length);i++){const c=S(t,o[i],a),h=m(o[i]);if(s.push(O(t,a,c)),a=c+h,r!==void 0&&s.length===r)break}return s.push(O(t,a)),s}}function st(t,e,r=0){return S(t,e,r)===r}function M(t,e=0,r=m(t)-e){return Ve(t,e,r)}function O(t,e,r=m(t)){return Ge(t,e,r)}function se(t){return Be(t)}var nt=Object.getOwnPropertyNames,ot=Object.getOwnPropertySymbols,at=Object.prototype.hasOwnProperty;function x(t,e){return function(s,n,o){return t(s,n,o)&&e(s,n,o)}}function $(t){return function(r,s,n){if(!r||!s||typeof r!="object"||typeof s!="object")return t(r,s,n);var o=n.cache,a=o.get(r),i=o.get(s);if(a&&i)return a===s&&i===r;o.set(r,s),o.set(s,r);var c=t(r,s,n);return o.delete(r),o.delete(s),c}}function _(t){return nt(t).concat(ot(t))}var ne=Object.hasOwn||function(t,e){return at.call(t,e)};function v(t,e){return t||e?t===e:t===e||t!==t&&e!==e}var oe="_owner",z=Object.getOwnPropertyDescriptor,B=Object.keys;function it(t,e,r){var s=t.length;if(e.length!==s)return!1;for(;s-- >0;)if(!r.equals(t[s],e[s],s,s,t,e,r))return!1;return!0}function ut(t,e){return v(t.getTime(),e.getTime())}function J(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.entries(),o=0,a,i;(a=n.next())&&!a.done;){for(var c=e.entries(),h=!1,u=0;(i=c.next())&&!i.done;){var l=a.value,f=l[0],b=l[1],d=i.value,y=d[0],q=d[1];!h&&!s[u]&&(h=r.equals(f,y,o,u,t,e,r)&&r.equals(b,q,f,y,t,e,r))&&(s[u]=!0),u++}if(!h)return!1;o++}return!0}function lt(t,e,r){var s=B(t),n=s.length;if(B(e).length!==n)return!1;for(var o;n-- >0;)if(o=s[n],o===oe&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!ne(e,o)||!r.equals(t[o],e[o],o,o,t,e,r))return!1;return!0}function w(t,e,r){var s=_(t),n=s.length;if(_(e).length!==n)return!1;for(var o,a,i;n-- >0;)if(o=s[n],o===oe&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!ne(e,o)||!r.equals(t[o],e[o],o,o,t,e,r)||(a=z(t,o),i=z(e,o),(a||i)&&(!a||!i||a.configurable!==i.configurable||a.enumerable!==i.enumerable||a.writable!==i.writable)))return!1;return!0}function ct(t,e){return v(t.valueOf(),e.valueOf())}function ft(t,e){return t.source===e.source&&t.flags===e.flags}function G(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.values(),o,a;(o=n.next())&&!o.done;){for(var i=e.values(),c=!1,h=0;(a=i.next())&&!a.done;)!c&&!s[h]&&(c=r.equals(o.value,a.value,o.value,a.value,t,e,r))&&(s[h]=!0),h++;if(!c)return!1}return!0}function ht(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}var pt="[object Arguments]",mt="[object Boolean]",dt="[object Date]",bt="[object Map]",gt="[object Number]",Nt="[object Object]",vt="[object RegExp]",yt="[object Set]",wt="[object String]",Et=Array.isArray,U=typeof ArrayBuffer=="function"&&ArrayBuffer.isView?ArrayBuffer.isView:null,V=Object.assign,Ot=Object.prototype.toString.call.bind(Object.prototype.toString);function $t(t){var e=t.areArraysEqual,r=t.areDatesEqual,s=t.areMapsEqual,n=t.areObjectsEqual,o=t.arePrimitiveWrappersEqual,a=t.areRegExpsEqual,i=t.areSetsEqual,c=t.areTypedArraysEqual;return function(u,l,f){if(u===l)return!0;if(u==null||l==null||typeof u!="object"||typeof l!="object")return u!==u&&l!==l;var b=u.constructor;if(b!==l.constructor)return!1;if(b===Object)return n(u,l,f);if(Et(u))return e(u,l,f);if(U!=null&&U(u))return c(u,l,f);if(b===Date)return r(u,l,f);if(b===RegExp)return a(u,l,f);if(b===Map)return s(u,l,f);if(b===Set)return i(u,l,f);var d=Ot(u);return d===dt?r(u,l,f):d===vt?a(u,l,f):d===bt?s(u,l,f):d===yt?i(u,l,f):d===Nt?typeof u.then!="function"&&typeof l.then!="function"&&n(u,l,f):d===pt?n(u,l,f):d===mt||d===gt||d===wt?o(u,l,f):!1}}function At(t){var e=t.circular,r=t.createCustomConfig,s=t.strict,n={areArraysEqual:s?w:it,areDatesEqual:ut,areMapsEqual:s?x(J,w):J,areObjectsEqual:s?w:lt,arePrimitiveWrappersEqual:ct,areRegExpsEqual:ft,areSetsEqual:s?x(G,w):G,areTypedArraysEqual:s?w:ht};if(r&&(n=V({},n,r(n))),e){var o=$(n.areArraysEqual),a=$(n.areMapsEqual),i=$(n.areObjectsEqual),c=$(n.areSetsEqual);n=V({},n,{areArraysEqual:o,areMapsEqual:a,areObjectsEqual:i,areSetsEqual:c})}return n}function St(t){return function(e,r,s,n,o,a,i){return t(e,r,i)}}function Mt(t){var e=t.circular,r=t.comparator,s=t.createState,n=t.equals,o=t.strict;if(s)return function(c,h){var u=s(),l=u.cache,f=l===void 0?e?new WeakMap:void 0:l,b=u.meta;return r(c,h,{cache:f,equals:n,meta:b,strict:o})};if(e)return function(c,h){return r(c,h,{cache:new WeakMap,equals:n,meta:void 0,strict:o})};var a={cache:void 0,equals:n,meta:void 0,strict:o};return function(c,h){return r(c,h,a)}}var qt=g();g({strict:!0});g({circular:!0});g({circular:!0,strict:!0});g({createInternalComparator:function(){return v}});g({strict:!0,createInternalComparator:function(){return v}});g({circular:!0,createInternalComparator:function(){return v}});g({circular:!0,createInternalComparator:function(){return v},strict:!0});function g(t){t===void 0&&(t={});var e=t.circular,r=e===void 0?!1:e,s=t.createInternalComparator,n=t.createState,o=t.strict,a=o===void 0?!1:o,i=At(t),c=$t(i),h=s?s(c):St(c);return Mt({circular:r,comparator:c,createState:n,equals:h,strict:a})}function jt(t,e){return qt(t,e)}function C(t,e,r){return JSON.stringify(t,(n,o)=>{let a=o;return e&&(a=e(n,a)),a===void 0&&(a=null),a},r)}function ae(t,e){function r(n){return Object.keys(n).forEach(o=>{n[o]===null?n[o]=void 0:typeof n[o]=="object"&&(n[o]=r(n[o]))}),n}const s=JSON.parse(t,e);if(s!==null)return typeof s=="object"?r(s):s}function Ct(t){try{const e=C(t);return e===C(ae(e))}catch{return!1}}const Pt=t=>t.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/"),ie={title:"Platform.Bible menus",type:"object",properties:{mainMenu:{description:"Top level menu for the application",$ref:"#/$defs/multiColumnMenu"},defaultWebViewTopMenu:{description:"Default top menu for web views that don't specify their own",$ref:"#/$defs/multiColumnMenu"},defaultWebViewContextMenu:{description:"Default context menu for web views that don't specify their own",$ref:"#/$defs/singleColumnMenu"},webViewMenus:{description:"Menus that apply per web view in the application",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{$ref:"#/$defs/menusForOneWebView"}},additionalProperties:!1}},required:["mainMenu","defaultWebViewTopMenu","defaultWebViewContextMenu","webViewMenus"],additionalProperties:!1,$defs:{localizeKey:{description:"Identifier for a string that will be localized in a menu based on the user's UI language",type:"string",pattern:"^%[\\w\\-\\.]+%$"},referencedItem:{description:"Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)",type:"string",pattern:"^[\\w\\-]+\\.[\\w\\-]+$"},columnsWithHeaders:{description:"Group of columns that can be combined with other columns to form a multi-column menu",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single column with a header string",type:"object",properties:{label:{description:"Header text for this this column in the UI",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},order:{description:"Relative order of this column compared to other columns (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu groups to this column",type:"boolean"}},required:["label","order"],additionalProperties:!1}},properties:{isExtensible:{description:"Defines whether contributions are allowed to add columns to this multi-column menu",type:"boolean"}}},menuGroups:{description:"Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single group that contains menu items",type:"object",oneOf:[{properties:{column:{description:"Column where this group belongs, not required for single column menus",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["order"],additionalProperties:!1},{properties:{menuItem:{description:"Menu item that anchors the submenu where this group belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["menuItem","order"],additionalProperties:!1}]}},additionalProperties:!1},menuItem:{description:"Single item in a menu that can be clicked on to take an action or can be the parent of a submenu",type:"object",oneOf:[{properties:{id:{description:"ID for this menu item that holds a submenu",$ref:"#/$defs/referencedItem"}},required:["id"]},{properties:{command:{description:"Name of the PAPI command to run when this menu item is selected.",$ref:"#/$defs/referencedItem"},iconPathBefore:{description:"Path to the icon to display before the menu text",type:"string"},iconPathAfter:{description:"Path to the icon to display after the menu text",type:"string"}},required:["command"]}],properties:{label:{description:"Key that represents the text of this menu item to display",$ref:"#/$defs/localizeKey"},tooltip:{description:"Key that represents the text to display if a mouse pointer hovers over the menu item",$ref:"#/$defs/localizeKey"},searchTerms:{description:"Key that represents additional words the platform should reference when users are searching for menu items",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},group:{description:"Group to which this menu item belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this menu item compared to other menu items in the same group (sorted ascending)",type:"number"}},required:["label","group","order"],unevaluatedProperties:!1},groupsAndItems:{description:"Core schema for a column",type:"object",properties:{groups:{description:"Groups that belong in this menu",$ref:"#/$defs/menuGroups"},items:{description:"List of menu items that belong in this menu",type:"array",items:{$ref:"#/$defs/menuItem"},uniqueItems:!0}},required:["groups","items"]},singleColumnMenu:{description:"Menu that contains a column without a header",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"}],unevaluatedProperties:!1},multiColumnMenu:{description:"Menu that can contain multiple columns with headers",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"},{properties:{columns:{description:"Columns that belong in this menu",$ref:"#/$defs/columnsWithHeaders"}},required:["columns"]}],unevaluatedProperties:!1},menusForOneWebView:{description:"Set of menus that are associated with a single tab",type:"object",properties:{includeDefaults:{description:"Indicates whether the platform default menus should be included for this webview",type:"boolean"},topMenu:{description:"Menu that opens when you click on the top left corner of a tab",$ref:"#/$defs/multiColumnMenu"},contextMenu:{description:"Menu that opens when you right click on the main body/area of a tab",$ref:"#/$defs/singleColumnMenu"}},additionalProperties:!1}}};Object.freeze(ie);exports.AsyncVariable=be;exports.DocumentCombinerEngine=Se;exports.FIRST_SCR_BOOK_NUM=L;exports.FIRST_SCR_CHAPTER_NUM=X;exports.FIRST_SCR_VERSE_NUM=Q;exports.LAST_SCR_BOOK_NUM=Z;exports.Mutex=W;exports.MutexMap=Pe;exports.PlatformEventEmitter=Ce;exports.UnsubscriberAsyncList=je;exports.aggregateUnsubscriberAsyncs=xe;exports.aggregateUnsubscribers=Ie;exports.at=We;exports.charAt=Ke;exports.codePointAt=Le;exports.createSyncProxyForAsyncObject=Ae;exports.debounce=Ne;exports.deepClone=E;exports.deepEqual=jt;exports.deserialize=ae;exports.endsWith=Ze;exports.getAllObjectFunctionNames=$e;exports.getChaptersForBook=Y;exports.getErrorMessage=Ee;exports.groupBy=ve;exports.htmlEncode=Pt;exports.includes=Xe;exports.indexOf=S;exports.isSerializable=Ct;exports.isString=F;exports.lastIndexOf=re;exports.length=m;exports.menuDocumentSchema=ie;exports.newGuid=ge;exports.normalize=Qe;exports.offsetBook=Te;exports.offsetChapter=Re;exports.offsetVerse=De;exports.padEnd=Ye;exports.padStart=et;exports.serialize=C;exports.slice=tt;exports.split=rt;exports.startsWith=st;exports.substring=O;exports.toArray=se;exports.wait=H;exports.waitForDuration=Oe; +"use strict";var me=Object.defineProperty;var de=(t,e,r)=>e in t?me(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var p=(t,e,r)=>(de(t,typeof e!="symbol"?e+"":e,r),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const be=require("async-mutex");class ge{constructor(e,r=1e4){p(this,"variableName");p(this,"promiseToValue");p(this,"resolver");p(this,"rejecter");this.variableName=e,this.promiseToValue=new Promise((s,n)=>{this.resolver=s,this.rejecter=n}),r>0&&setTimeout(()=>{this.rejecter&&(this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`),this.complete())},r),Object.seal(this)}get promise(){return this.promiseToValue}get hasSettled(){return Object.isFrozen(this)}resolveToValue(e,r=!1){if(this.resolver)console.debug(`${this.variableName} is being resolved now`),this.resolver(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent resolution of ${this.variableName}`)}}rejectWithReason(e,r=!1){if(this.rejecter)console.debug(`${this.variableName} is being rejected now`),this.rejecter(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent rejection of ${this.variableName}`)}}complete(){this.resolver=void 0,this.rejecter=void 0,Object.freeze(this)}}function Ne(){return"00-0-4-1-000".replace(/[^-]/g,t=>((Math.random()+~~t)*65536>>t).toString(16).padStart(4,"0"))}function F(t){return typeof t=="string"||t instanceof String}function E(t){return JSON.parse(JSON.stringify(t))}function ve(t,e=300){if(F(t))throw new Error("Tried to debounce a string! Could be XSS");let r;return(...s)=>{clearTimeout(r),r=setTimeout(()=>t(...s),e)}}function ye(t,e,r){const s=new Map;return t.forEach(n=>{const o=e(n),a=s.get(o),i=r?r(n,o):n;a?a.push(i):s.set(o,[i])}),s}function we(t){return typeof t=="object"&&t!==null&&"message"in t&&typeof t.message=="string"}function Ee(t){if(we(t))return t;try{return new Error(JSON.stringify(t))}catch{return new Error(String(t))}}function Oe(t){return Ee(t).message}function H(t){return new Promise(e=>setTimeout(e,t))}function $e(t,e){const r=H(e).then(()=>{});return Promise.any([r,t()])}function Ae(t,e="obj"){const r=new Set;Object.getOwnPropertyNames(t).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e} due to error: ${o}`)}});let s=Object.getPrototypeOf(t);for(;s&&Object.getPrototypeOf(s);)Object.getOwnPropertyNames(s).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e}'s prototype due to error: ${o}`)}}),s=Object.getPrototypeOf(s);return r}function Se(t,e={}){return new Proxy(e,{get(r,s){return s in r?r[s]:async(...n)=>(await t())[s](...n)}})}class Me{constructor(e,r){p(this,"baseDocument");p(this,"contributions",new Map);p(this,"latestOutput");p(this,"options");this.baseDocument=e,this.options=r,this.updateBaseDocument(e)}updateBaseDocument(e){return this.validateStartingDocument(e),this.baseDocument=this.options.copyDocuments?E(e):e,this.rebuild()}addOrUpdateContribution(e,r){this.validateContribution(e,r);const s=this.contributions.get(e),n=this.options.copyDocuments&&r?E(r):r;this.contributions.set(e,n);try{return this.rebuild()}catch(o){throw s?this.contributions.set(e,s):this.contributions.delete(e),new Error(`Error when setting the document named ${e}: ${o}`)}}deleteContribution(e){const r=this.contributions.get(e);if(!r)throw new Error("{documentKey} does not exist");this.contributions.delete(e);try{return this.rebuild()}catch(s){throw this.contributions.set(e,r),new Error(`Error when deleting the document named ${e}: ${s}`)}}rebuild(){if(this.contributions.size===0){let r=E(this.baseDocument);return r=this.transformFinalOutput(r),this.validateOutput(r),this.latestOutput=r,this.latestOutput}let e=this.baseDocument;return this.contributions.forEach(r=>{e=k(e,r,this.options.ignoreDuplicateProperties),this.validateOutput(e)}),e=this.transformFinalOutput(e),this.validateOutput(e),this.latestOutput=e,this.latestOutput}}function qe(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||Array.isArray(r))&&(e=!1)}),e}function je(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||!Array.isArray(r))&&(e=!1)}),e}function k(t,e,r){const s=E(t);return e&&Object.keys(e).forEach(n=>{if(Object.hasOwn(t,n)){if(qe(t[n],e[n]))s[n]=k(t[n],e[n],r);else if(je(t[n],e[n]))s[n]=s[n].concat(e[n]);else if(!r)throw new Error(`Cannot merge objects: key "${n}" already exists in the target object`)}else s[n]=e[n]}),s}class Ce{constructor(e="Anonymous"){p(this,"unsubscribers",new Set);this.name=e}add(...e){e.forEach(r=>{"dispose"in r?this.unsubscribers.add(r.dispose):this.unsubscribers.add(r)})}async runAllUnsubscribers(){const e=[...this.unsubscribers].map(s=>s()),r=await Promise.all(e);return this.unsubscribers.clear(),r.every((s,n)=>(s||console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${n} failed!`),s))}}class Pe{constructor(){p(this,"subscribe",this.event);p(this,"subscriptions");p(this,"lazyEvent");p(this,"isDisposed",!1);p(this,"dispose",()=>this.disposeFn());p(this,"emit",e=>{this.emitFn(e)})}get event(){return this.assertNotDisposed(),this.lazyEvent||(this.lazyEvent=e=>{if(!e||typeof e!="function")throw new Error("Event handler callback must be a function!");return this.subscriptions||(this.subscriptions=[]),this.subscriptions.push(e),()=>{if(!this.subscriptions)return!1;const r=this.subscriptions.indexOf(e);return r<0?!1:(this.subscriptions.splice(r,1),!0)}}),this.lazyEvent}emitFn(e){var r;this.assertNotDisposed(),(r=this.subscriptions)==null||r.forEach(s=>s(e))}assertNotDisposed(){if(this.isDisposed)throw new Error("Emitter is disposed")}disposeFn(){return this.assertNotDisposed(),this.isDisposed=!0,this.subscriptions=void 0,this.lazyEvent=void 0,Promise.resolve(!0)}}class W extends be.Mutex{}class Te{constructor(){p(this,"mutexesByID",new Map)}get(e){let r=this.mutexesByID.get(e);return r||(r=new W,this.mutexesByID.set(e,r),r)}}const K=[{shortName:"ERR",fullNames:["ERROR"],chapters:-1},{shortName:"GEN",fullNames:["Genesis"],chapters:50},{shortName:"EXO",fullNames:["Exodus"],chapters:40},{shortName:"LEV",fullNames:["Leviticus"],chapters:27},{shortName:"NUM",fullNames:["Numbers"],chapters:36},{shortName:"DEU",fullNames:["Deuteronomy"],chapters:34},{shortName:"JOS",fullNames:["Joshua"],chapters:24},{shortName:"JDG",fullNames:["Judges"],chapters:21},{shortName:"RUT",fullNames:["Ruth"],chapters:4},{shortName:"1SA",fullNames:["1 Samuel"],chapters:31},{shortName:"2SA",fullNames:["2 Samuel"],chapters:24},{shortName:"1KI",fullNames:["1 Kings"],chapters:22},{shortName:"2KI",fullNames:["2 Kings"],chapters:25},{shortName:"1CH",fullNames:["1 Chronicles"],chapters:29},{shortName:"2CH",fullNames:["2 Chronicles"],chapters:36},{shortName:"EZR",fullNames:["Ezra"],chapters:10},{shortName:"NEH",fullNames:["Nehemiah"],chapters:13},{shortName:"EST",fullNames:["Esther"],chapters:10},{shortName:"JOB",fullNames:["Job"],chapters:42},{shortName:"PSA",fullNames:["Psalm","Psalms"],chapters:150},{shortName:"PRO",fullNames:["Proverbs"],chapters:31},{shortName:"ECC",fullNames:["Ecclesiastes"],chapters:12},{shortName:"SNG",fullNames:["Song of Solomon","Song of Songs"],chapters:8},{shortName:"ISA",fullNames:["Isaiah"],chapters:66},{shortName:"JER",fullNames:["Jeremiah"],chapters:52},{shortName:"LAM",fullNames:["Lamentations"],chapters:5},{shortName:"EZK",fullNames:["Ezekiel"],chapters:48},{shortName:"DAN",fullNames:["Daniel"],chapters:12},{shortName:"HOS",fullNames:["Hosea"],chapters:14},{shortName:"JOL",fullNames:["Joel"],chapters:3},{shortName:"AMO",fullNames:["Amos"],chapters:9},{shortName:"OBA",fullNames:["Obadiah"],chapters:1},{shortName:"JON",fullNames:["Jonah"],chapters:4},{shortName:"MIC",fullNames:["Micah"],chapters:7},{shortName:"NAM",fullNames:["Nahum"],chapters:3},{shortName:"HAB",fullNames:["Habakkuk"],chapters:3},{shortName:"ZEP",fullNames:["Zephaniah"],chapters:3},{shortName:"HAG",fullNames:["Haggai"],chapters:2},{shortName:"ZEC",fullNames:["Zechariah"],chapters:14},{shortName:"MAL",fullNames:["Malachi"],chapters:4},{shortName:"MAT",fullNames:["Matthew"],chapters:28},{shortName:"MRK",fullNames:["Mark"],chapters:16},{shortName:"LUK",fullNames:["Luke"],chapters:24},{shortName:"JHN",fullNames:["John"],chapters:21},{shortName:"ACT",fullNames:["Acts"],chapters:28},{shortName:"ROM",fullNames:["Romans"],chapters:16},{shortName:"1CO",fullNames:["1 Corinthians"],chapters:16},{shortName:"2CO",fullNames:["2 Corinthians"],chapters:13},{shortName:"GAL",fullNames:["Galatians"],chapters:6},{shortName:"EPH",fullNames:["Ephesians"],chapters:6},{shortName:"PHP",fullNames:["Philippians"],chapters:4},{shortName:"COL",fullNames:["Colossians"],chapters:4},{shortName:"1TH",fullNames:["1 Thessalonians"],chapters:5},{shortName:"2TH",fullNames:["2 Thessalonians"],chapters:3},{shortName:"1TI",fullNames:["1 Timothy"],chapters:6},{shortName:"2TI",fullNames:["2 Timothy"],chapters:4},{shortName:"TIT",fullNames:["Titus"],chapters:3},{shortName:"PHM",fullNames:["Philemon"],chapters:1},{shortName:"HEB",fullNames:["Hebrews"],chapters:13},{shortName:"JAS",fullNames:["James"],chapters:5},{shortName:"1PE",fullNames:["1 Peter"],chapters:5},{shortName:"2PE",fullNames:["2 Peter"],chapters:3},{shortName:"1JN",fullNames:["1 John"],chapters:5},{shortName:"2JN",fullNames:["2 John"],chapters:1},{shortName:"3JN",fullNames:["3 John"],chapters:1},{shortName:"JUD",fullNames:["Jude"],chapters:1},{shortName:"REV",fullNames:["Revelation"],chapters:22}],L=1,Z=K.length-1,X=1,Q=1,Y=t=>{var e;return((e=K[t])==null?void 0:e.chapters)??-1},Re=(t,e)=>({bookNum:Math.max(L,Math.min(t.bookNum+e,Z)),chapterNum:1,verseNum:1}),De=(t,e)=>({...t,chapterNum:Math.min(Math.max(X,t.chapterNum+e),Y(t.bookNum)),verseNum:1}),Ie=(t,e)=>({...t,verseNum:Math.max(Q,t.verseNum+e)}),xe=t=>(...e)=>t.map(s=>s(...e)).every(s=>s),_e=t=>async(...e)=>{const r=t.map(async s=>s(...e));return(await Promise.all(r)).every(s=>s)};var D=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},N={},ze=()=>{const t="\\ud800-\\udfff",e="\\u0300-\\u036f",r="\\ufe20-\\ufe2f",s="\\u20d0-\\u20ff",n="\\u1ab0-\\u1aff",o="\\u1dc0-\\u1dff",a=e+r+s+n+o,i="\\ufe0e\\ufe0f",c="\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93",h=`[${t}]`,u=`[${a}]`,l="\\ud83c[\\udffb-\\udfff]",f=`(?:${u}|${l})`,b=`[^${t}]`,d="(?:\\uD83C[\\uDDE6-\\uDDFF]){2}",y="[\\ud800-\\udbff][\\udc00-\\udfff]",q="\\u200d",le="(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)",ce=`[${c}]`,T=`${f}?`,R=`[${i}]?`,fe=`(?:${q}(?:${[b,d,y].join("|")})${R+T})*`,he=R+T+fe,pe=`(?:${[`${b}${u}?`,u,d,y,h,ce].join("|")})`;return new RegExp(`${le}|${l}(?=${l})|${pe+he}`,"g")},Be=D&&D.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(N,"__esModule",{value:!0});var A=Be(ze);function j(t){if(typeof t!="string")throw new Error("A string is expected as input");return t.match(A.default())||[]}var Je=N.toArray=j;function P(t){if(typeof t!="string")throw new Error("Input must be a string");var e=t.match(A.default());return e===null?0:e.length}var Ge=N.length=P;function ee(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");(typeof e!="number"||e<0)&&(e=0),typeof r=="number"&&r<0&&(r=0);var s=t.match(A.default());return s?s.slice(e,r).join(""):""}var Ue=N.substring=ee;function Ve(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");var s=P(t);if(typeof e!="number"&&(e=parseInt(e,10)),e>=s)return"";e<0&&(e+=s);var n;typeof r>"u"?n=s:(typeof r!="number"&&(r=parseInt(r,10)),n=r>=0?r+e:e);var o=t.match(A.default());return o?o.slice(e,n).join(""):""}var Fe=N.substr=Ve;function He(t,e,r,s){if(e===void 0&&(e=16),r===void 0&&(r="#"),s===void 0&&(s="right"),typeof t!="string"||typeof e!="number")throw new Error("Invalid arguments specified");if(["left","right"].indexOf(s)===-1)throw new Error("Pad position should be either left or right");typeof r!="string"&&(r=String(r));var n=P(t);if(n>e)return ee(t,0,e);if(n=s.length)return e===""?s.length:-1;if(e==="")return r;var n=j(e),o=!1,a;for(a=r;am(t)||e<-m(t)))return M(t,e,1)}function Le(t,e){return e<0||e>m(t)-1?"":M(t,e,1)}function Ze(t,e){if(!(e<0||e>m(t)-1))return M(t,e,1).codePointAt(0)}function Xe(t,e,r=m(t)){const s=se(t,e);return!(s===-1||s+m(e)!==r)}function re(t,e,r=0){const s=O(t,r);return S(s,e)!==-1}function S(t,e,r=0){return We(t,e,r)}function se(t,e,r=1/0){let s=r;s<0?s=0:s>=m(t)&&(s=m(t)-1);for(let n=s;n>=0;n--)if(M(t,n,m(e))===e)return n;return-1}function m(t){return Ge(t)}function Qe(t,e){const r=e.toUpperCase();return r==="NONE"?t:t.normalize(r)}function Ye(t,e,r=" "){return e<=m(t)?t:te(t,e,r,"right")}function et(t,e,r=" "){return e<=m(t)?t:te(t,e,r,"left")}function I(t,e){return e>t?t:e<-t?0:e<0?e+t:e}function tt(t,e,r){const s=m(t);if(e>s||r&&(e>r&&!(e>0&&e-s)||r<-s||e<0&&e>-s&&r>0))return"";const n=I(s,e),o=r?I(s,r):void 0;return O(t,n,o)}function rt(t,e,r){const s=[];if(r!==void 0&&r<=0)return[t];if(e==="")return ne(t).slice(0,r);let n=e;(typeof e=="string"||e instanceof RegExp&&!re(e.flags,"g"))&&(n=new RegExp(e,"g"));const o=t.match(n);let a=0;if(o){for(let i=0;i<(r?r-1:o.length);i++){const c=S(t,o[i],a),h=m(o[i]);if(s.push(O(t,a,c)),a=c+h,r!==void 0&&s.length===r)break}return s.push(O(t,a)),s}}function st(t,e,r=0){return S(t,e,r)===r}function M(t,e=0,r=m(t)-e){return Fe(t,e,r)}function O(t,e,r=m(t)){return Ue(t,e,r)}function ne(t){return Je(t)}var nt=Object.getOwnPropertyNames,ot=Object.getOwnPropertySymbols,at=Object.prototype.hasOwnProperty;function x(t,e){return function(s,n,o){return t(s,n,o)&&e(s,n,o)}}function $(t){return function(r,s,n){if(!r||!s||typeof r!="object"||typeof s!="object")return t(r,s,n);var o=n.cache,a=o.get(r),i=o.get(s);if(a&&i)return a===s&&i===r;o.set(r,s),o.set(s,r);var c=t(r,s,n);return o.delete(r),o.delete(s),c}}function _(t){return nt(t).concat(ot(t))}var oe=Object.hasOwn||function(t,e){return at.call(t,e)};function v(t,e){return t||e?t===e:t===e||t!==t&&e!==e}var ae="_owner",z=Object.getOwnPropertyDescriptor,B=Object.keys;function it(t,e,r){var s=t.length;if(e.length!==s)return!1;for(;s-- >0;)if(!r.equals(t[s],e[s],s,s,t,e,r))return!1;return!0}function ut(t,e){return v(t.getTime(),e.getTime())}function J(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.entries(),o=0,a,i;(a=n.next())&&!a.done;){for(var c=e.entries(),h=!1,u=0;(i=c.next())&&!i.done;){var l=a.value,f=l[0],b=l[1],d=i.value,y=d[0],q=d[1];!h&&!s[u]&&(h=r.equals(f,y,o,u,t,e,r)&&r.equals(b,q,f,y,t,e,r))&&(s[u]=!0),u++}if(!h)return!1;o++}return!0}function lt(t,e,r){var s=B(t),n=s.length;if(B(e).length!==n)return!1;for(var o;n-- >0;)if(o=s[n],o===ae&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!oe(e,o)||!r.equals(t[o],e[o],o,o,t,e,r))return!1;return!0}function w(t,e,r){var s=_(t),n=s.length;if(_(e).length!==n)return!1;for(var o,a,i;n-- >0;)if(o=s[n],o===ae&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!oe(e,o)||!r.equals(t[o],e[o],o,o,t,e,r)||(a=z(t,o),i=z(e,o),(a||i)&&(!a||!i||a.configurable!==i.configurable||a.enumerable!==i.enumerable||a.writable!==i.writable)))return!1;return!0}function ct(t,e){return v(t.valueOf(),e.valueOf())}function ft(t,e){return t.source===e.source&&t.flags===e.flags}function G(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.values(),o,a;(o=n.next())&&!o.done;){for(var i=e.values(),c=!1,h=0;(a=i.next())&&!a.done;)!c&&!s[h]&&(c=r.equals(o.value,a.value,o.value,a.value,t,e,r))&&(s[h]=!0),h++;if(!c)return!1}return!0}function ht(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}var pt="[object Arguments]",mt="[object Boolean]",dt="[object Date]",bt="[object Map]",gt="[object Number]",Nt="[object Object]",vt="[object RegExp]",yt="[object Set]",wt="[object String]",Et=Array.isArray,U=typeof ArrayBuffer=="function"&&ArrayBuffer.isView?ArrayBuffer.isView:null,V=Object.assign,Ot=Object.prototype.toString.call.bind(Object.prototype.toString);function $t(t){var e=t.areArraysEqual,r=t.areDatesEqual,s=t.areMapsEqual,n=t.areObjectsEqual,o=t.arePrimitiveWrappersEqual,a=t.areRegExpsEqual,i=t.areSetsEqual,c=t.areTypedArraysEqual;return function(u,l,f){if(u===l)return!0;if(u==null||l==null||typeof u!="object"||typeof l!="object")return u!==u&&l!==l;var b=u.constructor;if(b!==l.constructor)return!1;if(b===Object)return n(u,l,f);if(Et(u))return e(u,l,f);if(U!=null&&U(u))return c(u,l,f);if(b===Date)return r(u,l,f);if(b===RegExp)return a(u,l,f);if(b===Map)return s(u,l,f);if(b===Set)return i(u,l,f);var d=Ot(u);return d===dt?r(u,l,f):d===vt?a(u,l,f):d===bt?s(u,l,f):d===yt?i(u,l,f):d===Nt?typeof u.then!="function"&&typeof l.then!="function"&&n(u,l,f):d===pt?n(u,l,f):d===mt||d===gt||d===wt?o(u,l,f):!1}}function At(t){var e=t.circular,r=t.createCustomConfig,s=t.strict,n={areArraysEqual:s?w:it,areDatesEqual:ut,areMapsEqual:s?x(J,w):J,areObjectsEqual:s?w:lt,arePrimitiveWrappersEqual:ct,areRegExpsEqual:ft,areSetsEqual:s?x(G,w):G,areTypedArraysEqual:s?w:ht};if(r&&(n=V({},n,r(n))),e){var o=$(n.areArraysEqual),a=$(n.areMapsEqual),i=$(n.areObjectsEqual),c=$(n.areSetsEqual);n=V({},n,{areArraysEqual:o,areMapsEqual:a,areObjectsEqual:i,areSetsEqual:c})}return n}function St(t){return function(e,r,s,n,o,a,i){return t(e,r,i)}}function Mt(t){var e=t.circular,r=t.comparator,s=t.createState,n=t.equals,o=t.strict;if(s)return function(c,h){var u=s(),l=u.cache,f=l===void 0?e?new WeakMap:void 0:l,b=u.meta;return r(c,h,{cache:f,equals:n,meta:b,strict:o})};if(e)return function(c,h){return r(c,h,{cache:new WeakMap,equals:n,meta:void 0,strict:o})};var a={cache:void 0,equals:n,meta:void 0,strict:o};return function(c,h){return r(c,h,a)}}var qt=g();g({strict:!0});g({circular:!0});g({circular:!0,strict:!0});g({createInternalComparator:function(){return v}});g({strict:!0,createInternalComparator:function(){return v}});g({circular:!0,createInternalComparator:function(){return v}});g({circular:!0,createInternalComparator:function(){return v},strict:!0});function g(t){t===void 0&&(t={});var e=t.circular,r=e===void 0?!1:e,s=t.createInternalComparator,n=t.createState,o=t.strict,a=o===void 0?!1:o,i=At(t),c=$t(i),h=s?s(c):St(c);return Mt({circular:r,comparator:c,createState:n,equals:h,strict:a})}function jt(t,e){return qt(t,e)}function C(t,e,r){return JSON.stringify(t,(n,o)=>{let a=o;return e&&(a=e(n,a)),a===void 0&&(a=null),a},r)}function ie(t,e){function r(n){return Object.keys(n).forEach(o=>{n[o]===null?n[o]=void 0:typeof n[o]=="object"&&(n[o]=r(n[o]))}),n}const s=JSON.parse(t,e);if(s!==null)return typeof s=="object"?r(s):s}function Ct(t){try{const e=C(t);return e===C(ie(e))}catch{return!1}}const Pt=t=>t.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/"),ue={title:"Platform.Bible menus",type:"object",properties:{mainMenu:{description:"Top level menu for the application",$ref:"#/$defs/multiColumnMenu"},defaultWebViewTopMenu:{description:"Default top menu for web views that don't specify their own",$ref:"#/$defs/multiColumnMenu"},defaultWebViewContextMenu:{description:"Default context menu for web views that don't specify their own",$ref:"#/$defs/singleColumnMenu"},webViewMenus:{description:"Menus that apply per web view in the application",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{$ref:"#/$defs/menusForOneWebView"}},additionalProperties:!1}},required:["mainMenu","defaultWebViewTopMenu","defaultWebViewContextMenu","webViewMenus"],additionalProperties:!1,$defs:{localizeKey:{description:"Identifier for a string that will be localized in a menu based on the user's UI language",type:"string",pattern:"^%[\\w\\-\\.]+%$"},referencedItem:{description:"Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)",type:"string",pattern:"^[\\w\\-]+\\.[\\w\\-]+$"},columnsWithHeaders:{description:"Group of columns that can be combined with other columns to form a multi-column menu",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single column with a header string",type:"object",properties:{label:{description:"Header text for this this column in the UI",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},order:{description:"Relative order of this column compared to other columns (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu groups to this column",type:"boolean"}},required:["label","order"],additionalProperties:!1}},properties:{isExtensible:{description:"Defines whether contributions are allowed to add columns to this multi-column menu",type:"boolean"}}},menuGroups:{description:"Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single group that contains menu items",type:"object",oneOf:[{properties:{column:{description:"Column where this group belongs, not required for single column menus",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["order"],additionalProperties:!1},{properties:{menuItem:{description:"Menu item that anchors the submenu where this group belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["menuItem","order"],additionalProperties:!1}]}},additionalProperties:!1},menuItem:{description:"Single item in a menu that can be clicked on to take an action or can be the parent of a submenu",type:"object",oneOf:[{properties:{id:{description:"ID for this menu item that holds a submenu",$ref:"#/$defs/referencedItem"}},required:["id"]},{properties:{command:{description:"Name of the PAPI command to run when this menu item is selected.",$ref:"#/$defs/referencedItem"},iconPathBefore:{description:"Path to the icon to display before the menu text",type:"string"},iconPathAfter:{description:"Path to the icon to display after the menu text",type:"string"}},required:["command"]}],properties:{label:{description:"Key that represents the text of this menu item to display",$ref:"#/$defs/localizeKey"},tooltip:{description:"Key that represents the text to display if a mouse pointer hovers over the menu item",$ref:"#/$defs/localizeKey"},searchTerms:{description:"Key that represents additional words the platform should reference when users are searching for menu items",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},group:{description:"Group to which this menu item belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this menu item compared to other menu items in the same group (sorted ascending)",type:"number"}},required:["label","group","order"],unevaluatedProperties:!1},groupsAndItems:{description:"Core schema for a column",type:"object",properties:{groups:{description:"Groups that belong in this menu",$ref:"#/$defs/menuGroups"},items:{description:"List of menu items that belong in this menu",type:"array",items:{$ref:"#/$defs/menuItem"},uniqueItems:!0}},required:["groups","items"]},singleColumnMenu:{description:"Menu that contains a column without a header",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"}],unevaluatedProperties:!1},multiColumnMenu:{description:"Menu that can contain multiple columns with headers",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"},{properties:{columns:{description:"Columns that belong in this menu",$ref:"#/$defs/columnsWithHeaders"}},required:["columns"]}],unevaluatedProperties:!1},menusForOneWebView:{description:"Set of menus that are associated with a single tab",type:"object",properties:{includeDefaults:{description:"Indicates whether the platform default menus should be included for this webview",type:"boolean"},topMenu:{description:"Menu that opens when you click on the top left corner of a tab",$ref:"#/$defs/multiColumnMenu"},contextMenu:{description:"Menu that opens when you right click on the main body/area of a tab",$ref:"#/$defs/singleColumnMenu"}},additionalProperties:!1}}};Object.freeze(ue);exports.AsyncVariable=ge;exports.DocumentCombinerEngine=Me;exports.FIRST_SCR_BOOK_NUM=L;exports.FIRST_SCR_CHAPTER_NUM=X;exports.FIRST_SCR_VERSE_NUM=Q;exports.LAST_SCR_BOOK_NUM=Z;exports.Mutex=W;exports.MutexMap=Te;exports.PlatformEventEmitter=Pe;exports.UnsubscriberAsyncList=Ce;exports.aggregateUnsubscriberAsyncs=_e;exports.aggregateUnsubscribers=xe;exports.at=Ke;exports.charAt=Le;exports.codePointAt=Ze;exports.createSyncProxyForAsyncObject=Se;exports.debounce=ve;exports.deepClone=E;exports.deepEqual=jt;exports.deserialize=ie;exports.endsWith=Xe;exports.getAllObjectFunctionNames=Ae;exports.getChaptersForBook=Y;exports.getErrorMessage=Oe;exports.groupBy=ye;exports.htmlEncode=Pt;exports.includes=re;exports.indexOf=S;exports.isSerializable=Ct;exports.isString=F;exports.lastIndexOf=se;exports.length=m;exports.menuDocumentSchema=ue;exports.newGuid=Ne;exports.normalize=Qe;exports.offsetBook=Re;exports.offsetChapter=De;exports.offsetVerse=Ie;exports.padEnd=Ye;exports.padStart=et;exports.serialize=C;exports.slice=tt;exports.split=rt;exports.startsWith=st;exports.substring=O;exports.toArray=ne;exports.wait=H;exports.waitForDuration=$e; //# sourceMappingURL=index.cjs.map diff --git a/lib/platform-bible-utils/dist/index.cjs.map b/lib/platform-bible-utils/dist/index.cjs.map index e2cf90cd78..2994992c72 100644 --- a/lib/platform-bible-utils/dist/index.cjs.map +++ b/lib/platform-bible-utils/dist/index.cjs.map @@ -1 +1 @@ -{"version":3,"file":"index.cjs","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/mutex.ts","../src/mutex-map.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { Mutex as AsyncMutex } from 'async-mutex';\n\n// Extending Mutex from async-mutex so we can add JSDoc\n\n/**\n * Class that allows calling asynchronous functions multiple times at once while only running one at\n * a time.\n *\n * @example\n *\n * ```typescript\n * const mutex = new Mutex();\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n * ```\n *\n * See [`async-mutex`](https://www.npmjs.com/package/async-mutex) for more information.\n */\nclass Mutex extends AsyncMutex {}\n\nexport default Mutex;\n","import Mutex from './mutex';\n\n/** Map of {@link Mutex}es that automatically (lazily) generates a new {@link Mutex} for any new key */\nclass MutexMap {\n private mutexesByID = new Map();\n\n get(mutexID: string): Mutex {\n let retVal = this.mutexesByID.get(mutexID);\n if (retVal) return retVal;\n\n retVal = new Mutex();\n this.mutexesByID.set(mutexID, retVal);\n return retVal;\n }\n}\n\nexport default MutexMap;\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * Finds the Unicode code point at the given index\n *\n * @param {string} string String to index\n * @param {number} index Position of the character to be returned in range of 0 to -length(string)\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > length(string) || index < -length(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * Always indexes string as a sequence of Unicode code points\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, empty string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > length(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to index\n * @param {number} index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {number | undefined} Non-negative integer representing the code point value of the\n * character at the given index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > length(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * Determines whether a string ends with the characters of this string. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Characters to search for at the end of the string\n * @param {number} [endPosition=length(string)] End position where searchString is expected to be\n * found. Default is `length(string)`\n * @returns {boolean} True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = length(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + length(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * Performs a case-sensitive search to determine if searchString is found in string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString String to search for\n * @param {string} [position=0] Position within the string to start searching for searchString.\n * Default is `0`\n * @returns {boolean} True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * Returns the index of the first occurrence of a given string. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The string to search for\n * @param {number} [position=0] Start of searching. Default is `0`\n * @returns {number} Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * Searches this string and returns the index of the last occurrence of the specified substring.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Substring to search for\n * @param {number} [position=+Infinity] The method returns the index of the last occurrence of the\n * specified substring at a position less than or equal to position. . Default is `+Infinity`\n * @returns {number} Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(\n string: string,\n searchString: string,\n position: number = +Infinity,\n): number {\n let validatedPosition = position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= length(string)) {\n validatedPosition = length(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, length(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * Returns the length of a string. This function handles Unicode code points instead of UTF-16\n * character codes.\n *\n * @param {string} string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function length(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * Returns the Unicode Normalization Form of this string.\n *\n * @param {string} string The starting string\n * @param {'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'} [form='NFC'] Form specifying the Unicode\n * Normalization Form. Default is `'NFC'`\n * @returns {string} A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within targetLength, it will be truncated. Default is `\" \"`\n * @returns {string} String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\nfunction correctSliceIndex(stringLength: number, index: number) {\n if (index > stringLength) return stringLength;\n if (index < -stringLength) return 0;\n if (index < 0) return index + stringLength;\n return index;\n}\n\n/**\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The starting string\n * @param {number} indexStart The index of the first character to include in the returned substring.\n * @param {number} indexEnd The index of the first character to exclude from the returned substring.\n * @returns {string} A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const stringLength: number = length(string);\n if (\n indexStart > stringLength ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(\n indexStart > 0 &&\n indexStart < stringLength &&\n indexEnd < 0 &&\n indexEnd > -stringLength\n )) ||\n indexEnd < -stringLength ||\n (indexStart < 0 && indexStart > -stringLength && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(stringLength, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The string to split\n * @param {string | RegExp} separator The pattern describing where each split should occur\n * @param {number} splitLimit Limit on the number of substrings to be included in the array. Splits\n * the string at each occurrence of specified separator, but stops when limit entries have been\n * placed in the array.\n * @returns {string[] | undefined} An array of strings, split at each point where separator occurs\n * in the starting string. Returns undefined if separator is not found in string.\n */\nexport function split(\n string: string,\n separator: string | RegExp,\n splitLimit?: number,\n): string[] | undefined {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !separator.flags.includes('g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return undefined;\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = length(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate. This function handles Unicode code points instead of UTF-16 character\n * codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The characters to be searched for at the start of this string.\n * @param {number} [position=0] The start position at which searchString is expected to be found\n * (the index of searchString's first character). Default is `0`\n * @returns {boolean} True if the given characters are found at the beginning of the string,\n * including when searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * Returns a substring by providing start and length. This function handles Unicode code points\n * instead of UTF-16 character codes. This function is not exported because it is considered\n * deprecated, however it is still useful as a local helper function.\n *\n * @param {string} string String to be divided\n * @param {number} [begin=Start of string] Start position. Default is `Start of string`\n * @param {number} [len=String length minus start parameter] Length of result. Default is `String\n * length minus start parameter`. Default is `String length minus start parameter`\n * @returns {string} Substring from starting string\n */\nfunction substr(string: string, begin: number = 0, len: number = length(string) - begin): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * Returns a substring by providing start and end position. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to be divided\n * @param {string} begin Start position\n * @param {number} [end=End of string] End position. Default is `End of string`\n * @returns {string} Substring from starting string\n */\nexport function substring(\n string: string,\n begin?: number | undefined,\n end: number | undefined = length(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * Converts a string to an array of string characters. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param {string} string String to convert to array\n * @returns {string[]} An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","Mutex","AsyncMutex","MutexMap","mutexID","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","stringLength","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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Aa,8DACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,WAAY,OAAO,EAC9B,qBAAsB,EACxB,CACF,CACF,CACF,EACA,qBAAsB,EACxB,EACA,SAAU,CACR,YACE,mGACF,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,GAAI,CACF,YAAa,6CACb,KAAM,wBACR,CACF,EACA,SAAU,CAAC,IAAI,CACjB,EACA,CACE,WAAY,CACV,QAAS,CACP,YAAa,mEACb,KAAM,wBACR,EACA,eAAgB,CACd,YAAa,mDACb,KAAM,QACR,EACA,cAAe,CACb,YAAa,kDACb,KAAM,QACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,WAAY,CACV,MAAO,CACL,YAAa,4DACb,KAAM,qBACR,EACA,QAAS,CACP,YACE,uFACF,KAAM,qBACR,EACA,YAAa,CACX,YACE,6GACF,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YAAa,wCACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,qGACF,KAAM,QACR,CACF,EACA,SAAU,CAAC,QAAS,QAAS,OAAO,EACpC,sBAAuB,EACzB,EACA,eAAgB,CACd,YAAa,2BACb,KAAM,SACN,WAAY,CACV,OAAQ,CACN,YAAa,kCACb,KAAM,oBACR,EACA,MAAO,CACL,YAAa,8CACb,KAAM,QACN,MAAO,CAAE,KAAM,kBAAmB,EAClC,YAAa,EACf,CACF,EACA,SAAU,CAAC,SAAU,OAAO,CAC9B,EACA,iBAAkB,CAChB,YAAa,+CACb,KAAM,SACN,MAAO,CAAC,CAAE,KAAM,yBAA0B,EAC1C,sBAAuB,EACzB,EACA,gBAAiB,CACf,YAAa,sDACb,KAAM,SACN,MAAO,CACL,CAAE,KAAM,wBAAyB,EACjC,CACE,WAAY,CACV,QAAS,CACP,YAAa,mCACb,KAAM,4BACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,sBAAuB,EACzB,EACA,mBAAoB,CAClB,YAAa,qDACb,KAAM,SACN,WAAY,CACV,gBAAiB,CACf,YACE,mFACF,KAAM,SACR,EACA,QAAS,CACP,YAAa,iEACb,KAAM,yBACR,EACA,YAAa,CACX,YAAa,sEACb,KAAM,0BACR,CACF,EACA,qBAAsB,EACxB,CACF,CACF,EAEA,OAAO,OAAOA,EAAkB","x_google_ignoreList":[9,10,12]} \ No newline at end of file +{"version":3,"file":"index.cjs","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/mutex.ts","../src/mutex-map.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { Mutex as AsyncMutex } from 'async-mutex';\n\n// Extending Mutex from async-mutex so we can add JSDoc\n\n/**\n * Class that allows calling asynchronous functions multiple times at once while only running one at\n * a time.\n *\n * @example\n *\n * ```typescript\n * const mutex = new Mutex();\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n * ```\n *\n * See [`async-mutex`](https://www.npmjs.com/package/async-mutex) for more information.\n */\nclass Mutex extends AsyncMutex {}\n\nexport default Mutex;\n","import Mutex from './mutex';\n\n/** Map of {@link Mutex}es that automatically (lazily) generates a new {@link Mutex} for any new key */\nclass MutexMap {\n private mutexesByID = new Map();\n\n get(mutexID: string): Mutex {\n let retVal = this.mutexesByID.get(mutexID);\n if (retVal) return retVal;\n\n retVal = new Mutex();\n this.mutexesByID.set(mutexID, retVal);\n return retVal;\n }\n}\n\nexport default MutexMap;\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * Finds the Unicode code point at the given index\n *\n * @param {string} string String to index\n * @param {number} index Position of the character to be returned in range of 0 to -length(string)\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > length(string) || index < -length(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * Always indexes string as a sequence of Unicode code points\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, empty string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > length(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to index\n * @param {number} index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {number | undefined} Non-negative integer representing the code point value of the\n * character at the given index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > length(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * Determines whether a string ends with the characters of this string. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Characters to search for at the end of the string\n * @param {number} [endPosition=length(string)] End position where searchString is expected to be\n * found. Default is `length(string)`\n * @returns {boolean} True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = length(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + length(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * Performs a case-sensitive search to determine if searchString is found in string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString String to search for\n * @param {string} [position=0] Position within the string to start searching for searchString.\n * Default is `0`\n * @returns {boolean} True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * Returns the index of the first occurrence of a given string. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The string to search for\n * @param {number} [position=0] Start of searching. Default is `0`\n * @returns {number} Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * Searches this string and returns the index of the last occurrence of the specified substring.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Substring to search for\n * @param {number} [position=+Infinity] The method returns the index of the last occurrence of the\n * specified substring at a position less than or equal to position. . Default is `+Infinity`\n * @returns {number} Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(\n string: string,\n searchString: string,\n position: number = +Infinity,\n): number {\n let validatedPosition = position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= length(string)) {\n validatedPosition = length(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, length(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * Returns the length of a string. This function handles Unicode code points instead of UTF-16\n * character codes.\n *\n * @param {string} string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function length(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * Returns the Unicode Normalization Form of this string.\n *\n * @param {string} string The starting string\n * @param {'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'} [form='NFC'] Form specifying the Unicode\n * Normalization Form. Default is `'NFC'`\n * @returns {string} A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within targetLength, it will be truncated. Default is `\" \"`\n * @returns {string} String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\nfunction correctSliceIndex(stringLength: number, index: number) {\n if (index > stringLength) return stringLength;\n if (index < -stringLength) return 0;\n if (index < 0) return index + stringLength;\n return index;\n}\n\n/**\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The starting string\n * @param {number} indexStart The index of the first character to include in the returned substring.\n * @param {number} indexEnd The index of the first character to exclude from the returned substring.\n * @returns {string} A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const stringLength: number = length(string);\n if (\n indexStart > stringLength ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(\n indexStart > 0 &&\n indexStart < stringLength &&\n indexEnd < 0 &&\n indexEnd > -stringLength\n )) ||\n indexEnd < -stringLength ||\n (indexStart < 0 && indexStart > -stringLength && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(stringLength, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The string to split\n * @param {string | RegExp} separator The pattern describing where each split should occur\n * @param {number} splitLimit Limit on the number of substrings to be included in the array. Splits\n * the string at each occurrence of specified separator, but stops when limit entries have been\n * placed in the array.\n * @returns {string[] | undefined} An array of strings, split at each point where separator occurs\n * in the starting string. Returns undefined if separator is not found in string.\n */\nexport function split(\n string: string,\n separator: string | RegExp,\n splitLimit?: number,\n): string[] | undefined {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !includes(separator.flags, 'g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return undefined;\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = length(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate. This function handles Unicode code points instead of UTF-16 character\n * codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The characters to be searched for at the start of this string.\n * @param {number} [position=0] The start position at which searchString is expected to be found\n * (the index of searchString's first character). Default is `0`\n * @returns {boolean} True if the given characters are found at the beginning of the string,\n * including when searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * Returns a substring by providing start and length. This function handles Unicode code points\n * instead of UTF-16 character codes. This function is not exported because it is considered\n * deprecated, however it is still useful as a local helper function.\n *\n * @param {string} string String to be divided\n * @param {number} [begin=Start of string] Start position. Default is `Start of string`\n * @param {number} [len=String length minus start parameter] Length of result. Default is `String\n * length minus start parameter`. Default is `String length minus start parameter`\n * @returns {string} Substring from starting string\n */\nfunction substr(string: string, begin: number = 0, len: number = length(string) - begin): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * Returns a substring by providing start and end position. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to be divided\n * @param {string} begin Start position\n * @param {number} [end=End of string] End position. Default is `End of string`\n * @returns {string} Substring from starting string\n */\nexport function substring(\n string: string,\n begin?: number | undefined,\n end: number | undefined = length(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * Converts a string to an array of string characters. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param {string} string String to convert to array\n * @returns {string[]} An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","Mutex","AsyncMutex","MutexMap","mutexID","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","stringLength","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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,YAAa,8DACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,WAAY,OAAO,EAC9B,qBAAsB,EACxB,CACF,CACF,CACF,EACA,qBAAsB,EACxB,EACA,SAAU,CACR,YACE,mGACF,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,GAAI,CACF,YAAa,6CACb,KAAM,wBACR,CACF,EACA,SAAU,CAAC,IAAI,CACjB,EACA,CACE,WAAY,CACV,QAAS,CACP,YAAa,mEACb,KAAM,wBACR,EACA,eAAgB,CACd,YAAa,mDACb,KAAM,QACR,EACA,cAAe,CACb,YAAa,kDACb,KAAM,QACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,WAAY,CACV,MAAO,CACL,YAAa,4DACb,KAAM,qBACR,EACA,QAAS,CACP,YACE,uFACF,KAAM,qBACR,EACA,YAAa,CACX,YACE,6GACF,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YAAa,wCACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,qGACF,KAAM,QACR,CACF,EACA,SAAU,CAAC,QAAS,QAAS,OAAO,EACpC,sBAAuB,EACzB,EACA,eAAgB,CACd,YAAa,2BACb,KAAM,SACN,WAAY,CACV,OAAQ,CACN,YAAa,kCACb,KAAM,oBACR,EACA,MAAO,CACL,YAAa,8CACb,KAAM,QACN,MAAO,CAAE,KAAM,kBAAmB,EAClC,YAAa,EACf,CACF,EACA,SAAU,CAAC,SAAU,OAAO,CAC9B,EACA,iBAAkB,CAChB,YAAa,+CACb,KAAM,SACN,MAAO,CAAC,CAAE,KAAM,yBAA0B,EAC1C,sBAAuB,EACzB,EACA,gBAAiB,CACf,YAAa,sDACb,KAAM,SACN,MAAO,CACL,CAAE,KAAM,wBAAyB,EACjC,CACE,WAAY,CACV,QAAS,CACP,YAAa,mCACb,KAAM,4BACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,sBAAuB,EACzB,EACA,mBAAoB,CAClB,YAAa,qDACb,KAAM,SACN,WAAY,CACV,gBAAiB,CACf,YACE,mFACF,KAAM,SACR,EACA,QAAS,CACP,YAAa,iEACb,KAAM,yBACR,EACA,YAAa,CACX,YAAa,sEACb,KAAM,0BACR,CACF,EACA,qBAAsB,EACxB,CACF,CACF,EAEA,OAAO,OAAOA,EAAkB","x_google_ignoreList":[9,10,12]} \ No newline at end of file diff --git a/lib/platform-bible-utils/dist/index.js b/lib/platform-bible-utils/dist/index.js index 73c15202ec..1671bbc49d 100644 --- a/lib/platform-bible-utils/dist/index.js +++ b/lib/platform-bible-utils/dist/index.js @@ -2,7 +2,7 @@ var te = Object.defineProperty; var re = (t, e, r) => e in t ? te(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r; var p = (t, e, r) => (re(t, typeof e != "symbol" ? e + "" : e, r), r); import { Mutex as se } from "async-mutex"; -class nt { +class ot { /** * Creates an instance of the class * @@ -76,7 +76,7 @@ class nt { this.resolver = void 0, this.rejecter = void 0, Object.freeze(this); } } -function ot() { +function at() { return "00-0-4-1-000".replace( /[^-]/g, (t) => ( @@ -92,7 +92,7 @@ function ne(t) { function O(t) { return JSON.parse(JSON.stringify(t)); } -function at(t, e = 300) { +function it(t, e = 300) { if (ne(t)) throw new Error("Tried to debounce a string! Could be XSS"); let r; @@ -100,7 +100,7 @@ function at(t, e = 300) { clearTimeout(r), r = setTimeout(() => t(...s), e); }; } -function it(t, e, r) { +function ut(t, e, r) { const s = /* @__PURE__ */ new Map(); return t.forEach((n) => { const o = e(n), a = s.get(o), i = r ? r(n, o) : n; @@ -123,18 +123,18 @@ function ae(t) { return new Error(String(t)); } } -function ut(t) { +function lt(t) { return ae(t).message; } function ie(t) { return new Promise((e) => setTimeout(e, t)); } -function lt(t, e) { +function ct(t, e) { const r = ie(e).then(() => { }); return Promise.any([r, t()]); } -function ct(t, e = "obj") { +function ft(t, e = "obj") { const r = /* @__PURE__ */ new Set(); Object.getOwnPropertyNames(t).forEach((n) => { try { @@ -154,14 +154,14 @@ function ct(t, e = "obj") { }), s = Object.getPrototypeOf(s); return r; } -function ft(t, e = {}) { +function ht(t, e = {}) { return new Proxy(e, { get(r, s) { return s in r ? r[s] : async (...n) => (await t())[s](...n); } }); } -class ht { +class pt { /** * Create a DocumentCombinerEngine instance * @@ -273,7 +273,7 @@ function U(t, e, r) { s[n] = e[n]; }), s; } -class pt { +class mt { constructor(e = "Anonymous") { p(this, "unsubscribers", /* @__PURE__ */ new Set()); this.name = e; @@ -298,7 +298,7 @@ class pt { return this.unsubscribers.clear(), r.every((s, n) => (s || console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${n} failed!`), s)); } } -class mt { +class dt { constructor() { /** * Subscribes a function to run when this event is emitted. @@ -369,7 +369,7 @@ class mt { } class ce extends se { } -class dt { +class bt { constructor() { p(this, "mutexesByID", /* @__PURE__ */ new Map()); } @@ -449,21 +449,21 @@ const k = [ ], fe = 1, he = k.length - 1, pe = 1, me = 1, de = (t) => { var e; return ((e = k[t]) == null ? void 0 : e.chapters) ?? -1; -}, bt = (t, e) => ({ +}, Nt = (t, e) => ({ bookNum: Math.max(fe, Math.min(t.bookNum + e, he)), chapterNum: 1, verseNum: 1 -}), Nt = (t, e) => ({ +}), gt = (t, e) => ({ ...t, chapterNum: Math.min( Math.max(pe, t.chapterNum + e), de(t.bookNum) ), verseNum: 1 -}), gt = (t, e) => ({ +}), vt = (t, e) => ({ ...t, verseNum: Math.max(me, t.verseNum + e) -}), vt = (t) => (...e) => t.map((s) => s(...e)).every((s) => s), yt = (t) => async (...e) => { +}), yt = (t) => (...e) => t.map((s) => s(...e)).every((s) => s), wt = (t) => async (...e) => { const r = t.map(async (s) => s(...e)); return (await Promise.all(r)).every((s) => s); }; @@ -548,29 +548,29 @@ function $e(t, e, r) { return o ? a : -1; } var Ae = g.indexOf = $e; -function wt(t, e) { +function Et(t, e) { if (!(e > d(t) || e < -d(t))) return q(t, e, 1); } -function Et(t, e) { +function Ot(t, e) { return e < 0 || e > d(t) - 1 ? "" : q(t, e, 1); } -function Ot(t, e) { +function $t(t, e) { if (!(e < 0 || e > d(t) - 1)) return q(t, e, 1).codePointAt(0); } -function $t(t, e, r = d(t)) { - const s = qe(t, e); +function At(t, e, r = d(t)) { + const s = je(t, e); return !(s === -1 || s + d(e) !== r); } -function At(t, e, r = 0) { +function qe(t, e, r = 0) { const s = $(t, r); return C(s, e) !== -1; } function C(t, e, r = 0) { return Ae(t, e, r); } -function qe(t, e, r = 1 / 0) { +function je(t, e, r = 1 / 0) { let s = r; s < 0 ? s = 0 : s >= d(t) && (s = d(t) - 1); for (let n = s; n >= 0; n--) @@ -606,9 +606,9 @@ function Ct(t, e, r) { if (r !== void 0 && r <= 0) return [t]; if (e === "") - return je(t).slice(0, r); + return Me(t).slice(0, r); let n = e; - (typeof e == "string" || e instanceof RegExp && !e.flags.includes("g")) && (n = new RegExp(e, "g")); + (typeof e == "string" || e instanceof RegExp && !qe(e.flags, "g")) && (n = new RegExp(e, "g")); const o = t.match(n); let a = 0; if (o) { @@ -629,10 +629,10 @@ function q(t, e = 0, r = d(t) - e) { function $(t, e, r = d(t)) { return ye(t, e, r); } -function je(t) { +function Me(t) { return ge(t); } -var Me = Object.getOwnPropertyNames, Se = Object.getOwnPropertySymbols, Ce = Object.prototype.hasOwnProperty; +var Se = Object.getOwnPropertyNames, Ce = Object.getOwnPropertySymbols, Pe = Object.prototype.hasOwnProperty; function I(t, e) { return function(s, n, o) { return t(s, n, o) && e(s, n, o); @@ -651,16 +651,16 @@ function E(t) { }; } function x(t) { - return Me(t).concat(Se(t)); + return Se(t).concat(Ce(t)); } var K = Object.hasOwn || function(t, e) { - return Ce.call(t, e); + return Pe.call(t, e); }; function v(t, e) { return t || e ? t === e : t === e || t !== t && e !== e; } var L = "_owner", z = Object.getOwnPropertyDescriptor, _ = Object.keys; -function Pe(t, e, r) { +function De(t, e, r) { var s = t.length; if (e.length !== s) return !1; @@ -669,7 +669,7 @@ function Pe(t, e, r) { return !1; return !0; } -function De(t, e) { +function Te(t, e) { return v(t.getTime(), e.getTime()); } function J(t, e, r) { @@ -686,7 +686,7 @@ function J(t, e, r) { } return !0; } -function Te(t, e, r) { +function Re(t, e, r) { var s = _(t), n = s.length; if (_(e).length !== n) return !1; @@ -704,10 +704,10 @@ function w(t, e, r) { return !1; return !0; } -function Re(t, e) { +function Ie(t, e) { return v(t.valueOf(), e.valueOf()); } -function Ie(t, e) { +function xe(t, e) { return t.source === e.source && t.flags === e.flags; } function B(t, e, r) { @@ -721,7 +721,7 @@ function B(t, e, r) { } return !0; } -function xe(t, e) { +function ze(t, e) { var r = t.length; if (e.length !== r) return !1; @@ -730,8 +730,8 @@ function xe(t, e) { return !1; return !0; } -var ze = "[object Arguments]", _e = "[object Boolean]", Je = "[object Date]", Be = "[object Map]", Ge = "[object Number]", Ve = "[object Object]", He = "[object RegExp]", Ue = "[object Set]", ke = "[object String]", Fe = Array.isArray, G = typeof ArrayBuffer == "function" && ArrayBuffer.isView ? ArrayBuffer.isView : null, V = Object.assign, We = Object.prototype.toString.call.bind(Object.prototype.toString); -function Ke(t) { +var _e = "[object Arguments]", Je = "[object Boolean]", Be = "[object Date]", Ge = "[object Map]", Ve = "[object Number]", He = "[object Object]", Ue = "[object RegExp]", ke = "[object Set]", Fe = "[object String]", We = Array.isArray, G = typeof ArrayBuffer == "function" && ArrayBuffer.isView ? ArrayBuffer.isView : null, V = Object.assign, Ke = Object.prototype.toString.call.bind(Object.prototype.toString); +function Le(t) { var e = t.areArraysEqual, r = t.areDatesEqual, s = t.areMapsEqual, n = t.areObjectsEqual, o = t.arePrimitiveWrappersEqual, a = t.areRegExpsEqual, i = t.areSetsEqual, c = t.areTypedArraysEqual; return function(u, l, f) { if (u === l) @@ -743,7 +743,7 @@ function Ke(t) { return !1; if (b === Object) return n(u, l, f); - if (Fe(u)) + if (We(u)) return e(u, l, f); if (G != null && G(u)) return c(u, l, f); @@ -755,20 +755,20 @@ function Ke(t) { return s(u, l, f); if (b === Set) return i(u, l, f); - var m = We(u); - return m === Je ? r(u, l, f) : m === He ? a(u, l, f) : m === Be ? s(u, l, f) : m === Ue ? i(u, l, f) : m === Ve ? typeof u.then != "function" && typeof l.then != "function" && n(u, l, f) : m === ze ? n(u, l, f) : m === _e || m === Ge || m === ke ? o(u, l, f) : !1; + var m = Ke(u); + return m === Be ? r(u, l, f) : m === Ue ? a(u, l, f) : m === Ge ? s(u, l, f) : m === ke ? i(u, l, f) : m === He ? typeof u.then != "function" && typeof l.then != "function" && n(u, l, f) : m === _e ? n(u, l, f) : m === Je || m === Ve || m === Fe ? o(u, l, f) : !1; }; } -function Le(t) { +function Ze(t) { var e = t.circular, r = t.createCustomConfig, s = t.strict, n = { - areArraysEqual: s ? w : Pe, - areDatesEqual: De, + areArraysEqual: s ? w : De, + areDatesEqual: Te, areMapsEqual: s ? I(J, w) : J, - areObjectsEqual: s ? w : Te, - arePrimitiveWrappersEqual: Re, - areRegExpsEqual: Ie, + areObjectsEqual: s ? w : Re, + arePrimitiveWrappersEqual: Ie, + areRegExpsEqual: xe, areSetsEqual: s ? I(B, w) : B, - areTypedArraysEqual: s ? w : xe + areTypedArraysEqual: s ? w : ze }; if (r && (n = V({}, n, r(n))), e) { var o = E(n.areArraysEqual), a = E(n.areMapsEqual), i = E(n.areObjectsEqual), c = E(n.areSetsEqual); @@ -781,12 +781,12 @@ function Le(t) { } return n; } -function Ze(t) { +function Xe(t) { return function(e, r, s, n, o, a, i) { return t(e, r, i); }; } -function Xe(t) { +function Qe(t) { var e = t.circular, r = t.comparator, s = t.createState, n = t.equals, o = t.strict; if (s) return function(c, h) { @@ -817,7 +817,7 @@ function Xe(t) { return r(c, h, a); }; } -var Qe = N(); +var Ye = N(); N({ strict: !0 }); N({ circular: !0 }); N({ @@ -850,11 +850,11 @@ N({ }); function N(t) { t === void 0 && (t = {}); - var e = t.circular, r = e === void 0 ? !1 : e, s = t.createInternalComparator, n = t.createState, o = t.strict, a = o === void 0 ? !1 : o, i = Le(t), c = Ke(i), h = s ? s(c) : Ze(c); - return Xe({ circular: r, comparator: c, createState: n, equals: h, strict: a }); + var e = t.circular, r = e === void 0 ? !1 : e, s = t.createInternalComparator, n = t.createState, o = t.strict, a = o === void 0 ? !1 : o, i = Ze(t), c = Le(i), h = s ? s(c) : Xe(c); + return Qe({ circular: r, comparator: c, createState: n, equals: h, strict: a }); } function Dt(t, e) { - return Qe(t, e); + return Ye(t, e); } function H(t, e, r) { return JSON.stringify(t, (n, o) => { @@ -862,7 +862,7 @@ function H(t, e, r) { return e && (a = e(n, a)), a === void 0 && (a = null), a; }, r); } -function Ye(t, e) { +function et(t, e) { function r(n) { return Object.keys(n).forEach((o) => { n[o] === null ? n[o] = void 0 : typeof n[o] == "object" && (n[o] = r(n[o])); @@ -875,12 +875,12 @@ function Ye(t, e) { function Tt(t) { try { const e = H(t); - return e === H(Ye(e)); + return e === H(et(e)); } catch { return !1; } } -const Rt = (t) => t.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'").replace(/\//g, "/"), et = { +const Rt = (t) => t.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'").replace(/\//g, "/"), tt = { title: "Platform.Bible menus", type: "object", properties: { @@ -1126,46 +1126,46 @@ const Rt = (t) => t.replace(/&/g, "&").replace(//g, " } } }; -Object.freeze(et); +Object.freeze(tt); export { - nt as AsyncVariable, - ht as DocumentCombinerEngine, + ot as AsyncVariable, + pt as DocumentCombinerEngine, fe as FIRST_SCR_BOOK_NUM, pe as FIRST_SCR_CHAPTER_NUM, me as FIRST_SCR_VERSE_NUM, he as LAST_SCR_BOOK_NUM, ce as Mutex, - dt as MutexMap, - mt as PlatformEventEmitter, - pt as UnsubscriberAsyncList, - yt as aggregateUnsubscriberAsyncs, - vt as aggregateUnsubscribers, - wt as at, - Et as charAt, - Ot as codePointAt, - ft as createSyncProxyForAsyncObject, - at as debounce, + bt as MutexMap, + dt as PlatformEventEmitter, + mt as UnsubscriberAsyncList, + wt as aggregateUnsubscriberAsyncs, + yt as aggregateUnsubscribers, + Et as at, + Ot as charAt, + $t as codePointAt, + ht as createSyncProxyForAsyncObject, + it as debounce, O as deepClone, Dt as deepEqual, - Ye as deserialize, - $t as endsWith, - ct as getAllObjectFunctionNames, + et as deserialize, + At as endsWith, + ft as getAllObjectFunctionNames, de as getChaptersForBook, - ut as getErrorMessage, - it as groupBy, + lt as getErrorMessage, + ut as groupBy, Rt as htmlEncode, - At as includes, + qe as includes, C as indexOf, Tt as isSerializable, ne as isString, - qe as lastIndexOf, + je as lastIndexOf, d as length, - et as menuDocumentSchema, - ot as newGuid, + tt as menuDocumentSchema, + at as newGuid, qt as normalize, - bt as offsetBook, - Nt as offsetChapter, - gt as offsetVerse, + Nt as offsetBook, + gt as offsetChapter, + vt as offsetVerse, jt as padEnd, Mt as padStart, H as serialize, @@ -1173,8 +1173,8 @@ export { Ct as split, Pt as startsWith, $ as substring, - je as toArray, + Me as toArray, ie as wait, - lt as waitForDuration + ct as waitForDuration }; //# sourceMappingURL=index.js.map diff --git a/lib/platform-bible-utils/dist/index.js.map b/lib/platform-bible-utils/dist/index.js.map index fa7c777f41..e38bd935c0 100644 --- a/lib/platform-bible-utils/dist/index.js.map +++ b/lib/platform-bible-utils/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/mutex.ts","../src/mutex-map.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { Mutex as AsyncMutex } from 'async-mutex';\n\n// Extending Mutex from async-mutex so we can add JSDoc\n\n/**\n * Class that allows calling asynchronous functions multiple times at once while only running one at\n * a time.\n *\n * @example\n *\n * ```typescript\n * const mutex = new Mutex();\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n * ```\n *\n * See [`async-mutex`](https://www.npmjs.com/package/async-mutex) for more information.\n */\nclass Mutex extends AsyncMutex {}\n\nexport default Mutex;\n","import Mutex from './mutex';\n\n/** Map of {@link Mutex}es that automatically (lazily) generates a new {@link Mutex} for any new key */\nclass MutexMap {\n private mutexesByID = new Map();\n\n get(mutexID: string): Mutex {\n let retVal = this.mutexesByID.get(mutexID);\n if (retVal) return retVal;\n\n retVal = new Mutex();\n this.mutexesByID.set(mutexID, retVal);\n return retVal;\n }\n}\n\nexport default MutexMap;\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * Finds the Unicode code point at the given index\n *\n * @param {string} string String to index\n * @param {number} index Position of the character to be returned in range of 0 to -length(string)\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > length(string) || index < -length(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * Always indexes string as a sequence of Unicode code points\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, empty string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > length(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to index\n * @param {number} index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {number | undefined} Non-negative integer representing the code point value of the\n * character at the given index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > length(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * Determines whether a string ends with the characters of this string. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Characters to search for at the end of the string\n * @param {number} [endPosition=length(string)] End position where searchString is expected to be\n * found. Default is `length(string)`\n * @returns {boolean} True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = length(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + length(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * Performs a case-sensitive search to determine if searchString is found in string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString String to search for\n * @param {string} [position=0] Position within the string to start searching for searchString.\n * Default is `0`\n * @returns {boolean} True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * Returns the index of the first occurrence of a given string. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The string to search for\n * @param {number} [position=0] Start of searching. Default is `0`\n * @returns {number} Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * Searches this string and returns the index of the last occurrence of the specified substring.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Substring to search for\n * @param {number} [position=+Infinity] The method returns the index of the last occurrence of the\n * specified substring at a position less than or equal to position. . Default is `+Infinity`\n * @returns {number} Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(\n string: string,\n searchString: string,\n position: number = +Infinity,\n): number {\n let validatedPosition = position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= length(string)) {\n validatedPosition = length(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, length(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * Returns the length of a string. This function handles Unicode code points instead of UTF-16\n * character codes.\n *\n * @param {string} string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function length(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * Returns the Unicode Normalization Form of this string.\n *\n * @param {string} string The starting string\n * @param {'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'} [form='NFC'] Form specifying the Unicode\n * Normalization Form. Default is `'NFC'`\n * @returns {string} A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within targetLength, it will be truncated. Default is `\" \"`\n * @returns {string} String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\nfunction correctSliceIndex(stringLength: number, index: number) {\n if (index > stringLength) return stringLength;\n if (index < -stringLength) return 0;\n if (index < 0) return index + stringLength;\n return index;\n}\n\n/**\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The starting string\n * @param {number} indexStart The index of the first character to include in the returned substring.\n * @param {number} indexEnd The index of the first character to exclude from the returned substring.\n * @returns {string} A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const stringLength: number = length(string);\n if (\n indexStart > stringLength ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(\n indexStart > 0 &&\n indexStart < stringLength &&\n indexEnd < 0 &&\n indexEnd > -stringLength\n )) ||\n indexEnd < -stringLength ||\n (indexStart < 0 && indexStart > -stringLength && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(stringLength, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The string to split\n * @param {string | RegExp} separator The pattern describing where each split should occur\n * @param {number} splitLimit Limit on the number of substrings to be included in the array. Splits\n * the string at each occurrence of specified separator, but stops when limit entries have been\n * placed in the array.\n * @returns {string[] | undefined} An array of strings, split at each point where separator occurs\n * in the starting string. Returns undefined if separator is not found in string.\n */\nexport function split(\n string: string,\n separator: string | RegExp,\n splitLimit?: number,\n): string[] | undefined {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !separator.flags.includes('g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return undefined;\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = length(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate. This function handles Unicode code points instead of UTF-16 character\n * codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The characters to be searched for at the start of this string.\n * @param {number} [position=0] The start position at which searchString is expected to be found\n * (the index of searchString's first character). Default is `0`\n * @returns {boolean} True if the given characters are found at the beginning of the string,\n * including when searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * Returns a substring by providing start and length. This function handles Unicode code points\n * instead of UTF-16 character codes. This function is not exported because it is considered\n * deprecated, however it is still useful as a local helper function.\n *\n * @param {string} string String to be divided\n * @param {number} [begin=Start of string] Start position. Default is `Start of string`\n * @param {number} [len=String length minus start parameter] Length of result. Default is `String\n * length minus start parameter`. Default is `String length minus start parameter`\n * @returns {string} Substring from starting string\n */\nfunction substr(string: string, begin: number = 0, len: number = length(string) - begin): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * Returns a substring by providing start and end position. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to be divided\n * @param {string} begin Start position\n * @param {number} [end=End of string] End position. Default is `End of string`\n * @returns {string} Substring from starting string\n */\nexport function substring(\n string: string,\n begin?: number | undefined,\n end: number | undefined = length(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * Converts a string to an array of string characters. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param {string} string String to convert to array\n * @returns {string[]} An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","Mutex","AsyncMutex","MutexMap","mutexID","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","stringLength","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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","x_google_ignoreList":[9,10,12]} \ No newline at end of file +{"version":3,"file":"index.js","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/mutex.ts","../src/mutex-map.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { Mutex as AsyncMutex } from 'async-mutex';\n\n// Extending Mutex from async-mutex so we can add JSDoc\n\n/**\n * Class that allows calling asynchronous functions multiple times at once while only running one at\n * a time.\n *\n * @example\n *\n * ```typescript\n * const mutex = new Mutex();\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n * ```\n *\n * See [`async-mutex`](https://www.npmjs.com/package/async-mutex) for more information.\n */\nclass Mutex extends AsyncMutex {}\n\nexport default Mutex;\n","import Mutex from './mutex';\n\n/** Map of {@link Mutex}es that automatically (lazily) generates a new {@link Mutex} for any new key */\nclass MutexMap {\n private mutexesByID = new Map();\n\n get(mutexID: string): Mutex {\n let retVal = this.mutexesByID.get(mutexID);\n if (retVal) return retVal;\n\n retVal = new Mutex();\n this.mutexesByID.set(mutexID, retVal);\n return retVal;\n }\n}\n\nexport default MutexMap;\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * Finds the Unicode code point at the given index\n *\n * @param {string} string String to index\n * @param {number} index Position of the character to be returned in range of 0 to -length(string)\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > length(string) || index < -length(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * Always indexes string as a sequence of Unicode code points\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, empty string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > length(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to index\n * @param {number} index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {number | undefined} Non-negative integer representing the code point value of the\n * character at the given index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > length(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * Determines whether a string ends with the characters of this string. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Characters to search for at the end of the string\n * @param {number} [endPosition=length(string)] End position where searchString is expected to be\n * found. Default is `length(string)`\n * @returns {boolean} True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = length(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + length(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * Performs a case-sensitive search to determine if searchString is found in string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString String to search for\n * @param {string} [position=0] Position within the string to start searching for searchString.\n * Default is `0`\n * @returns {boolean} True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * Returns the index of the first occurrence of a given string. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The string to search for\n * @param {number} [position=0] Start of searching. Default is `0`\n * @returns {number} Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * Searches this string and returns the index of the last occurrence of the specified substring.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Substring to search for\n * @param {number} [position=+Infinity] The method returns the index of the last occurrence of the\n * specified substring at a position less than or equal to position. . Default is `+Infinity`\n * @returns {number} Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(\n string: string,\n searchString: string,\n position: number = +Infinity,\n): number {\n let validatedPosition = position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= length(string)) {\n validatedPosition = length(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, length(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * Returns the length of a string. This function handles Unicode code points instead of UTF-16\n * character codes.\n *\n * @param {string} string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function length(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * Returns the Unicode Normalization Form of this string.\n *\n * @param {string} string The starting string\n * @param {'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'} [form='NFC'] Form specifying the Unicode\n * Normalization Form. Default is `'NFC'`\n * @returns {string} A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within targetLength, it will be truncated. Default is `\" \"`\n * @returns {string} String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\nfunction correctSliceIndex(stringLength: number, index: number) {\n if (index > stringLength) return stringLength;\n if (index < -stringLength) return 0;\n if (index < 0) return index + stringLength;\n return index;\n}\n\n/**\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The starting string\n * @param {number} indexStart The index of the first character to include in the returned substring.\n * @param {number} indexEnd The index of the first character to exclude from the returned substring.\n * @returns {string} A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const stringLength: number = length(string);\n if (\n indexStart > stringLength ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(\n indexStart > 0 &&\n indexStart < stringLength &&\n indexEnd < 0 &&\n indexEnd > -stringLength\n )) ||\n indexEnd < -stringLength ||\n (indexStart < 0 && indexStart > -stringLength && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(stringLength, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The string to split\n * @param {string | RegExp} separator The pattern describing where each split should occur\n * @param {number} splitLimit Limit on the number of substrings to be included in the array. Splits\n * the string at each occurrence of specified separator, but stops when limit entries have been\n * placed in the array.\n * @returns {string[] | undefined} An array of strings, split at each point where separator occurs\n * in the starting string. Returns undefined if separator is not found in string.\n */\nexport function split(\n string: string,\n separator: string | RegExp,\n splitLimit?: number,\n): string[] | undefined {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !includes(separator.flags, 'g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return undefined;\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = length(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate. This function handles Unicode code points instead of UTF-16 character\n * codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The characters to be searched for at the start of this string.\n * @param {number} [position=0] The start position at which searchString is expected to be found\n * (the index of searchString's first character). Default is `0`\n * @returns {boolean} True if the given characters are found at the beginning of the string,\n * including when searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * Returns a substring by providing start and length. This function handles Unicode code points\n * instead of UTF-16 character codes. This function is not exported because it is considered\n * deprecated, however it is still useful as a local helper function.\n *\n * @param {string} string String to be divided\n * @param {number} [begin=Start of string] Start position. Default is `Start of string`\n * @param {number} [len=String length minus start parameter] Length of result. Default is `String\n * length minus start parameter`. Default is `String length minus start parameter`\n * @returns {string} Substring from starting string\n */\nfunction substr(string: string, begin: number = 0, len: number = length(string) - begin): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * Returns a substring by providing start and end position. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to be divided\n * @param {string} begin Start position\n * @param {number} [end=End of string] End position. Default is `End of string`\n * @returns {string} Substring from starting string\n */\nexport function substring(\n string: string,\n begin?: number | undefined,\n end: number | undefined = length(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * Converts a string to an array of string characters. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param {string} string String to convert to array\n * @returns {string[]} An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","Mutex","AsyncMutex","MutexMap","mutexID","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","stringLength","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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","x_google_ignoreList":[9,10,12]} \ No newline at end of file diff --git a/lib/platform-bible-utils/src/string-util.ts b/lib/platform-bible-utils/src/string-util.ts index 70d4f63680..e8141443ff 100644 --- a/lib/platform-bible-utils/src/string-util.ts +++ b/lib/platform-bible-utils/src/string-util.ts @@ -267,7 +267,7 @@ export function split( let regexSeparator = separator; if ( typeof separator === 'string' || - (separator instanceof RegExp && !separator.flags.includes('g')) + (separator instanceof RegExp && !includes(separator.flags, 'g')) ) { regexSeparator = new RegExp(separator, 'g'); } diff --git a/src/extension-host/services/extension-storage.service.ts b/src/extension-host/services/extension-storage.service.ts index 4038a00ada..707856dc48 100644 --- a/src/extension-host/services/extension-storage.service.ts +++ b/src/extension-host/services/extension-storage.service.ts @@ -8,7 +8,7 @@ import { import { ExecutionToken } from '@node/models/execution-token.model'; import executionTokenService from '@node/services/execution-token.service'; import { Buffer } from 'buffer'; -import { length } from 'platform-bible-utils'; +import { length, includes } from 'platform-bible-utils'; // #region Functions that need to be called by other services to initialize this service @@ -52,7 +52,7 @@ export function buildExtensionPathFromName(extensionName: string, fileName: stri // TODO: If we really care about the potential to jump into other directories, this probably // needs some work. For example, this doesn't detect symlinks. There might be many other holes. if (!isValidFileOrDirectoryName(fileName)) throw new Error(`Invalid file name: ${fileName}`); - if (fileName.includes('..')) throw new Error('Cannot include ".." in the file name'); + if (includes(fileName, '..')) throw new Error('Cannot include ".." in the file name'); return joinUriPaths(baseUri, fileName); } diff --git a/src/extension-host/services/extension.service.ts b/src/extension-host/services/extension.service.ts index e7f5f83b02..6c78984ded 100644 --- a/src/extension-host/services/extension.service.ts +++ b/src/extension-host/services/extension.service.ts @@ -21,6 +21,8 @@ import { UnsubscriberAsync, UnsubscriberAsyncList, deserialize, + endsWith, + includes, length, startsWith, slice, @@ -116,11 +118,11 @@ let availableExtensions: ExtensionInfo[]; /** Parse string extension manifest into an object and perform any transformations needed */ function parseManifest(extensionManifestJson: string): ExtensionManifest { const extensionManifest: ExtensionManifest = deserialize(extensionManifestJson); - if (extensionManifest.name.includes('..')) + if (includes(extensionManifest.name, '..')) throw new Error('Extension name must not include `..`!'); // Replace ts with js so people can list their source code ts name but run the transpiled js if (extensionManifest.main && extensionManifest.main.toLowerCase().endsWith('.ts')) - extensionManifest.main = `${slice(extensionManifest.main, 0, -3)}.js`; + extensionManifest.main = `${extensionManifest.main.slice(0, -3)}.js`; return extensionManifest; } @@ -196,7 +198,7 @@ async function getExtensionZipUris(): Promise { .flatMap((dirEntries) => dirEntries[nodeFS.EntryType.File]) .filter((extensionFileUri) => extensionFileUri), ) - .filter((extensionFileUri) => extensionFileUri.toLowerCase().endsWith('.zip')); + .filter((extensionFileUri) => endsWith(extensionFileUri.toLowerCase(), '.zip')); } /** @@ -231,7 +233,7 @@ async function getExtensionUrisToLoad(): Promise { const extensionFolderPromises = commandLineExtensionDirectories .map((extensionDirPath) => { const extensionFolder = extensionDirPath.endsWith(MANIFEST_FILE_NAME) - ? slice(extensionDirPath, 0, -length(MANIFEST_FILE_NAME)) + ? extensionDirPath.slice(0, -MANIFEST_FILE_NAME.length) : extensionDirPath; return extensionFolder; }) @@ -284,7 +286,7 @@ async function unzipCompressedExtensionFile(zipUri: Uri): Promise { await Promise.all( zipEntries.map(async ([fileName]) => { const parsedPath = path.parse(fileName); - if (fileName.includes('..')) { + if (includes(fileName, '..')) { logger.warn(`Invalid extension ZIP file entry in "${zipUri}": ${fileName}`); zipEntriesInProperDirectory = false; } @@ -441,7 +443,7 @@ async function cacheExtensionTypeDeclarations(extensionInfos: ExtensionInfo[]) { // it can lead to problems with race conditions. If this ever becomes a problem, we can fix // this code. const dtsInfos = ( - await nodeFS.readDir(extensionInfo.dirUri, (entryName) => entryName.endsWith('.d.ts')) + await nodeFS.readDir(extensionInfo.dirUri, (entryName) => endsWith(entryName, '.d.ts')) )[nodeFS.EntryType.File].map(createDtsInfoFromUri); if (dtsInfos.length <= 0) { diff --git a/src/extension-host/services/project-lookup.service-host.ts b/src/extension-host/services/project-lookup.service-host.ts index 828f7e2087..d6da8446fa 100644 --- a/src/extension-host/services/project-lookup.service-host.ts +++ b/src/extension-host/services/project-lookup.service-host.ts @@ -8,7 +8,7 @@ import { joinUriPaths } from '@node/utils/util'; import logger from '@shared/services/logger.service'; import networkObjectService from '@shared/services/network-object.service'; import * as nodeFS from '@node/services/node-file-system.service'; -import { deserialize, wait } from 'platform-bible-utils'; +import { deserialize, endsWith, wait } from 'platform-bible-utils'; /** This points to the directory where all of the project subdirectories live */ const PROJECTS_ROOT_URI = joinUriPaths('file://', os.homedir(), '.platform.bible', 'projects'); @@ -64,7 +64,7 @@ async function loadAllProjectsMetadata(): Promise> { async function getProjectMetadata(projectId: string): Promise { const idUpper = projectId.toUpperCase(); const uris = await getProjectUris(); - const matches = uris.filter((uri) => uri.toUpperCase().endsWith(`_${idUpper}`)); + const matches = uris.filter((uri) => endsWith(uri.toUpperCase(), `_${idUpper}`)); if (matches.length === 0) throw new Error(`No known project with ID ${projectId}`); if (matches.length > 1) throw new Error(`${matches.length} projects share the ID ${projectId}`); diff --git a/src/main/services/extension-asset-protocol.service.ts b/src/main/services/extension-asset-protocol.service.ts index f75d540551..cf017faf7e 100644 --- a/src/main/services/extension-asset-protocol.service.ts +++ b/src/main/services/extension-asset-protocol.service.ts @@ -1,7 +1,7 @@ import { protocol } from 'electron'; import { StatusCodes } from 'http-status-codes'; import extensionAssetService from '@shared/services/extension-asset.service'; -import { indexOf, length, substring } from 'platform-bible-utils'; +import { includes, indexOf, lastIndexOf, length, substring } from 'platform-bible-utils'; /** Here some of the most common MIME types that we expect to handle */ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types @@ -30,7 +30,7 @@ const knownMimeTypes = { /** Lookup the MIME type to pass back to the renderer */ function getMimeTypeForFileName(fileName: string): string { - const dotIndex = fileName.lastIndexOf('.'); + const dotIndex = lastIndexOf(fileName, '.'); if (dotIndex > 0) { const fileType: string = substring(fileName, dotIndex); // Assert key type confirmed in check. @@ -71,7 +71,7 @@ const initialize = () => { const uri: string = substring(request.url, length(`${protocolName}://`)); // There have to be at least 2 parts to the URI divided by a slash - if (!uri.includes('/')) { + if (!includes(uri, '/')) { return errorResponse(request.url, StatusCodes.BAD_REQUEST); } diff --git a/src/main/services/extension-host.service.ts b/src/main/services/extension-host.service.ts index 3b099d95ec..2bf40017a7 100644 --- a/src/main/services/extension-host.service.ts +++ b/src/main/services/extension-host.service.ts @@ -6,7 +6,7 @@ import { commandLineArgumentsAliases, } from '@node/utils/command-line.util'; import logger, { formatLog, WARN_TAG } from '@shared/services/logger.service'; -import { waitForDuration } from 'platform-bible-utils'; +import { includes, waitForDuration } from 'platform-bible-utils'; import { ChildProcess, ChildProcessByStdio, fork, spawn } from 'child_process'; import { app } from 'electron'; import path from 'path'; @@ -25,7 +25,7 @@ const closePromise: Promise = new Promise((resolve) => { // log functions for inside the extension host process function logProcessError(message: unknown) { let msg = message?.toString() || ''; - if (msg.includes(WARN_TAG)) { + if (includes(msg, WARN_TAG)) { msg = msg.split(WARN_TAG).join(''); // TODO: Can't use our new split here for some reason logger.warn(formatLog(msg, EXTENSION_HOST_NAME, 'warning')); } else logger.error(formatLog(msg, EXTENSION_HOST_NAME, 'error')); diff --git a/src/node/utils/util.ts b/src/node/utils/util.ts index 6f4438ebbc..667d453337 100644 --- a/src/node/utils/util.ts +++ b/src/node/utils/util.ts @@ -4,6 +4,7 @@ import path from 'path'; import os from 'os'; import { Uri } from '@shared/data/file-system.model'; import memoizeOne from 'memoize-one'; +import { includes } from 'platform-bible-utils'; // FOR SCHEME DOCUMENTATION, SEE Uri JSDOC const APP_SCHEME = 'app'; @@ -60,7 +61,7 @@ const getSchemePaths = memoizeOne((): { [scheme: string]: string } => { // TODO: Make URI an actual class. Will be challenging when passing through WebSocket function getPathInfoFromUri(uri: Uri): { scheme: string; uriPath: string } { // Add app scheme to the uri if it doesn't have one - const fullUri = uri.includes(PROTOCOL_PART) ? uri : `${APP_SCHEME}${PROTOCOL_PART}${uri}`; + const fullUri = includes(uri, PROTOCOL_PART) ? uri : `${APP_SCHEME}${PROTOCOL_PART}${uri}`; const [scheme, uriPath] = fullUri.split(PROTOCOL_PART); // TODO: Our new split doesn't support this return return { diff --git a/src/shared/services/data-provider.service.ts b/src/shared/services/data-provider.service.ts index 7e12465401..4ee655e2ae 100644 --- a/src/shared/services/data-provider.service.ts +++ b/src/shared/services/data-provider.service.ts @@ -21,6 +21,7 @@ import { isString, CannotHaveOnDidDispose, AsyncVariable, + endsWith, startsWith, } from 'platform-bible-utils'; import * as networkService from '@shared/services/network.service'; @@ -54,7 +55,7 @@ const SUBSCRIBE_PLACEHOLDER = {}; * provider name if it's already there to avoid duplication */ const getDataProviderObjectId = (providerName: string) => { - return providerName.endsWith(`-${DATA_PROVIDER_LABEL}`) + return endsWith(providerName, `-${DATA_PROVIDER_LABEL}`) ? providerName : `${providerName}-${DATA_PROVIDER_LABEL}`; }; diff --git a/src/shared/services/logger.service.ts b/src/shared/services/logger.service.ts index 7977bc0354..d93bdd813c 100644 --- a/src/shared/services/logger.service.ts +++ b/src/shared/services/logger.service.ts @@ -1,6 +1,7 @@ import chalk from 'chalk'; import log, { LogLevel } from 'electron-log'; import { getProcessType, isClient, isExtensionHost, isRenderer } from '@shared/utils/internal-util'; +import { includes } from 'platform-bible-utils'; export const WARN_TAG = ''; @@ -70,7 +71,7 @@ function identifyCaller(): string | undefined { // Start at 3 to skip the "Error" line, this function's stack frame, and this function's caller for (let lineNumber = 3; lineNumber < lines.length; lineNumber += 1) { // Skip over all logging library frames to get to the real call - if (!lines[lineNumber].includes('node_modules') && !lines[lineNumber].includes('node:')) { + if (!includes(lines[lineNumber], 'node_modules') && !includes(lines[lineNumber], 'node:')) { details = parseErrorLine(lines[lineNumber]); if (details) break; } @@ -95,7 +96,7 @@ export function formatLog(message: string, serviceName: string, tag = '') { // Remove the new line at the end of every message coming from stdout from other processes const messageTrimmed = message.trimEnd(); const openTag = `[${serviceName}${tag ? ' ' : ''}${tag}]`; - if (messageTrimmed.includes('\n')) { + if (includes(messageTrimmed, '\n')) { const closeTag = `[/${serviceName}${tag ? ' ' : ''}${tag}]`; // Multi-line return `\n${openTag}\n${messageTrimmed}\n${closeTag}`; diff --git a/src/shared/utils/util.ts b/src/shared/utils/util.ts index 5608381224..933e9b1a56 100644 --- a/src/shared/utils/util.ts +++ b/src/shared/utils/util.ts @@ -1,5 +1,12 @@ import { ProcessType } from '@shared/global-this.model'; -import { UnsubscriberAsync, indexOf, isString, length, substring } from 'platform-bible-utils'; +import { + UnsubscriberAsync, + charAt, + indexOf, + isString, + length, + substring, +} from 'platform-bible-utils'; const NONCE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; const NONCE_CHARS_LENGTH = length(NONCE_CHARS); @@ -14,7 +21,7 @@ const NONCE_CHARS_LENGTH = length(NONCE_CHARS); export function newNonce(): string { let nonce = ''; for (let i = 0; i < 32; i++) - nonce += NONCE_CHARS.charAt(Math.floor(Math.random() * NONCE_CHARS_LENGTH)); + nonce += charAt(NONCE_CHARS, Math.floor(Math.random() * NONCE_CHARS_LENGTH)); return nonce; } diff --git a/stop-processes.mjs b/stop-processes.mjs index cade724092..067b28a317 100644 --- a/stop-processes.mjs +++ b/stop-processes.mjs @@ -1,6 +1,7 @@ /* eslint-disable no-console */ import { exec } from 'child_process'; import fkill from 'fkill'; +import { indexOf, lastIndexOf } from 'platform-bible-utils'; // All processes with any of these terms in the command line will be killed const searchTerms = ['electronmon', 'esbuild', 'nodemon', 'vite', 'webpack', 'extension-host']; @@ -34,8 +35,8 @@ function killProcessesWithSearchTerm() { .split('\n') .slice(1) .map((line) => { - const firstIndex = line.indexOf(','); - const lastIndex = line.lastIndexOf(','); + const firstIndex = indexOf(line, ','); + const lastIndex = lastIndexOf(line, ','); const pid = line.substring(lastIndex + 1); const command = line.substring(firstIndex + 1, lastIndex); return { pid, command }; @@ -46,7 +47,7 @@ function killProcessesWithSearchTerm() { .slice(1) .map((line) => { const trimmedLine = line.trim(); - const index = trimmedLine.indexOf(' '); + const index = indexOf(trimmedLine, ' '); const pid = trimmedLine.substring(0, index); const command = trimmedLine.substring(index + 1); return { pid, command }; @@ -59,7 +60,7 @@ function killProcessesWithSearchTerm() { // Kill the processes with a search term in process name or arguments await Promise.all( processes.map(async ({ pid, command }) => { - if (command && pid && searchTerms.some((term) => command.includes(term))) { + if (command && pid && searchTerms.some((term) => includes(command, term))) { console.log(`Killing ${command}`); return fkill(Number(pid), fkillOptions); } From 64e4a0eca62734ffb09a8962b45f31a524f9308e Mon Sep 17 00:00:00 2001 From: Rolf Heij Date: Mon, 19 Feb 2024 16:27:25 -0500 Subject: [PATCH 18/22] Fix bug in split function --- lib/platform-bible-utils/dist/index.cjs | 2 +- lib/platform-bible-utils/dist/index.cjs.map | 2 +- lib/platform-bible-utils/dist/index.d.ts | 2 +- lib/platform-bible-utils/dist/index.js | 14 +++++++------- lib/platform-bible-utils/dist/index.js.map | 2 +- lib/platform-bible-utils/src/string-util.test.ts | 5 +++++ lib/platform-bible-utils/src/string-util.ts | 8 ++------ src/main/services/extension-host.service.ts | 4 ++-- src/node/utils/util.ts | 3 ++- src/renderer/services/web-view.service-host.ts | 3 ++- src/shared/services/logger.service.ts | 3 ++- 11 files changed, 26 insertions(+), 22 deletions(-) diff --git a/lib/platform-bible-utils/dist/index.cjs b/lib/platform-bible-utils/dist/index.cjs index 6db422b9d5..9f1aa2c5c7 100644 --- a/lib/platform-bible-utils/dist/index.cjs +++ b/lib/platform-bible-utils/dist/index.cjs @@ -1,2 +1,2 @@ -"use strict";var pe=Object.defineProperty;var me=(t,e,r)=>e in t?pe(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var p=(t,e,r)=>(me(t,typeof e!="symbol"?e+"":e,r),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const de=require("async-mutex");class be{constructor(e,r=1e4){p(this,"variableName");p(this,"promiseToValue");p(this,"resolver");p(this,"rejecter");this.variableName=e,this.promiseToValue=new Promise((s,n)=>{this.resolver=s,this.rejecter=n}),r>0&&setTimeout(()=>{this.rejecter&&(this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`),this.complete())},r),Object.seal(this)}get promise(){return this.promiseToValue}get hasSettled(){return Object.isFrozen(this)}resolveToValue(e,r=!1){if(this.resolver)console.debug(`${this.variableName} is being resolved now`),this.resolver(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent resolution of ${this.variableName}`)}}rejectWithReason(e,r=!1){if(this.rejecter)console.debug(`${this.variableName} is being rejected now`),this.rejecter(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent rejection of ${this.variableName}`)}}complete(){this.resolver=void 0,this.rejecter=void 0,Object.freeze(this)}}function ge(){return"00-0-4-1-000".replace(/[^-]/g,t=>((Math.random()+~~t)*65536>>t).toString(16).padStart(4,"0"))}function F(t){return typeof t=="string"||t instanceof String}function E(t){return JSON.parse(JSON.stringify(t))}function Ne(t,e=300){if(F(t))throw new Error("Tried to debounce a string! Could be XSS");let r;return(...s)=>{clearTimeout(r),r=setTimeout(()=>t(...s),e)}}function ve(t,e,r){const s=new Map;return t.forEach(n=>{const o=e(n),a=s.get(o),i=r?r(n,o):n;a?a.push(i):s.set(o,[i])}),s}function ye(t){return typeof t=="object"&&t!==null&&"message"in t&&typeof t.message=="string"}function we(t){if(ye(t))return t;try{return new Error(JSON.stringify(t))}catch{return new Error(String(t))}}function Ee(t){return we(t).message}function H(t){return new Promise(e=>setTimeout(e,t))}function Oe(t,e){const r=H(e).then(()=>{});return Promise.any([r,t()])}function $e(t,e="obj"){const r=new Set;Object.getOwnPropertyNames(t).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e} due to error: ${o}`)}});let s=Object.getPrototypeOf(t);for(;s&&Object.getPrototypeOf(s);)Object.getOwnPropertyNames(s).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e}'s prototype due to error: ${o}`)}}),s=Object.getPrototypeOf(s);return r}function Ae(t,e={}){return new Proxy(e,{get(r,s){return s in r?r[s]:async(...n)=>(await t())[s](...n)}})}class Se{constructor(e,r){p(this,"baseDocument");p(this,"contributions",new Map);p(this,"latestOutput");p(this,"options");this.baseDocument=e,this.options=r,this.updateBaseDocument(e)}updateBaseDocument(e){return this.validateStartingDocument(e),this.baseDocument=this.options.copyDocuments?E(e):e,this.rebuild()}addOrUpdateContribution(e,r){this.validateContribution(e,r);const s=this.contributions.get(e),n=this.options.copyDocuments&&r?E(r):r;this.contributions.set(e,n);try{return this.rebuild()}catch(o){throw s?this.contributions.set(e,s):this.contributions.delete(e),new Error(`Error when setting the document named ${e}: ${o}`)}}deleteContribution(e){const r=this.contributions.get(e);if(!r)throw new Error("{documentKey} does not exist");this.contributions.delete(e);try{return this.rebuild()}catch(s){throw this.contributions.set(e,r),new Error(`Error when deleting the document named ${e}: ${s}`)}}rebuild(){if(this.contributions.size===0){let r=E(this.baseDocument);return r=this.transformFinalOutput(r),this.validateOutput(r),this.latestOutput=r,this.latestOutput}let e=this.baseDocument;return this.contributions.forEach(r=>{e=k(e,r,this.options.ignoreDuplicateProperties),this.validateOutput(e)}),e=this.transformFinalOutput(e),this.validateOutput(e),this.latestOutput=e,this.latestOutput}}function Me(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||Array.isArray(r))&&(e=!1)}),e}function qe(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||!Array.isArray(r))&&(e=!1)}),e}function k(t,e,r){const s=E(t);return e&&Object.keys(e).forEach(n=>{if(Object.hasOwn(t,n)){if(Me(t[n],e[n]))s[n]=k(t[n],e[n],r);else if(qe(t[n],e[n]))s[n]=s[n].concat(e[n]);else if(!r)throw new Error(`Cannot merge objects: key "${n}" already exists in the target object`)}else s[n]=e[n]}),s}class je{constructor(e="Anonymous"){p(this,"unsubscribers",new Set);this.name=e}add(...e){e.forEach(r=>{"dispose"in r?this.unsubscribers.add(r.dispose):this.unsubscribers.add(r)})}async runAllUnsubscribers(){const e=[...this.unsubscribers].map(s=>s()),r=await Promise.all(e);return this.unsubscribers.clear(),r.every((s,n)=>(s||console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${n} failed!`),s))}}class Ce{constructor(){p(this,"subscribe",this.event);p(this,"subscriptions");p(this,"lazyEvent");p(this,"isDisposed",!1);p(this,"dispose",()=>this.disposeFn());p(this,"emit",e=>{this.emitFn(e)})}get event(){return this.assertNotDisposed(),this.lazyEvent||(this.lazyEvent=e=>{if(!e||typeof e!="function")throw new Error("Event handler callback must be a function!");return this.subscriptions||(this.subscriptions=[]),this.subscriptions.push(e),()=>{if(!this.subscriptions)return!1;const r=this.subscriptions.indexOf(e);return r<0?!1:(this.subscriptions.splice(r,1),!0)}}),this.lazyEvent}emitFn(e){var r;this.assertNotDisposed(),(r=this.subscriptions)==null||r.forEach(s=>s(e))}assertNotDisposed(){if(this.isDisposed)throw new Error("Emitter is disposed")}disposeFn(){return this.assertNotDisposed(),this.isDisposed=!0,this.subscriptions=void 0,this.lazyEvent=void 0,Promise.resolve(!0)}}class W extends de.Mutex{}class Pe{constructor(){p(this,"mutexesByID",new Map)}get(e){let r=this.mutexesByID.get(e);return r||(r=new W,this.mutexesByID.set(e,r),r)}}const K=[{shortName:"ERR",fullNames:["ERROR"],chapters:-1},{shortName:"GEN",fullNames:["Genesis"],chapters:50},{shortName:"EXO",fullNames:["Exodus"],chapters:40},{shortName:"LEV",fullNames:["Leviticus"],chapters:27},{shortName:"NUM",fullNames:["Numbers"],chapters:36},{shortName:"DEU",fullNames:["Deuteronomy"],chapters:34},{shortName:"JOS",fullNames:["Joshua"],chapters:24},{shortName:"JDG",fullNames:["Judges"],chapters:21},{shortName:"RUT",fullNames:["Ruth"],chapters:4},{shortName:"1SA",fullNames:["1 Samuel"],chapters:31},{shortName:"2SA",fullNames:["2 Samuel"],chapters:24},{shortName:"1KI",fullNames:["1 Kings"],chapters:22},{shortName:"2KI",fullNames:["2 Kings"],chapters:25},{shortName:"1CH",fullNames:["1 Chronicles"],chapters:29},{shortName:"2CH",fullNames:["2 Chronicles"],chapters:36},{shortName:"EZR",fullNames:["Ezra"],chapters:10},{shortName:"NEH",fullNames:["Nehemiah"],chapters:13},{shortName:"EST",fullNames:["Esther"],chapters:10},{shortName:"JOB",fullNames:["Job"],chapters:42},{shortName:"PSA",fullNames:["Psalm","Psalms"],chapters:150},{shortName:"PRO",fullNames:["Proverbs"],chapters:31},{shortName:"ECC",fullNames:["Ecclesiastes"],chapters:12},{shortName:"SNG",fullNames:["Song of Solomon","Song of Songs"],chapters:8},{shortName:"ISA",fullNames:["Isaiah"],chapters:66},{shortName:"JER",fullNames:["Jeremiah"],chapters:52},{shortName:"LAM",fullNames:["Lamentations"],chapters:5},{shortName:"EZK",fullNames:["Ezekiel"],chapters:48},{shortName:"DAN",fullNames:["Daniel"],chapters:12},{shortName:"HOS",fullNames:["Hosea"],chapters:14},{shortName:"JOL",fullNames:["Joel"],chapters:3},{shortName:"AMO",fullNames:["Amos"],chapters:9},{shortName:"OBA",fullNames:["Obadiah"],chapters:1},{shortName:"JON",fullNames:["Jonah"],chapters:4},{shortName:"MIC",fullNames:["Micah"],chapters:7},{shortName:"NAM",fullNames:["Nahum"],chapters:3},{shortName:"HAB",fullNames:["Habakkuk"],chapters:3},{shortName:"ZEP",fullNames:["Zephaniah"],chapters:3},{shortName:"HAG",fullNames:["Haggai"],chapters:2},{shortName:"ZEC",fullNames:["Zechariah"],chapters:14},{shortName:"MAL",fullNames:["Malachi"],chapters:4},{shortName:"MAT",fullNames:["Matthew"],chapters:28},{shortName:"MRK",fullNames:["Mark"],chapters:16},{shortName:"LUK",fullNames:["Luke"],chapters:24},{shortName:"JHN",fullNames:["John"],chapters:21},{shortName:"ACT",fullNames:["Acts"],chapters:28},{shortName:"ROM",fullNames:["Romans"],chapters:16},{shortName:"1CO",fullNames:["1 Corinthians"],chapters:16},{shortName:"2CO",fullNames:["2 Corinthians"],chapters:13},{shortName:"GAL",fullNames:["Galatians"],chapters:6},{shortName:"EPH",fullNames:["Ephesians"],chapters:6},{shortName:"PHP",fullNames:["Philippians"],chapters:4},{shortName:"COL",fullNames:["Colossians"],chapters:4},{shortName:"1TH",fullNames:["1 Thessalonians"],chapters:5},{shortName:"2TH",fullNames:["2 Thessalonians"],chapters:3},{shortName:"1TI",fullNames:["1 Timothy"],chapters:6},{shortName:"2TI",fullNames:["2 Timothy"],chapters:4},{shortName:"TIT",fullNames:["Titus"],chapters:3},{shortName:"PHM",fullNames:["Philemon"],chapters:1},{shortName:"HEB",fullNames:["Hebrews"],chapters:13},{shortName:"JAS",fullNames:["James"],chapters:5},{shortName:"1PE",fullNames:["1 Peter"],chapters:5},{shortName:"2PE",fullNames:["2 Peter"],chapters:3},{shortName:"1JN",fullNames:["1 John"],chapters:5},{shortName:"2JN",fullNames:["2 John"],chapters:1},{shortName:"3JN",fullNames:["3 John"],chapters:1},{shortName:"JUD",fullNames:["Jude"],chapters:1},{shortName:"REV",fullNames:["Revelation"],chapters:22}],L=1,Z=K.length-1,X=1,Q=1,Y=t=>{var e;return((e=K[t])==null?void 0:e.chapters)??-1},Te=(t,e)=>({bookNum:Math.max(L,Math.min(t.bookNum+e,Z)),chapterNum:1,verseNum:1}),Re=(t,e)=>({...t,chapterNum:Math.min(Math.max(X,t.chapterNum+e),Y(t.bookNum)),verseNum:1}),De=(t,e)=>({...t,verseNum:Math.max(Q,t.verseNum+e)}),Ie=t=>(...e)=>t.map(s=>s(...e)).every(s=>s),xe=t=>async(...e)=>{const r=t.map(async s=>s(...e));return(await Promise.all(r)).every(s=>s)};var D=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},N={},_e=()=>{const t="\\ud800-\\udfff",e="\\u0300-\\u036f",r="\\ufe20-\\ufe2f",s="\\u20d0-\\u20ff",n="\\u1ab0-\\u1aff",o="\\u1dc0-\\u1dff",a=e+r+s+n+o,i="\\ufe0e\\ufe0f",c="\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93",h=`[${t}]`,u=`[${a}]`,l="\\ud83c[\\udffb-\\udfff]",f=`(?:${u}|${l})`,b=`[^${t}]`,d="(?:\\uD83C[\\uDDE6-\\uDDFF]){2}",y="[\\ud800-\\udbff][\\udc00-\\udfff]",q="\\u200d",ue="(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)",le=`[${c}]`,T=`${f}?`,R=`[${i}]?`,ce=`(?:${q}(?:${[b,d,y].join("|")})${R+T})*`,fe=R+T+ce,he=`(?:${[`${b}${u}?`,u,d,y,h,le].join("|")})`;return new RegExp(`${ue}|${l}(?=${l})|${he+fe}`,"g")},ze=D&&D.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(N,"__esModule",{value:!0});var A=ze(_e);function j(t){if(typeof t!="string")throw new Error("A string is expected as input");return t.match(A.default())||[]}var Be=N.toArray=j;function P(t){if(typeof t!="string")throw new Error("Input must be a string");var e=t.match(A.default());return e===null?0:e.length}var Je=N.length=P;function ee(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");(typeof e!="number"||e<0)&&(e=0),typeof r=="number"&&r<0&&(r=0);var s=t.match(A.default());return s?s.slice(e,r).join(""):""}var Ge=N.substring=ee;function Ue(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");var s=P(t);if(typeof e!="number"&&(e=parseInt(e,10)),e>=s)return"";e<0&&(e+=s);var n;typeof r>"u"?n=s:(typeof r!="number"&&(r=parseInt(r,10)),n=r>=0?r+e:e);var o=t.match(A.default());return o?o.slice(e,n).join(""):""}var Ve=N.substr=Ue;function Fe(t,e,r,s){if(e===void 0&&(e=16),r===void 0&&(r="#"),s===void 0&&(s="right"),typeof t!="string"||typeof e!="number")throw new Error("Invalid arguments specified");if(["left","right"].indexOf(s)===-1)throw new Error("Pad position should be either left or right");typeof r!="string"&&(r=String(r));var n=P(t);if(n>e)return ee(t,0,e);if(n=s.length)return e===""?s.length:-1;if(e==="")return r;var n=j(e),o=!1,a;for(a=r;am(t)||e<-m(t)))return M(t,e,1)}function Ke(t,e){return e<0||e>m(t)-1?"":M(t,e,1)}function Le(t,e){if(!(e<0||e>m(t)-1))return M(t,e,1).codePointAt(0)}function Ze(t,e,r=m(t)){const s=re(t,e);return!(s===-1||s+m(e)!==r)}function Xe(t,e,r=0){const s=O(t,r);return S(s,e)!==-1}function S(t,e,r=0){return ke(t,e,r)}function re(t,e,r=1/0){let s=r;s<0?s=0:s>=m(t)&&(s=m(t)-1);for(let n=s;n>=0;n--)if(M(t,n,m(e))===e)return n;return-1}function m(t){return Je(t)}function Qe(t,e){const r=e.toUpperCase();return r==="NONE"?t:t.normalize(r)}function Ye(t,e,r=" "){return e<=m(t)?t:te(t,e,r,"right")}function et(t,e,r=" "){return e<=m(t)?t:te(t,e,r,"left")}function I(t,e){return e>t?t:e<-t?0:e<0?e+t:e}function tt(t,e,r){const s=m(t);if(e>s||r&&(e>r&&!(e>0&&e-s)||r<-s||e<0&&e>-s&&r>0))return"";const n=I(s,e),o=r?I(s,r):void 0;return O(t,n,o)}function rt(t,e,r){const s=[];if(r!==void 0&&r<=0)return[t];if(e==="")return se(t).slice(0,r);let n=e;(typeof e=="string"||e instanceof RegExp&&!e.flags.includes("g"))&&(n=new RegExp(e,"g"));const o=t.match(n);let a=0;if(o){for(let i=0;i<(r?r-1:o.length);i++){const c=S(t,o[i],a),h=m(o[i]);if(s.push(O(t,a,c)),a=c+h,r!==void 0&&s.length===r)break}return s.push(O(t,a)),s}}function st(t,e,r=0){return S(t,e,r)===r}function M(t,e=0,r=m(t)-e){return Ve(t,e,r)}function O(t,e,r=m(t)){return Ge(t,e,r)}function se(t){return Be(t)}var nt=Object.getOwnPropertyNames,ot=Object.getOwnPropertySymbols,at=Object.prototype.hasOwnProperty;function x(t,e){return function(s,n,o){return t(s,n,o)&&e(s,n,o)}}function $(t){return function(r,s,n){if(!r||!s||typeof r!="object"||typeof s!="object")return t(r,s,n);var o=n.cache,a=o.get(r),i=o.get(s);if(a&&i)return a===s&&i===r;o.set(r,s),o.set(s,r);var c=t(r,s,n);return o.delete(r),o.delete(s),c}}function _(t){return nt(t).concat(ot(t))}var ne=Object.hasOwn||function(t,e){return at.call(t,e)};function v(t,e){return t||e?t===e:t===e||t!==t&&e!==e}var oe="_owner",z=Object.getOwnPropertyDescriptor,B=Object.keys;function it(t,e,r){var s=t.length;if(e.length!==s)return!1;for(;s-- >0;)if(!r.equals(t[s],e[s],s,s,t,e,r))return!1;return!0}function ut(t,e){return v(t.getTime(),e.getTime())}function J(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.entries(),o=0,a,i;(a=n.next())&&!a.done;){for(var c=e.entries(),h=!1,u=0;(i=c.next())&&!i.done;){var l=a.value,f=l[0],b=l[1],d=i.value,y=d[0],q=d[1];!h&&!s[u]&&(h=r.equals(f,y,o,u,t,e,r)&&r.equals(b,q,f,y,t,e,r))&&(s[u]=!0),u++}if(!h)return!1;o++}return!0}function lt(t,e,r){var s=B(t),n=s.length;if(B(e).length!==n)return!1;for(var o;n-- >0;)if(o=s[n],o===oe&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!ne(e,o)||!r.equals(t[o],e[o],o,o,t,e,r))return!1;return!0}function w(t,e,r){var s=_(t),n=s.length;if(_(e).length!==n)return!1;for(var o,a,i;n-- >0;)if(o=s[n],o===oe&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!ne(e,o)||!r.equals(t[o],e[o],o,o,t,e,r)||(a=z(t,o),i=z(e,o),(a||i)&&(!a||!i||a.configurable!==i.configurable||a.enumerable!==i.enumerable||a.writable!==i.writable)))return!1;return!0}function ct(t,e){return v(t.valueOf(),e.valueOf())}function ft(t,e){return t.source===e.source&&t.flags===e.flags}function G(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.values(),o,a;(o=n.next())&&!o.done;){for(var i=e.values(),c=!1,h=0;(a=i.next())&&!a.done;)!c&&!s[h]&&(c=r.equals(o.value,a.value,o.value,a.value,t,e,r))&&(s[h]=!0),h++;if(!c)return!1}return!0}function ht(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}var pt="[object Arguments]",mt="[object Boolean]",dt="[object Date]",bt="[object Map]",gt="[object Number]",Nt="[object Object]",vt="[object RegExp]",yt="[object Set]",wt="[object String]",Et=Array.isArray,U=typeof ArrayBuffer=="function"&&ArrayBuffer.isView?ArrayBuffer.isView:null,V=Object.assign,Ot=Object.prototype.toString.call.bind(Object.prototype.toString);function $t(t){var e=t.areArraysEqual,r=t.areDatesEqual,s=t.areMapsEqual,n=t.areObjectsEqual,o=t.arePrimitiveWrappersEqual,a=t.areRegExpsEqual,i=t.areSetsEqual,c=t.areTypedArraysEqual;return function(u,l,f){if(u===l)return!0;if(u==null||l==null||typeof u!="object"||typeof l!="object")return u!==u&&l!==l;var b=u.constructor;if(b!==l.constructor)return!1;if(b===Object)return n(u,l,f);if(Et(u))return e(u,l,f);if(U!=null&&U(u))return c(u,l,f);if(b===Date)return r(u,l,f);if(b===RegExp)return a(u,l,f);if(b===Map)return s(u,l,f);if(b===Set)return i(u,l,f);var d=Ot(u);return d===dt?r(u,l,f):d===vt?a(u,l,f):d===bt?s(u,l,f):d===yt?i(u,l,f):d===Nt?typeof u.then!="function"&&typeof l.then!="function"&&n(u,l,f):d===pt?n(u,l,f):d===mt||d===gt||d===wt?o(u,l,f):!1}}function At(t){var e=t.circular,r=t.createCustomConfig,s=t.strict,n={areArraysEqual:s?w:it,areDatesEqual:ut,areMapsEqual:s?x(J,w):J,areObjectsEqual:s?w:lt,arePrimitiveWrappersEqual:ct,areRegExpsEqual:ft,areSetsEqual:s?x(G,w):G,areTypedArraysEqual:s?w:ht};if(r&&(n=V({},n,r(n))),e){var o=$(n.areArraysEqual),a=$(n.areMapsEqual),i=$(n.areObjectsEqual),c=$(n.areSetsEqual);n=V({},n,{areArraysEqual:o,areMapsEqual:a,areObjectsEqual:i,areSetsEqual:c})}return n}function St(t){return function(e,r,s,n,o,a,i){return t(e,r,i)}}function Mt(t){var e=t.circular,r=t.comparator,s=t.createState,n=t.equals,o=t.strict;if(s)return function(c,h){var u=s(),l=u.cache,f=l===void 0?e?new WeakMap:void 0:l,b=u.meta;return r(c,h,{cache:f,equals:n,meta:b,strict:o})};if(e)return function(c,h){return r(c,h,{cache:new WeakMap,equals:n,meta:void 0,strict:o})};var a={cache:void 0,equals:n,meta:void 0,strict:o};return function(c,h){return r(c,h,a)}}var qt=g();g({strict:!0});g({circular:!0});g({circular:!0,strict:!0});g({createInternalComparator:function(){return v}});g({strict:!0,createInternalComparator:function(){return v}});g({circular:!0,createInternalComparator:function(){return v}});g({circular:!0,createInternalComparator:function(){return v},strict:!0});function g(t){t===void 0&&(t={});var e=t.circular,r=e===void 0?!1:e,s=t.createInternalComparator,n=t.createState,o=t.strict,a=o===void 0?!1:o,i=At(t),c=$t(i),h=s?s(c):St(c);return Mt({circular:r,comparator:c,createState:n,equals:h,strict:a})}function jt(t,e){return qt(t,e)}function C(t,e,r){return JSON.stringify(t,(n,o)=>{let a=o;return e&&(a=e(n,a)),a===void 0&&(a=null),a},r)}function ae(t,e){function r(n){return Object.keys(n).forEach(o=>{n[o]===null?n[o]=void 0:typeof n[o]=="object"&&(n[o]=r(n[o]))}),n}const s=JSON.parse(t,e);if(s!==null)return typeof s=="object"?r(s):s}function Ct(t){try{const e=C(t);return e===C(ae(e))}catch{return!1}}const Pt=t=>t.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/"),ie={title:"Platform.Bible menus",type:"object",properties:{mainMenu:{description:"Top level menu for the application",$ref:"#/$defs/multiColumnMenu"},defaultWebViewTopMenu:{description:"Default top menu for web views that don't specify their own",$ref:"#/$defs/multiColumnMenu"},defaultWebViewContextMenu:{description:"Default context menu for web views that don't specify their own",$ref:"#/$defs/singleColumnMenu"},webViewMenus:{description:"Menus that apply per web view in the application",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{$ref:"#/$defs/menusForOneWebView"}},additionalProperties:!1}},required:["mainMenu","defaultWebViewTopMenu","defaultWebViewContextMenu","webViewMenus"],additionalProperties:!1,$defs:{localizeKey:{description:"Identifier for a string that will be localized in a menu based on the user's UI language",type:"string",pattern:"^%[\\w\\-\\.]+%$"},referencedItem:{description:"Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)",type:"string",pattern:"^[\\w\\-]+\\.[\\w\\-]+$"},columnsWithHeaders:{description:"Group of columns that can be combined with other columns to form a multi-column menu",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single column with a header string",type:"object",properties:{label:{description:"Header text for this this column in the UI",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},order:{description:"Relative order of this column compared to other columns (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu groups to this column",type:"boolean"}},required:["label","order"],additionalProperties:!1}},properties:{isExtensible:{description:"Defines whether contributions are allowed to add columns to this multi-column menu",type:"boolean"}}},menuGroups:{description:"Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single group that contains menu items",type:"object",oneOf:[{properties:{column:{description:"Column where this group belongs, not required for single column menus",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["order"],additionalProperties:!1},{properties:{menuItem:{description:"Menu item that anchors the submenu where this group belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["menuItem","order"],additionalProperties:!1}]}},additionalProperties:!1},menuItem:{description:"Single item in a menu that can be clicked on to take an action or can be the parent of a submenu",type:"object",oneOf:[{properties:{id:{description:"ID for this menu item that holds a submenu",$ref:"#/$defs/referencedItem"}},required:["id"]},{properties:{command:{description:"Name of the PAPI command to run when this menu item is selected.",$ref:"#/$defs/referencedItem"},iconPathBefore:{description:"Path to the icon to display before the menu text",type:"string"},iconPathAfter:{description:"Path to the icon to display after the menu text",type:"string"}},required:["command"]}],properties:{label:{description:"Key that represents the text of this menu item to display",$ref:"#/$defs/localizeKey"},tooltip:{description:"Key that represents the text to display if a mouse pointer hovers over the menu item",$ref:"#/$defs/localizeKey"},searchTerms:{description:"Key that represents additional words the platform should reference when users are searching for menu items",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},group:{description:"Group to which this menu item belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this menu item compared to other menu items in the same group (sorted ascending)",type:"number"}},required:["label","group","order"],unevaluatedProperties:!1},groupsAndItems:{description:"Core schema for a column",type:"object",properties:{groups:{description:"Groups that belong in this menu",$ref:"#/$defs/menuGroups"},items:{description:"List of menu items that belong in this menu",type:"array",items:{$ref:"#/$defs/menuItem"},uniqueItems:!0}},required:["groups","items"]},singleColumnMenu:{description:"Menu that contains a column without a header",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"}],unevaluatedProperties:!1},multiColumnMenu:{description:"Menu that can contain multiple columns with headers",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"},{properties:{columns:{description:"Columns that belong in this menu",$ref:"#/$defs/columnsWithHeaders"}},required:["columns"]}],unevaluatedProperties:!1},menusForOneWebView:{description:"Set of menus that are associated with a single tab",type:"object",properties:{includeDefaults:{description:"Indicates whether the platform default menus should be included for this webview",type:"boolean"},topMenu:{description:"Menu that opens when you click on the top left corner of a tab",$ref:"#/$defs/multiColumnMenu"},contextMenu:{description:"Menu that opens when you right click on the main body/area of a tab",$ref:"#/$defs/singleColumnMenu"}},additionalProperties:!1}}};Object.freeze(ie);exports.AsyncVariable=be;exports.DocumentCombinerEngine=Se;exports.FIRST_SCR_BOOK_NUM=L;exports.FIRST_SCR_CHAPTER_NUM=X;exports.FIRST_SCR_VERSE_NUM=Q;exports.LAST_SCR_BOOK_NUM=Z;exports.Mutex=W;exports.MutexMap=Pe;exports.PlatformEventEmitter=Ce;exports.UnsubscriberAsyncList=je;exports.aggregateUnsubscriberAsyncs=xe;exports.aggregateUnsubscribers=Ie;exports.at=We;exports.charAt=Ke;exports.codePointAt=Le;exports.createSyncProxyForAsyncObject=Ae;exports.debounce=Ne;exports.deepClone=E;exports.deepEqual=jt;exports.deserialize=ae;exports.endsWith=Ze;exports.getAllObjectFunctionNames=$e;exports.getChaptersForBook=Y;exports.getErrorMessage=Ee;exports.groupBy=ve;exports.htmlEncode=Pt;exports.includes=Xe;exports.indexOf=S;exports.isSerializable=Ct;exports.isString=F;exports.lastIndexOf=re;exports.length=m;exports.menuDocumentSchema=ie;exports.newGuid=ge;exports.normalize=Qe;exports.offsetBook=Te;exports.offsetChapter=Re;exports.offsetVerse=De;exports.padEnd=Ye;exports.padStart=et;exports.serialize=C;exports.slice=tt;exports.split=rt;exports.startsWith=st;exports.substring=O;exports.toArray=se;exports.wait=H;exports.waitForDuration=Oe; +"use strict";var pe=Object.defineProperty;var me=(t,e,r)=>e in t?pe(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var p=(t,e,r)=>(me(t,typeof e!="symbol"?e+"":e,r),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const de=require("async-mutex");class be{constructor(e,r=1e4){p(this,"variableName");p(this,"promiseToValue");p(this,"resolver");p(this,"rejecter");this.variableName=e,this.promiseToValue=new Promise((s,n)=>{this.resolver=s,this.rejecter=n}),r>0&&setTimeout(()=>{this.rejecter&&(this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`),this.complete())},r),Object.seal(this)}get promise(){return this.promiseToValue}get hasSettled(){return Object.isFrozen(this)}resolveToValue(e,r=!1){if(this.resolver)console.debug(`${this.variableName} is being resolved now`),this.resolver(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent resolution of ${this.variableName}`)}}rejectWithReason(e,r=!1){if(this.rejecter)console.debug(`${this.variableName} is being rejected now`),this.rejecter(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent rejection of ${this.variableName}`)}}complete(){this.resolver=void 0,this.rejecter=void 0,Object.freeze(this)}}function ge(){return"00-0-4-1-000".replace(/[^-]/g,t=>((Math.random()+~~t)*65536>>t).toString(16).padStart(4,"0"))}function F(t){return typeof t=="string"||t instanceof String}function E(t){return JSON.parse(JSON.stringify(t))}function Ne(t,e=300){if(F(t))throw new Error("Tried to debounce a string! Could be XSS");let r;return(...s)=>{clearTimeout(r),r=setTimeout(()=>t(...s),e)}}function ve(t,e,r){const s=new Map;return t.forEach(n=>{const o=e(n),a=s.get(o),i=r?r(n,o):n;a?a.push(i):s.set(o,[i])}),s}function ye(t){return typeof t=="object"&&t!==null&&"message"in t&&typeof t.message=="string"}function we(t){if(ye(t))return t;try{return new Error(JSON.stringify(t))}catch{return new Error(String(t))}}function Ee(t){return we(t).message}function H(t){return new Promise(e=>setTimeout(e,t))}function Oe(t,e){const r=H(e).then(()=>{});return Promise.any([r,t()])}function $e(t,e="obj"){const r=new Set;Object.getOwnPropertyNames(t).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e} due to error: ${o}`)}});let s=Object.getPrototypeOf(t);for(;s&&Object.getPrototypeOf(s);)Object.getOwnPropertyNames(s).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e}'s prototype due to error: ${o}`)}}),s=Object.getPrototypeOf(s);return r}function Ae(t,e={}){return new Proxy(e,{get(r,s){return s in r?r[s]:async(...n)=>(await t())[s](...n)}})}class Se{constructor(e,r){p(this,"baseDocument");p(this,"contributions",new Map);p(this,"latestOutput");p(this,"options");this.baseDocument=e,this.options=r,this.updateBaseDocument(e)}updateBaseDocument(e){return this.validateStartingDocument(e),this.baseDocument=this.options.copyDocuments?E(e):e,this.rebuild()}addOrUpdateContribution(e,r){this.validateContribution(e,r);const s=this.contributions.get(e),n=this.options.copyDocuments&&r?E(r):r;this.contributions.set(e,n);try{return this.rebuild()}catch(o){throw s?this.contributions.set(e,s):this.contributions.delete(e),new Error(`Error when setting the document named ${e}: ${o}`)}}deleteContribution(e){const r=this.contributions.get(e);if(!r)throw new Error("{documentKey} does not exist");this.contributions.delete(e);try{return this.rebuild()}catch(s){throw this.contributions.set(e,r),new Error(`Error when deleting the document named ${e}: ${s}`)}}rebuild(){if(this.contributions.size===0){let r=E(this.baseDocument);return r=this.transformFinalOutput(r),this.validateOutput(r),this.latestOutput=r,this.latestOutput}let e=this.baseDocument;return this.contributions.forEach(r=>{e=k(e,r,this.options.ignoreDuplicateProperties),this.validateOutput(e)}),e=this.transformFinalOutput(e),this.validateOutput(e),this.latestOutput=e,this.latestOutput}}function Me(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||Array.isArray(r))&&(e=!1)}),e}function qe(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||!Array.isArray(r))&&(e=!1)}),e}function k(t,e,r){const s=E(t);return e&&Object.keys(e).forEach(n=>{if(Object.hasOwn(t,n)){if(Me(t[n],e[n]))s[n]=k(t[n],e[n],r);else if(qe(t[n],e[n]))s[n]=s[n].concat(e[n]);else if(!r)throw new Error(`Cannot merge objects: key "${n}" already exists in the target object`)}else s[n]=e[n]}),s}class je{constructor(e="Anonymous"){p(this,"unsubscribers",new Set);this.name=e}add(...e){e.forEach(r=>{"dispose"in r?this.unsubscribers.add(r.dispose):this.unsubscribers.add(r)})}async runAllUnsubscribers(){const e=[...this.unsubscribers].map(s=>s()),r=await Promise.all(e);return this.unsubscribers.clear(),r.every((s,n)=>(s||console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${n} failed!`),s))}}class Ce{constructor(){p(this,"subscribe",this.event);p(this,"subscriptions");p(this,"lazyEvent");p(this,"isDisposed",!1);p(this,"dispose",()=>this.disposeFn());p(this,"emit",e=>{this.emitFn(e)})}get event(){return this.assertNotDisposed(),this.lazyEvent||(this.lazyEvent=e=>{if(!e||typeof e!="function")throw new Error("Event handler callback must be a function!");return this.subscriptions||(this.subscriptions=[]),this.subscriptions.push(e),()=>{if(!this.subscriptions)return!1;const r=this.subscriptions.indexOf(e);return r<0?!1:(this.subscriptions.splice(r,1),!0)}}),this.lazyEvent}emitFn(e){var r;this.assertNotDisposed(),(r=this.subscriptions)==null||r.forEach(s=>s(e))}assertNotDisposed(){if(this.isDisposed)throw new Error("Emitter is disposed")}disposeFn(){return this.assertNotDisposed(),this.isDisposed=!0,this.subscriptions=void 0,this.lazyEvent=void 0,Promise.resolve(!0)}}class W extends de.Mutex{}class Pe{constructor(){p(this,"mutexesByID",new Map)}get(e){let r=this.mutexesByID.get(e);return r||(r=new W,this.mutexesByID.set(e,r),r)}}const K=[{shortName:"ERR",fullNames:["ERROR"],chapters:-1},{shortName:"GEN",fullNames:["Genesis"],chapters:50},{shortName:"EXO",fullNames:["Exodus"],chapters:40},{shortName:"LEV",fullNames:["Leviticus"],chapters:27},{shortName:"NUM",fullNames:["Numbers"],chapters:36},{shortName:"DEU",fullNames:["Deuteronomy"],chapters:34},{shortName:"JOS",fullNames:["Joshua"],chapters:24},{shortName:"JDG",fullNames:["Judges"],chapters:21},{shortName:"RUT",fullNames:["Ruth"],chapters:4},{shortName:"1SA",fullNames:["1 Samuel"],chapters:31},{shortName:"2SA",fullNames:["2 Samuel"],chapters:24},{shortName:"1KI",fullNames:["1 Kings"],chapters:22},{shortName:"2KI",fullNames:["2 Kings"],chapters:25},{shortName:"1CH",fullNames:["1 Chronicles"],chapters:29},{shortName:"2CH",fullNames:["2 Chronicles"],chapters:36},{shortName:"EZR",fullNames:["Ezra"],chapters:10},{shortName:"NEH",fullNames:["Nehemiah"],chapters:13},{shortName:"EST",fullNames:["Esther"],chapters:10},{shortName:"JOB",fullNames:["Job"],chapters:42},{shortName:"PSA",fullNames:["Psalm","Psalms"],chapters:150},{shortName:"PRO",fullNames:["Proverbs"],chapters:31},{shortName:"ECC",fullNames:["Ecclesiastes"],chapters:12},{shortName:"SNG",fullNames:["Song of Solomon","Song of Songs"],chapters:8},{shortName:"ISA",fullNames:["Isaiah"],chapters:66},{shortName:"JER",fullNames:["Jeremiah"],chapters:52},{shortName:"LAM",fullNames:["Lamentations"],chapters:5},{shortName:"EZK",fullNames:["Ezekiel"],chapters:48},{shortName:"DAN",fullNames:["Daniel"],chapters:12},{shortName:"HOS",fullNames:["Hosea"],chapters:14},{shortName:"JOL",fullNames:["Joel"],chapters:3},{shortName:"AMO",fullNames:["Amos"],chapters:9},{shortName:"OBA",fullNames:["Obadiah"],chapters:1},{shortName:"JON",fullNames:["Jonah"],chapters:4},{shortName:"MIC",fullNames:["Micah"],chapters:7},{shortName:"NAM",fullNames:["Nahum"],chapters:3},{shortName:"HAB",fullNames:["Habakkuk"],chapters:3},{shortName:"ZEP",fullNames:["Zephaniah"],chapters:3},{shortName:"HAG",fullNames:["Haggai"],chapters:2},{shortName:"ZEC",fullNames:["Zechariah"],chapters:14},{shortName:"MAL",fullNames:["Malachi"],chapters:4},{shortName:"MAT",fullNames:["Matthew"],chapters:28},{shortName:"MRK",fullNames:["Mark"],chapters:16},{shortName:"LUK",fullNames:["Luke"],chapters:24},{shortName:"JHN",fullNames:["John"],chapters:21},{shortName:"ACT",fullNames:["Acts"],chapters:28},{shortName:"ROM",fullNames:["Romans"],chapters:16},{shortName:"1CO",fullNames:["1 Corinthians"],chapters:16},{shortName:"2CO",fullNames:["2 Corinthians"],chapters:13},{shortName:"GAL",fullNames:["Galatians"],chapters:6},{shortName:"EPH",fullNames:["Ephesians"],chapters:6},{shortName:"PHP",fullNames:["Philippians"],chapters:4},{shortName:"COL",fullNames:["Colossians"],chapters:4},{shortName:"1TH",fullNames:["1 Thessalonians"],chapters:5},{shortName:"2TH",fullNames:["2 Thessalonians"],chapters:3},{shortName:"1TI",fullNames:["1 Timothy"],chapters:6},{shortName:"2TI",fullNames:["2 Timothy"],chapters:4},{shortName:"TIT",fullNames:["Titus"],chapters:3},{shortName:"PHM",fullNames:["Philemon"],chapters:1},{shortName:"HEB",fullNames:["Hebrews"],chapters:13},{shortName:"JAS",fullNames:["James"],chapters:5},{shortName:"1PE",fullNames:["1 Peter"],chapters:5},{shortName:"2PE",fullNames:["2 Peter"],chapters:3},{shortName:"1JN",fullNames:["1 John"],chapters:5},{shortName:"2JN",fullNames:["2 John"],chapters:1},{shortName:"3JN",fullNames:["3 John"],chapters:1},{shortName:"JUD",fullNames:["Jude"],chapters:1},{shortName:"REV",fullNames:["Revelation"],chapters:22}],L=1,Z=K.length-1,X=1,Q=1,Y=t=>{var e;return((e=K[t])==null?void 0:e.chapters)??-1},Te=(t,e)=>({bookNum:Math.max(L,Math.min(t.bookNum+e,Z)),chapterNum:1,verseNum:1}),Re=(t,e)=>({...t,chapterNum:Math.min(Math.max(X,t.chapterNum+e),Y(t.bookNum)),verseNum:1}),De=(t,e)=>({...t,verseNum:Math.max(Q,t.verseNum+e)}),Ie=t=>(...e)=>t.map(s=>s(...e)).every(s=>s),xe=t=>async(...e)=>{const r=t.map(async s=>s(...e));return(await Promise.all(r)).every(s=>s)};var D=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},N={},_e=()=>{const t="\\ud800-\\udfff",e="\\u0300-\\u036f",r="\\ufe20-\\ufe2f",s="\\u20d0-\\u20ff",n="\\u1ab0-\\u1aff",o="\\u1dc0-\\u1dff",a=e+r+s+n+o,i="\\ufe0e\\ufe0f",c="\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93",h=`[${t}]`,u=`[${a}]`,l="\\ud83c[\\udffb-\\udfff]",f=`(?:${u}|${l})`,b=`[^${t}]`,d="(?:\\uD83C[\\uDDE6-\\uDDFF]){2}",y="[\\ud800-\\udbff][\\udc00-\\udfff]",q="\\u200d",ue="(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)",le=`[${c}]`,T=`${f}?`,R=`[${i}]?`,ce=`(?:${q}(?:${[b,d,y].join("|")})${R+T})*`,fe=R+T+ce,he=`(?:${[`${b}${u}?`,u,d,y,h,le].join("|")})`;return new RegExp(`${ue}|${l}(?=${l})|${he+fe}`,"g")},ze=D&&D.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(N,"__esModule",{value:!0});var A=ze(_e);function j(t){if(typeof t!="string")throw new Error("A string is expected as input");return t.match(A.default())||[]}var Be=N.toArray=j;function P(t){if(typeof t!="string")throw new Error("Input must be a string");var e=t.match(A.default());return e===null?0:e.length}var Je=N.length=P;function ee(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");(typeof e!="number"||e<0)&&(e=0),typeof r=="number"&&r<0&&(r=0);var s=t.match(A.default());return s?s.slice(e,r).join(""):""}var Ge=N.substring=ee;function Ue(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");var s=P(t);if(typeof e!="number"&&(e=parseInt(e,10)),e>=s)return"";e<0&&(e+=s);var n;typeof r>"u"?n=s:(typeof r!="number"&&(r=parseInt(r,10)),n=r>=0?r+e:e);var o=t.match(A.default());return o?o.slice(e,n).join(""):""}var Ve=N.substr=Ue;function Fe(t,e,r,s){if(e===void 0&&(e=16),r===void 0&&(r="#"),s===void 0&&(s="right"),typeof t!="string"||typeof e!="number")throw new Error("Invalid arguments specified");if(["left","right"].indexOf(s)===-1)throw new Error("Pad position should be either left or right");typeof r!="string"&&(r=String(r));var n=P(t);if(n>e)return ee(t,0,e);if(n=s.length)return e===""?s.length:-1;if(e==="")return r;var n=j(e),o=!1,a;for(a=r;am(t)||e<-m(t)))return M(t,e,1)}function Ke(t,e){return e<0||e>m(t)-1?"":M(t,e,1)}function Le(t,e){if(!(e<0||e>m(t)-1))return M(t,e,1).codePointAt(0)}function Ze(t,e,r=m(t)){const s=re(t,e);return!(s===-1||s+m(e)!==r)}function Xe(t,e,r=0){const s=O(t,r);return S(s,e)!==-1}function S(t,e,r=0){return ke(t,e,r)}function re(t,e,r=1/0){let s=r;s<0?s=0:s>=m(t)&&(s=m(t)-1);for(let n=s;n>=0;n--)if(M(t,n,m(e))===e)return n;return-1}function m(t){return Je(t)}function Qe(t,e){const r=e.toUpperCase();return r==="NONE"?t:t.normalize(r)}function Ye(t,e,r=" "){return e<=m(t)?t:te(t,e,r,"right")}function et(t,e,r=" "){return e<=m(t)?t:te(t,e,r,"left")}function I(t,e){return e>t?t:e<-t?0:e<0?e+t:e}function tt(t,e,r){const s=m(t);if(e>s||r&&(e>r&&!(e>0&&e-s)||r<-s||e<0&&e>-s&&r>0))return"";const n=I(s,e),o=r?I(s,r):void 0;return O(t,n,o)}function rt(t,e,r){const s=[];if(r!==void 0&&r<=0)return[t];if(e==="")return se(t).slice(0,r);let n=e;(typeof e=="string"||e instanceof RegExp&&!e.flags.includes("g"))&&(n=new RegExp(e,"g"));const o=t.match(n);let a=0;if(!o)return[t];for(let i=0;i<(r?r-1:o.length);i++){const c=S(t,o[i],a),h=m(o[i]);if(s.push(O(t,a,c)),a=c+h,r!==void 0&&s.length===r)break}return s.push(O(t,a)),s}function st(t,e,r=0){return S(t,e,r)===r}function M(t,e=0,r=m(t)-e){return Ve(t,e,r)}function O(t,e,r=m(t)){return Ge(t,e,r)}function se(t){return Be(t)}var nt=Object.getOwnPropertyNames,ot=Object.getOwnPropertySymbols,at=Object.prototype.hasOwnProperty;function x(t,e){return function(s,n,o){return t(s,n,o)&&e(s,n,o)}}function $(t){return function(r,s,n){if(!r||!s||typeof r!="object"||typeof s!="object")return t(r,s,n);var o=n.cache,a=o.get(r),i=o.get(s);if(a&&i)return a===s&&i===r;o.set(r,s),o.set(s,r);var c=t(r,s,n);return o.delete(r),o.delete(s),c}}function _(t){return nt(t).concat(ot(t))}var ne=Object.hasOwn||function(t,e){return at.call(t,e)};function v(t,e){return t||e?t===e:t===e||t!==t&&e!==e}var oe="_owner",z=Object.getOwnPropertyDescriptor,B=Object.keys;function it(t,e,r){var s=t.length;if(e.length!==s)return!1;for(;s-- >0;)if(!r.equals(t[s],e[s],s,s,t,e,r))return!1;return!0}function ut(t,e){return v(t.getTime(),e.getTime())}function J(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.entries(),o=0,a,i;(a=n.next())&&!a.done;){for(var c=e.entries(),h=!1,u=0;(i=c.next())&&!i.done;){var l=a.value,f=l[0],b=l[1],d=i.value,y=d[0],q=d[1];!h&&!s[u]&&(h=r.equals(f,y,o,u,t,e,r)&&r.equals(b,q,f,y,t,e,r))&&(s[u]=!0),u++}if(!h)return!1;o++}return!0}function lt(t,e,r){var s=B(t),n=s.length;if(B(e).length!==n)return!1;for(var o;n-- >0;)if(o=s[n],o===oe&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!ne(e,o)||!r.equals(t[o],e[o],o,o,t,e,r))return!1;return!0}function w(t,e,r){var s=_(t),n=s.length;if(_(e).length!==n)return!1;for(var o,a,i;n-- >0;)if(o=s[n],o===oe&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!ne(e,o)||!r.equals(t[o],e[o],o,o,t,e,r)||(a=z(t,o),i=z(e,o),(a||i)&&(!a||!i||a.configurable!==i.configurable||a.enumerable!==i.enumerable||a.writable!==i.writable)))return!1;return!0}function ct(t,e){return v(t.valueOf(),e.valueOf())}function ft(t,e){return t.source===e.source&&t.flags===e.flags}function G(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.values(),o,a;(o=n.next())&&!o.done;){for(var i=e.values(),c=!1,h=0;(a=i.next())&&!a.done;)!c&&!s[h]&&(c=r.equals(o.value,a.value,o.value,a.value,t,e,r))&&(s[h]=!0),h++;if(!c)return!1}return!0}function ht(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}var pt="[object Arguments]",mt="[object Boolean]",dt="[object Date]",bt="[object Map]",gt="[object Number]",Nt="[object Object]",vt="[object RegExp]",yt="[object Set]",wt="[object String]",Et=Array.isArray,U=typeof ArrayBuffer=="function"&&ArrayBuffer.isView?ArrayBuffer.isView:null,V=Object.assign,Ot=Object.prototype.toString.call.bind(Object.prototype.toString);function $t(t){var e=t.areArraysEqual,r=t.areDatesEqual,s=t.areMapsEqual,n=t.areObjectsEqual,o=t.arePrimitiveWrappersEqual,a=t.areRegExpsEqual,i=t.areSetsEqual,c=t.areTypedArraysEqual;return function(u,l,f){if(u===l)return!0;if(u==null||l==null||typeof u!="object"||typeof l!="object")return u!==u&&l!==l;var b=u.constructor;if(b!==l.constructor)return!1;if(b===Object)return n(u,l,f);if(Et(u))return e(u,l,f);if(U!=null&&U(u))return c(u,l,f);if(b===Date)return r(u,l,f);if(b===RegExp)return a(u,l,f);if(b===Map)return s(u,l,f);if(b===Set)return i(u,l,f);var d=Ot(u);return d===dt?r(u,l,f):d===vt?a(u,l,f):d===bt?s(u,l,f):d===yt?i(u,l,f):d===Nt?typeof u.then!="function"&&typeof l.then!="function"&&n(u,l,f):d===pt?n(u,l,f):d===mt||d===gt||d===wt?o(u,l,f):!1}}function At(t){var e=t.circular,r=t.createCustomConfig,s=t.strict,n={areArraysEqual:s?w:it,areDatesEqual:ut,areMapsEqual:s?x(J,w):J,areObjectsEqual:s?w:lt,arePrimitiveWrappersEqual:ct,areRegExpsEqual:ft,areSetsEqual:s?x(G,w):G,areTypedArraysEqual:s?w:ht};if(r&&(n=V({},n,r(n))),e){var o=$(n.areArraysEqual),a=$(n.areMapsEqual),i=$(n.areObjectsEqual),c=$(n.areSetsEqual);n=V({},n,{areArraysEqual:o,areMapsEqual:a,areObjectsEqual:i,areSetsEqual:c})}return n}function St(t){return function(e,r,s,n,o,a,i){return t(e,r,i)}}function Mt(t){var e=t.circular,r=t.comparator,s=t.createState,n=t.equals,o=t.strict;if(s)return function(c,h){var u=s(),l=u.cache,f=l===void 0?e?new WeakMap:void 0:l,b=u.meta;return r(c,h,{cache:f,equals:n,meta:b,strict:o})};if(e)return function(c,h){return r(c,h,{cache:new WeakMap,equals:n,meta:void 0,strict:o})};var a={cache:void 0,equals:n,meta:void 0,strict:o};return function(c,h){return r(c,h,a)}}var qt=g();g({strict:!0});g({circular:!0});g({circular:!0,strict:!0});g({createInternalComparator:function(){return v}});g({strict:!0,createInternalComparator:function(){return v}});g({circular:!0,createInternalComparator:function(){return v}});g({circular:!0,createInternalComparator:function(){return v},strict:!0});function g(t){t===void 0&&(t={});var e=t.circular,r=e===void 0?!1:e,s=t.createInternalComparator,n=t.createState,o=t.strict,a=o===void 0?!1:o,i=At(t),c=$t(i),h=s?s(c):St(c);return Mt({circular:r,comparator:c,createState:n,equals:h,strict:a})}function jt(t,e){return qt(t,e)}function C(t,e,r){return JSON.stringify(t,(n,o)=>{let a=o;return e&&(a=e(n,a)),a===void 0&&(a=null),a},r)}function ae(t,e){function r(n){return Object.keys(n).forEach(o=>{n[o]===null?n[o]=void 0:typeof n[o]=="object"&&(n[o]=r(n[o]))}),n}const s=JSON.parse(t,e);if(s!==null)return typeof s=="object"?r(s):s}function Ct(t){try{const e=C(t);return e===C(ae(e))}catch{return!1}}const Pt=t=>t.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/"),ie={title:"Platform.Bible menus",type:"object",properties:{mainMenu:{description:"Top level menu for the application",$ref:"#/$defs/multiColumnMenu"},defaultWebViewTopMenu:{description:"Default top menu for web views that don't specify their own",$ref:"#/$defs/multiColumnMenu"},defaultWebViewContextMenu:{description:"Default context menu for web views that don't specify their own",$ref:"#/$defs/singleColumnMenu"},webViewMenus:{description:"Menus that apply per web view in the application",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{$ref:"#/$defs/menusForOneWebView"}},additionalProperties:!1}},required:["mainMenu","defaultWebViewTopMenu","defaultWebViewContextMenu","webViewMenus"],additionalProperties:!1,$defs:{localizeKey:{description:"Identifier for a string that will be localized in a menu based on the user's UI language",type:"string",pattern:"^%[\\w\\-\\.]+%$"},referencedItem:{description:"Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)",type:"string",pattern:"^[\\w\\-]+\\.[\\w\\-]+$"},columnsWithHeaders:{description:"Group of columns that can be combined with other columns to form a multi-column menu",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single column with a header string",type:"object",properties:{label:{description:"Header text for this this column in the UI",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},order:{description:"Relative order of this column compared to other columns (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu groups to this column",type:"boolean"}},required:["label","order"],additionalProperties:!1}},properties:{isExtensible:{description:"Defines whether contributions are allowed to add columns to this multi-column menu",type:"boolean"}}},menuGroups:{description:"Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single group that contains menu items",type:"object",oneOf:[{properties:{column:{description:"Column where this group belongs, not required for single column menus",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["order"],additionalProperties:!1},{properties:{menuItem:{description:"Menu item that anchors the submenu where this group belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["menuItem","order"],additionalProperties:!1}]}},additionalProperties:!1},menuItem:{description:"Single item in a menu that can be clicked on to take an action or can be the parent of a submenu",type:"object",oneOf:[{properties:{id:{description:"ID for this menu item that holds a submenu",$ref:"#/$defs/referencedItem"}},required:["id"]},{properties:{command:{description:"Name of the PAPI command to run when this menu item is selected.",$ref:"#/$defs/referencedItem"},iconPathBefore:{description:"Path to the icon to display before the menu text",type:"string"},iconPathAfter:{description:"Path to the icon to display after the menu text",type:"string"}},required:["command"]}],properties:{label:{description:"Key that represents the text of this menu item to display",$ref:"#/$defs/localizeKey"},tooltip:{description:"Key that represents the text to display if a mouse pointer hovers over the menu item",$ref:"#/$defs/localizeKey"},searchTerms:{description:"Key that represents additional words the platform should reference when users are searching for menu items",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},group:{description:"Group to which this menu item belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this menu item compared to other menu items in the same group (sorted ascending)",type:"number"}},required:["label","group","order"],unevaluatedProperties:!1},groupsAndItems:{description:"Core schema for a column",type:"object",properties:{groups:{description:"Groups that belong in this menu",$ref:"#/$defs/menuGroups"},items:{description:"List of menu items that belong in this menu",type:"array",items:{$ref:"#/$defs/menuItem"},uniqueItems:!0}},required:["groups","items"]},singleColumnMenu:{description:"Menu that contains a column without a header",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"}],unevaluatedProperties:!1},multiColumnMenu:{description:"Menu that can contain multiple columns with headers",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"},{properties:{columns:{description:"Columns that belong in this menu",$ref:"#/$defs/columnsWithHeaders"}},required:["columns"]}],unevaluatedProperties:!1},menusForOneWebView:{description:"Set of menus that are associated with a single tab",type:"object",properties:{includeDefaults:{description:"Indicates whether the platform default menus should be included for this webview",type:"boolean"},topMenu:{description:"Menu that opens when you click on the top left corner of a tab",$ref:"#/$defs/multiColumnMenu"},contextMenu:{description:"Menu that opens when you right click on the main body/area of a tab",$ref:"#/$defs/singleColumnMenu"}},additionalProperties:!1}}};Object.freeze(ie);exports.AsyncVariable=be;exports.DocumentCombinerEngine=Se;exports.FIRST_SCR_BOOK_NUM=L;exports.FIRST_SCR_CHAPTER_NUM=X;exports.FIRST_SCR_VERSE_NUM=Q;exports.LAST_SCR_BOOK_NUM=Z;exports.Mutex=W;exports.MutexMap=Pe;exports.PlatformEventEmitter=Ce;exports.UnsubscriberAsyncList=je;exports.aggregateUnsubscriberAsyncs=xe;exports.aggregateUnsubscribers=Ie;exports.at=We;exports.charAt=Ke;exports.codePointAt=Le;exports.createSyncProxyForAsyncObject=Ae;exports.debounce=Ne;exports.deepClone=E;exports.deepEqual=jt;exports.deserialize=ae;exports.endsWith=Ze;exports.getAllObjectFunctionNames=$e;exports.getChaptersForBook=Y;exports.getErrorMessage=Ee;exports.groupBy=ve;exports.htmlEncode=Pt;exports.includes=Xe;exports.indexOf=S;exports.isSerializable=Ct;exports.isString=F;exports.lastIndexOf=re;exports.length=m;exports.menuDocumentSchema=ie;exports.newGuid=ge;exports.normalize=Qe;exports.offsetBook=Te;exports.offsetChapter=Re;exports.offsetVerse=De;exports.padEnd=Ye;exports.padStart=et;exports.serialize=C;exports.slice=tt;exports.split=rt;exports.startsWith=st;exports.substring=O;exports.toArray=se;exports.wait=H;exports.waitForDuration=Oe; //# sourceMappingURL=index.cjs.map diff --git a/lib/platform-bible-utils/dist/index.cjs.map b/lib/platform-bible-utils/dist/index.cjs.map index e2cf90cd78..b470f6aadb 100644 --- a/lib/platform-bible-utils/dist/index.cjs.map +++ b/lib/platform-bible-utils/dist/index.cjs.map @@ -1 +1 @@ -{"version":3,"file":"index.cjs","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/mutex.ts","../src/mutex-map.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { Mutex as AsyncMutex } from 'async-mutex';\n\n// Extending Mutex from async-mutex so we can add JSDoc\n\n/**\n * Class that allows calling asynchronous functions multiple times at once while only running one at\n * a time.\n *\n * @example\n *\n * ```typescript\n * const mutex = new Mutex();\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n * ```\n *\n * See [`async-mutex`](https://www.npmjs.com/package/async-mutex) for more information.\n */\nclass Mutex extends AsyncMutex {}\n\nexport default Mutex;\n","import Mutex from './mutex';\n\n/** Map of {@link Mutex}es that automatically (lazily) generates a new {@link Mutex} for any new key */\nclass MutexMap {\n private mutexesByID = new Map();\n\n get(mutexID: string): Mutex {\n let retVal = this.mutexesByID.get(mutexID);\n if (retVal) return retVal;\n\n retVal = new Mutex();\n this.mutexesByID.set(mutexID, retVal);\n return retVal;\n }\n}\n\nexport default MutexMap;\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * Finds the Unicode code point at the given index\n *\n * @param {string} string String to index\n * @param {number} index Position of the character to be returned in range of 0 to -length(string)\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > length(string) || index < -length(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * Always indexes string as a sequence of Unicode code points\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, empty string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > length(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to index\n * @param {number} index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {number | undefined} Non-negative integer representing the code point value of the\n * character at the given index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > length(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * Determines whether a string ends with the characters of this string. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Characters to search for at the end of the string\n * @param {number} [endPosition=length(string)] End position where searchString is expected to be\n * found. Default is `length(string)`\n * @returns {boolean} True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = length(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + length(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * Performs a case-sensitive search to determine if searchString is found in string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString String to search for\n * @param {string} [position=0] Position within the string to start searching for searchString.\n * Default is `0`\n * @returns {boolean} True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * Returns the index of the first occurrence of a given string. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The string to search for\n * @param {number} [position=0] Start of searching. Default is `0`\n * @returns {number} Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * Searches this string and returns the index of the last occurrence of the specified substring.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Substring to search for\n * @param {number} [position=+Infinity] The method returns the index of the last occurrence of the\n * specified substring at a position less than or equal to position. . Default is `+Infinity`\n * @returns {number} Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(\n string: string,\n searchString: string,\n position: number = +Infinity,\n): number {\n let validatedPosition = position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= length(string)) {\n validatedPosition = length(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, length(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * Returns the length of a string. This function handles Unicode code points instead of UTF-16\n * character codes.\n *\n * @param {string} string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function length(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * Returns the Unicode Normalization Form of this string.\n *\n * @param {string} string The starting string\n * @param {'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'} [form='NFC'] Form specifying the Unicode\n * Normalization Form. Default is `'NFC'`\n * @returns {string} A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within targetLength, it will be truncated. Default is `\" \"`\n * @returns {string} String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\nfunction correctSliceIndex(stringLength: number, index: number) {\n if (index > stringLength) return stringLength;\n if (index < -stringLength) return 0;\n if (index < 0) return index + stringLength;\n return index;\n}\n\n/**\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The starting string\n * @param {number} indexStart The index of the first character to include in the returned substring.\n * @param {number} indexEnd The index of the first character to exclude from the returned substring.\n * @returns {string} A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const stringLength: number = length(string);\n if (\n indexStart > stringLength ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(\n indexStart > 0 &&\n indexStart < stringLength &&\n indexEnd < 0 &&\n indexEnd > -stringLength\n )) ||\n indexEnd < -stringLength ||\n (indexStart < 0 && indexStart > -stringLength && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(stringLength, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The string to split\n * @param {string | RegExp} separator The pattern describing where each split should occur\n * @param {number} splitLimit Limit on the number of substrings to be included in the array. Splits\n * the string at each occurrence of specified separator, but stops when limit entries have been\n * placed in the array.\n * @returns {string[] | undefined} An array of strings, split at each point where separator occurs\n * in the starting string. Returns undefined if separator is not found in string.\n */\nexport function split(\n string: string,\n separator: string | RegExp,\n splitLimit?: number,\n): string[] | undefined {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !separator.flags.includes('g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return undefined;\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = length(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate. This function handles Unicode code points instead of UTF-16 character\n * codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The characters to be searched for at the start of this string.\n * @param {number} [position=0] The start position at which searchString is expected to be found\n * (the index of searchString's first character). Default is `0`\n * @returns {boolean} True if the given characters are found at the beginning of the string,\n * including when searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * Returns a substring by providing start and length. This function handles Unicode code points\n * instead of UTF-16 character codes. This function is not exported because it is considered\n * deprecated, however it is still useful as a local helper function.\n *\n * @param {string} string String to be divided\n * @param {number} [begin=Start of string] Start position. Default is `Start of string`\n * @param {number} [len=String length minus start parameter] Length of result. Default is `String\n * length minus start parameter`. Default is `String length minus start parameter`\n * @returns {string} Substring from starting string\n */\nfunction substr(string: string, begin: number = 0, len: number = length(string) - begin): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * Returns a substring by providing start and end position. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to be divided\n * @param {string} begin Start position\n * @param {number} [end=End of string] End position. Default is `End of string`\n * @returns {string} Substring from starting string\n */\nexport function substring(\n string: string,\n begin?: number | undefined,\n end: number | undefined = length(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * Converts a string to an array of string characters. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param {string} string String to convert to array\n * @returns {string[]} An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","Mutex","AsyncMutex","MutexMap","mutexID","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","stringLength","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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Aa,8DACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,WAAY,OAAO,EAC9B,qBAAsB,EACxB,CACF,CACF,CACF,EACA,qBAAsB,EACxB,EACA,SAAU,CACR,YACE,mGACF,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,GAAI,CACF,YAAa,6CACb,KAAM,wBACR,CACF,EACA,SAAU,CAAC,IAAI,CACjB,EACA,CACE,WAAY,CACV,QAAS,CACP,YAAa,mEACb,KAAM,wBACR,EACA,eAAgB,CACd,YAAa,mDACb,KAAM,QACR,EACA,cAAe,CACb,YAAa,kDACb,KAAM,QACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,WAAY,CACV,MAAO,CACL,YAAa,4DACb,KAAM,qBACR,EACA,QAAS,CACP,YACE,uFACF,KAAM,qBACR,EACA,YAAa,CACX,YACE,6GACF,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YAAa,wCACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,qGACF,KAAM,QACR,CACF,EACA,SAAU,CAAC,QAAS,QAAS,OAAO,EACpC,sBAAuB,EACzB,EACA,eAAgB,CACd,YAAa,2BACb,KAAM,SACN,WAAY,CACV,OAAQ,CACN,YAAa,kCACb,KAAM,oBACR,EACA,MAAO,CACL,YAAa,8CACb,KAAM,QACN,MAAO,CAAE,KAAM,kBAAmB,EAClC,YAAa,EACf,CACF,EACA,SAAU,CAAC,SAAU,OAAO,CAC9B,EACA,iBAAkB,CAChB,YAAa,+CACb,KAAM,SACN,MAAO,CAAC,CAAE,KAAM,yBAA0B,EAC1C,sBAAuB,EACzB,EACA,gBAAiB,CACf,YAAa,sDACb,KAAM,SACN,MAAO,CACL,CAAE,KAAM,wBAAyB,EACjC,CACE,WAAY,CACV,QAAS,CACP,YAAa,mCACb,KAAM,4BACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,sBAAuB,EACzB,EACA,mBAAoB,CAClB,YAAa,qDACb,KAAM,SACN,WAAY,CACV,gBAAiB,CACf,YACE,mFACF,KAAM,SACR,EACA,QAAS,CACP,YAAa,iEACb,KAAM,yBACR,EACA,YAAa,CACX,YAAa,sEACb,KAAM,0BACR,CACF,EACA,qBAAsB,EACxB,CACF,CACF,EAEA,OAAO,OAAOA,EAAkB","x_google_ignoreList":[9,10,12]} \ No newline at end of file +{"version":3,"file":"index.cjs","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/mutex.ts","../src/mutex-map.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { Mutex as AsyncMutex } from 'async-mutex';\n\n// Extending Mutex from async-mutex so we can add JSDoc\n\n/**\n * Class that allows calling asynchronous functions multiple times at once while only running one at\n * a time.\n *\n * @example\n *\n * ```typescript\n * const mutex = new Mutex();\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n * ```\n *\n * See [`async-mutex`](https://www.npmjs.com/package/async-mutex) for more information.\n */\nclass Mutex extends AsyncMutex {}\n\nexport default Mutex;\n","import Mutex from './mutex';\n\n/** Map of {@link Mutex}es that automatically (lazily) generates a new {@link Mutex} for any new key */\nclass MutexMap {\n private mutexesByID = new Map();\n\n get(mutexID: string): Mutex {\n let retVal = this.mutexesByID.get(mutexID);\n if (retVal) return retVal;\n\n retVal = new Mutex();\n this.mutexesByID.set(mutexID, retVal);\n return retVal;\n }\n}\n\nexport default MutexMap;\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * Finds the Unicode code point at the given index\n *\n * @param {string} string String to index\n * @param {number} index Position of the character to be returned in range of 0 to -length(string)\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > length(string) || index < -length(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * Always indexes string as a sequence of Unicode code points\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, empty string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > length(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to index\n * @param {number} index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {number | undefined} Non-negative integer representing the code point value of the\n * character at the given index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > length(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * Determines whether a string ends with the characters of this string. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Characters to search for at the end of the string\n * @param {number} [endPosition=length(string)] End position where searchString is expected to be\n * found. Default is `length(string)`\n * @returns {boolean} True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = length(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + length(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * Performs a case-sensitive search to determine if searchString is found in string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString String to search for\n * @param {string} [position=0] Position within the string to start searching for searchString.\n * Default is `0`\n * @returns {boolean} True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * Returns the index of the first occurrence of a given string. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The string to search for\n * @param {number} [position=0] Start of searching. Default is `0`\n * @returns {number} Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * Searches this string and returns the index of the last occurrence of the specified substring.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Substring to search for\n * @param {number} [position=+Infinity] The method returns the index of the last occurrence of the\n * specified substring at a position less than or equal to position. . Default is `+Infinity`\n * @returns {number} Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(\n string: string,\n searchString: string,\n position: number = +Infinity,\n): number {\n let validatedPosition = position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= length(string)) {\n validatedPosition = length(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, length(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * Returns the length of a string. This function handles Unicode code points instead of UTF-16\n * character codes.\n *\n * @param {string} string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function length(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * Returns the Unicode Normalization Form of this string.\n *\n * @param {string} string The starting string\n * @param {'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'} [form='NFC'] Form specifying the Unicode\n * Normalization Form. Default is `'NFC'`\n * @returns {string} A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within targetLength, it will be truncated. Default is `\" \"`\n * @returns {string} String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\nfunction correctSliceIndex(stringLength: number, index: number) {\n if (index > stringLength) return stringLength;\n if (index < -stringLength) return 0;\n if (index < 0) return index + stringLength;\n return index;\n}\n\n/**\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The starting string\n * @param {number} indexStart The index of the first character to include in the returned substring.\n * @param {number} indexEnd The index of the first character to exclude from the returned substring.\n * @returns {string} A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const stringLength: number = length(string);\n if (\n indexStart > stringLength ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(\n indexStart > 0 &&\n indexStart < stringLength &&\n indexEnd < 0 &&\n indexEnd > -stringLength\n )) ||\n indexEnd < -stringLength ||\n (indexStart < 0 && indexStart > -stringLength && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(stringLength, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The string to split\n * @param {string | RegExp} separator The pattern describing where each split should occur\n * @param {number} splitLimit Limit on the number of substrings to be included in the array. Splits\n * the string at each occurrence of specified separator, but stops when limit entries have been\n * placed in the array.\n * @returns {string[] | undefined} An array of strings, split at each point where separator occurs\n * in the starting string. Returns undefined if separator is not found in string.\n */\nexport function split(\n string: string,\n separator: string | RegExp,\n splitLimit?: number,\n): string[] {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !separator.flags.includes('g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return [string];\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = length(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate. This function handles Unicode code points instead of UTF-16 character\n * codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The characters to be searched for at the start of this string.\n * @param {number} [position=0] The start position at which searchString is expected to be found\n * (the index of searchString's first character). Default is `0`\n * @returns {boolean} True if the given characters are found at the beginning of the string,\n * including when searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * Returns a substring by providing start and length. This function handles Unicode code points\n * instead of UTF-16 character codes. This function is not exported because it is considered\n * deprecated, however it is still useful as a local helper function.\n *\n * @param {string} string String to be divided\n * @param {number} [begin=Start of string] Start position. Default is `Start of string`\n * @param {number} [len=String length minus start parameter] Length of result. Default is `String\n * length minus start parameter`. Default is `String length minus start parameter`\n * @returns {string} Substring from starting string\n */\nfunction substr(string: string, begin: number = 0, len: number = length(string) - begin): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * Returns a substring by providing start and end position. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to be divided\n * @param {string} begin Start position\n * @param {number} [end=End of string] End position. Default is `End of string`\n * @returns {string} Substring from starting string\n */\nexport function substring(\n string: string,\n begin?: number | undefined,\n end: number | undefined = length(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * Converts a string to an array of string characters. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param {string} string String to convert to array\n * @returns {string[]} An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","Mutex","AsyncMutex","MutexMap","mutexID","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","stringLength","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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ACE,WAAY,CACV,SAAU,CACR,YAAa,8DACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,WAAY,OAAO,EAC9B,qBAAsB,EACxB,CACF,CACF,CACF,EACA,qBAAsB,EACxB,EACA,SAAU,CACR,YACE,mGACF,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,GAAI,CACF,YAAa,6CACb,KAAM,wBACR,CACF,EACA,SAAU,CAAC,IAAI,CACjB,EACA,CACE,WAAY,CACV,QAAS,CACP,YAAa,mEACb,KAAM,wBACR,EACA,eAAgB,CACd,YAAa,mDACb,KAAM,QACR,EACA,cAAe,CACb,YAAa,kDACb,KAAM,QACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,WAAY,CACV,MAAO,CACL,YAAa,4DACb,KAAM,qBACR,EACA,QAAS,CACP,YACE,uFACF,KAAM,qBACR,EACA,YAAa,CACX,YACE,6GACF,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YAAa,wCACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,qGACF,KAAM,QACR,CACF,EACA,SAAU,CAAC,QAAS,QAAS,OAAO,EACpC,sBAAuB,EACzB,EACA,eAAgB,CACd,YAAa,2BACb,KAAM,SACN,WAAY,CACV,OAAQ,CACN,YAAa,kCACb,KAAM,oBACR,EACA,MAAO,CACL,YAAa,8CACb,KAAM,QACN,MAAO,CAAE,KAAM,kBAAmB,EAClC,YAAa,EACf,CACF,EACA,SAAU,CAAC,SAAU,OAAO,CAC9B,EACA,iBAAkB,CAChB,YAAa,+CACb,KAAM,SACN,MAAO,CAAC,CAAE,KAAM,yBAA0B,EAC1C,sBAAuB,EACzB,EACA,gBAAiB,CACf,YAAa,sDACb,KAAM,SACN,MAAO,CACL,CAAE,KAAM,wBAAyB,EACjC,CACE,WAAY,CACV,QAAS,CACP,YAAa,mCACb,KAAM,4BACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,sBAAuB,EACzB,EACA,mBAAoB,CAClB,YAAa,qDACb,KAAM,SACN,WAAY,CACV,gBAAiB,CACf,YACE,mFACF,KAAM,SACR,EACA,QAAS,CACP,YAAa,iEACb,KAAM,yBACR,EACA,YAAa,CACX,YAAa,sEACb,KAAM,0BACR,CACF,EACA,qBAAsB,EACxB,CACF,CACF,EAEA,OAAO,OAAOA,EAAkB","x_google_ignoreList":[9,10,12]} \ No newline at end of file diff --git a/lib/platform-bible-utils/dist/index.d.ts b/lib/platform-bible-utils/dist/index.d.ts index 0b4052e850..a3c597e697 100644 --- a/lib/platform-bible-utils/dist/index.d.ts +++ b/lib/platform-bible-utils/dist/index.d.ts @@ -535,7 +535,7 @@ export declare function slice(string: string, indexStart: number, indexEnd?: num * @returns {string[] | undefined} An array of strings, split at each point where separator occurs * in the starting string. Returns undefined if separator is not found in string. */ -export declare function split(string: string, separator: string | RegExp, splitLimit?: number): string[] | undefined; +export declare function split(string: string, separator: string | RegExp, splitLimit?: number): string[]; /** * Determines whether the string begins with the characters of a specified string, returning true or * false as appropriate. This function handles Unicode code points instead of UTF-16 character diff --git a/lib/platform-bible-utils/dist/index.js b/lib/platform-bible-utils/dist/index.js index 73c15202ec..ab004fc1fe 100644 --- a/lib/platform-bible-utils/dist/index.js +++ b/lib/platform-bible-utils/dist/index.js @@ -611,14 +611,14 @@ function Ct(t, e, r) { (typeof e == "string" || e instanceof RegExp && !e.flags.includes("g")) && (n = new RegExp(e, "g")); const o = t.match(n); let a = 0; - if (o) { - for (let i = 0; i < (r ? r - 1 : o.length); i++) { - const c = C(t, o[i], a), h = d(o[i]); - if (s.push($(t, a, c)), a = c + h, r !== void 0 && s.length === r) - break; - } - return s.push($(t, a)), s; + if (!o) + return [t]; + for (let i = 0; i < (r ? r - 1 : o.length); i++) { + const c = C(t, o[i], a), h = d(o[i]); + if (s.push($(t, a, c)), a = c + h, r !== void 0 && s.length === r) + break; } + return s.push($(t, a)), s; } function Pt(t, e, r = 0) { return C(t, e, r) === r; diff --git a/lib/platform-bible-utils/dist/index.js.map b/lib/platform-bible-utils/dist/index.js.map index fa7c777f41..1cf5b02c28 100644 --- a/lib/platform-bible-utils/dist/index.js.map +++ b/lib/platform-bible-utils/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/mutex.ts","../src/mutex-map.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { Mutex as AsyncMutex } from 'async-mutex';\n\n// Extending Mutex from async-mutex so we can add JSDoc\n\n/**\n * Class that allows calling asynchronous functions multiple times at once while only running one at\n * a time.\n *\n * @example\n *\n * ```typescript\n * const mutex = new Mutex();\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n * ```\n *\n * See [`async-mutex`](https://www.npmjs.com/package/async-mutex) for more information.\n */\nclass Mutex extends AsyncMutex {}\n\nexport default Mutex;\n","import Mutex from './mutex';\n\n/** Map of {@link Mutex}es that automatically (lazily) generates a new {@link Mutex} for any new key */\nclass MutexMap {\n private mutexesByID = new Map();\n\n get(mutexID: string): Mutex {\n let retVal = this.mutexesByID.get(mutexID);\n if (retVal) return retVal;\n\n retVal = new Mutex();\n this.mutexesByID.set(mutexID, retVal);\n return retVal;\n }\n}\n\nexport default MutexMap;\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * Finds the Unicode code point at the given index\n *\n * @param {string} string String to index\n * @param {number} index Position of the character to be returned in range of 0 to -length(string)\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > length(string) || index < -length(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * Always indexes string as a sequence of Unicode code points\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, empty string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > length(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to index\n * @param {number} index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {number | undefined} Non-negative integer representing the code point value of the\n * character at the given index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > length(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * Determines whether a string ends with the characters of this string. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Characters to search for at the end of the string\n * @param {number} [endPosition=length(string)] End position where searchString is expected to be\n * found. Default is `length(string)`\n * @returns {boolean} True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = length(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + length(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * Performs a case-sensitive search to determine if searchString is found in string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString String to search for\n * @param {string} [position=0] Position within the string to start searching for searchString.\n * Default is `0`\n * @returns {boolean} True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * Returns the index of the first occurrence of a given string. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The string to search for\n * @param {number} [position=0] Start of searching. Default is `0`\n * @returns {number} Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * Searches this string and returns the index of the last occurrence of the specified substring.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Substring to search for\n * @param {number} [position=+Infinity] The method returns the index of the last occurrence of the\n * specified substring at a position less than or equal to position. . Default is `+Infinity`\n * @returns {number} Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(\n string: string,\n searchString: string,\n position: number = +Infinity,\n): number {\n let validatedPosition = position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= length(string)) {\n validatedPosition = length(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, length(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * Returns the length of a string. This function handles Unicode code points instead of UTF-16\n * character codes.\n *\n * @param {string} string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function length(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * Returns the Unicode Normalization Form of this string.\n *\n * @param {string} string The starting string\n * @param {'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'} [form='NFC'] Form specifying the Unicode\n * Normalization Form. Default is `'NFC'`\n * @returns {string} A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within targetLength, it will be truncated. Default is `\" \"`\n * @returns {string} String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\nfunction correctSliceIndex(stringLength: number, index: number) {\n if (index > stringLength) return stringLength;\n if (index < -stringLength) return 0;\n if (index < 0) return index + stringLength;\n return index;\n}\n\n/**\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The starting string\n * @param {number} indexStart The index of the first character to include in the returned substring.\n * @param {number} indexEnd The index of the first character to exclude from the returned substring.\n * @returns {string} A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const stringLength: number = length(string);\n if (\n indexStart > stringLength ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(\n indexStart > 0 &&\n indexStart < stringLength &&\n indexEnd < 0 &&\n indexEnd > -stringLength\n )) ||\n indexEnd < -stringLength ||\n (indexStart < 0 && indexStart > -stringLength && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(stringLength, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The string to split\n * @param {string | RegExp} separator The pattern describing where each split should occur\n * @param {number} splitLimit Limit on the number of substrings to be included in the array. Splits\n * the string at each occurrence of specified separator, but stops when limit entries have been\n * placed in the array.\n * @returns {string[] | undefined} An array of strings, split at each point where separator occurs\n * in the starting string. Returns undefined if separator is not found in string.\n */\nexport function split(\n string: string,\n separator: string | RegExp,\n splitLimit?: number,\n): string[] | undefined {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !separator.flags.includes('g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return undefined;\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = length(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate. This function handles Unicode code points instead of UTF-16 character\n * codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The characters to be searched for at the start of this string.\n * @param {number} [position=0] The start position at which searchString is expected to be found\n * (the index of searchString's first character). Default is `0`\n * @returns {boolean} True if the given characters are found at the beginning of the string,\n * including when searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * Returns a substring by providing start and length. This function handles Unicode code points\n * instead of UTF-16 character codes. This function is not exported because it is considered\n * deprecated, however it is still useful as a local helper function.\n *\n * @param {string} string String to be divided\n * @param {number} [begin=Start of string] Start position. Default is `Start of string`\n * @param {number} [len=String length minus start parameter] Length of result. Default is `String\n * length minus start parameter`. Default is `String length minus start parameter`\n * @returns {string} Substring from starting string\n */\nfunction substr(string: string, begin: number = 0, len: number = length(string) - begin): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * Returns a substring by providing start and end position. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to be divided\n * @param {string} begin Start position\n * @param {number} [end=End of string] End position. Default is `End of string`\n * @returns {string} Substring from starting string\n */\nexport function substring(\n string: string,\n begin?: number | undefined,\n end: number | undefined = length(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * Converts a string to an array of string characters. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param {string} string String to convert to array\n * @returns {string[]} An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","Mutex","AsyncMutex","MutexMap","mutexID","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","stringLength","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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","x_google_ignoreList":[9,10,12]} \ No newline at end of file +{"version":3,"file":"index.js","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/mutex.ts","../src/mutex-map.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { Mutex as AsyncMutex } from 'async-mutex';\n\n// Extending Mutex from async-mutex so we can add JSDoc\n\n/**\n * Class that allows calling asynchronous functions multiple times at once while only running one at\n * a time.\n *\n * @example\n *\n * ```typescript\n * const mutex = new Mutex();\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n * ```\n *\n * See [`async-mutex`](https://www.npmjs.com/package/async-mutex) for more information.\n */\nclass Mutex extends AsyncMutex {}\n\nexport default Mutex;\n","import Mutex from './mutex';\n\n/** Map of {@link Mutex}es that automatically (lazily) generates a new {@link Mutex} for any new key */\nclass MutexMap {\n private mutexesByID = new Map();\n\n get(mutexID: string): Mutex {\n let retVal = this.mutexesByID.get(mutexID);\n if (retVal) return retVal;\n\n retVal = new Mutex();\n this.mutexesByID.set(mutexID, retVal);\n return retVal;\n }\n}\n\nexport default MutexMap;\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * Finds the Unicode code point at the given index\n *\n * @param {string} string String to index\n * @param {number} index Position of the character to be returned in range of 0 to -length(string)\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > length(string) || index < -length(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * Always indexes string as a sequence of Unicode code points\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, empty string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > length(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to index\n * @param {number} index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {number | undefined} Non-negative integer representing the code point value of the\n * character at the given index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > length(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * Determines whether a string ends with the characters of this string. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Characters to search for at the end of the string\n * @param {number} [endPosition=length(string)] End position where searchString is expected to be\n * found. Default is `length(string)`\n * @returns {boolean} True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = length(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + length(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * Performs a case-sensitive search to determine if searchString is found in string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString String to search for\n * @param {string} [position=0] Position within the string to start searching for searchString.\n * Default is `0`\n * @returns {boolean} True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * Returns the index of the first occurrence of a given string. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The string to search for\n * @param {number} [position=0] Start of searching. Default is `0`\n * @returns {number} Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * Searches this string and returns the index of the last occurrence of the specified substring.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Substring to search for\n * @param {number} [position=+Infinity] The method returns the index of the last occurrence of the\n * specified substring at a position less than or equal to position. . Default is `+Infinity`\n * @returns {number} Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(\n string: string,\n searchString: string,\n position: number = +Infinity,\n): number {\n let validatedPosition = position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= length(string)) {\n validatedPosition = length(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, length(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * Returns the length of a string. This function handles Unicode code points instead of UTF-16\n * character codes.\n *\n * @param {string} string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function length(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * Returns the Unicode Normalization Form of this string.\n *\n * @param {string} string The starting string\n * @param {'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'} [form='NFC'] Form specifying the Unicode\n * Normalization Form. Default is `'NFC'`\n * @returns {string} A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within targetLength, it will be truncated. Default is `\" \"`\n * @returns {string} String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\nfunction correctSliceIndex(stringLength: number, index: number) {\n if (index > stringLength) return stringLength;\n if (index < -stringLength) return 0;\n if (index < 0) return index + stringLength;\n return index;\n}\n\n/**\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The starting string\n * @param {number} indexStart The index of the first character to include in the returned substring.\n * @param {number} indexEnd The index of the first character to exclude from the returned substring.\n * @returns {string} A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const stringLength: number = length(string);\n if (\n indexStart > stringLength ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(\n indexStart > 0 &&\n indexStart < stringLength &&\n indexEnd < 0 &&\n indexEnd > -stringLength\n )) ||\n indexEnd < -stringLength ||\n (indexStart < 0 && indexStart > -stringLength && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(stringLength, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The string to split\n * @param {string | RegExp} separator The pattern describing where each split should occur\n * @param {number} splitLimit Limit on the number of substrings to be included in the array. Splits\n * the string at each occurrence of specified separator, but stops when limit entries have been\n * placed in the array.\n * @returns {string[] | undefined} An array of strings, split at each point where separator occurs\n * in the starting string. Returns undefined if separator is not found in string.\n */\nexport function split(\n string: string,\n separator: string | RegExp,\n splitLimit?: number,\n): string[] {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !separator.flags.includes('g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return [string];\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = length(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate. This function handles Unicode code points instead of UTF-16 character\n * codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The characters to be searched for at the start of this string.\n * @param {number} [position=0] The start position at which searchString is expected to be found\n * (the index of searchString's first character). Default is `0`\n * @returns {boolean} True if the given characters are found at the beginning of the string,\n * including when searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * Returns a substring by providing start and length. This function handles Unicode code points\n * instead of UTF-16 character codes. This function is not exported because it is considered\n * deprecated, however it is still useful as a local helper function.\n *\n * @param {string} string String to be divided\n * @param {number} [begin=Start of string] Start position. Default is `Start of string`\n * @param {number} [len=String length minus start parameter] Length of result. Default is `String\n * length minus start parameter`. Default is `String length minus start parameter`\n * @returns {string} Substring from starting string\n */\nfunction substr(string: string, begin: number = 0, len: number = length(string) - begin): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * Returns a substring by providing start and end position. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to be divided\n * @param {string} begin Start position\n * @param {number} [end=End of string] End position. Default is `End of string`\n * @returns {string} Substring from starting string\n */\nexport function substring(\n string: string,\n begin?: number | undefined,\n end: number | undefined = length(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * Converts a string to an array of string characters. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param {string} string String to convert to array\n * @returns {string[]} An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","Mutex","AsyncMutex","MutexMap","mutexID","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","stringLength","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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","x_google_ignoreList":[9,10,12]} \ No newline at end of file diff --git a/lib/platform-bible-utils/src/string-util.test.ts b/lib/platform-bible-utils/src/string-util.test.ts index 1eff6d2872..b96c0f1a50 100644 --- a/lib/platform-bible-utils/src/string-util.test.ts +++ b/lib/platform-bible-utils/src/string-util.test.ts @@ -351,6 +351,11 @@ describe('split', () => { const result = split(MEDIUM_SURROGATE_PAIRS_STRING, /🦄/); expect(result).toEqual(['Look𐐷At', 'This𐐷Thing😉Its𐐷Awesome']); }); + + test('split with RegExp separator that matches nothing in the string', () => { + const result = split(MEDIUM_SURROGATE_PAIRS_STRING, /\d/); + expect(result).toEqual([MEDIUM_SURROGATE_PAIRS_STRING]); + }); }); describe('startsWith', () => { diff --git a/lib/platform-bible-utils/src/string-util.ts b/lib/platform-bible-utils/src/string-util.ts index 70d4f63680..bcdcc5b06c 100644 --- a/lib/platform-bible-utils/src/string-util.ts +++ b/lib/platform-bible-utils/src/string-util.ts @@ -251,11 +251,7 @@ export function slice(string: string, indexStart: number, indexEnd?: number): st * @returns {string[] | undefined} An array of strings, split at each point where separator occurs * in the starting string. Returns undefined if separator is not found in string. */ -export function split( - string: string, - separator: string | RegExp, - splitLimit?: number, -): string[] | undefined { +export function split(string: string, separator: string | RegExp, splitLimit?: number): string[] { const result: string[] = []; if (splitLimit !== undefined && splitLimit <= 0) { @@ -276,7 +272,7 @@ export function split( let currentIndex = 0; - if (!matches) return undefined; + if (!matches) return [string]; for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) { const matchIndex = indexOf(string, matches[index], currentIndex); diff --git a/src/main/services/extension-host.service.ts b/src/main/services/extension-host.service.ts index 3b099d95ec..d12509eb75 100644 --- a/src/main/services/extension-host.service.ts +++ b/src/main/services/extension-host.service.ts @@ -6,7 +6,7 @@ import { commandLineArgumentsAliases, } from '@node/utils/command-line.util'; import logger, { formatLog, WARN_TAG } from '@shared/services/logger.service'; -import { waitForDuration } from 'platform-bible-utils'; +import { split, waitForDuration } from 'platform-bible-utils'; import { ChildProcess, ChildProcessByStdio, fork, spawn } from 'child_process'; import { app } from 'electron'; import path from 'path'; @@ -26,7 +26,7 @@ const closePromise: Promise = new Promise((resolve) => { function logProcessError(message: unknown) { let msg = message?.toString() || ''; if (msg.includes(WARN_TAG)) { - msg = msg.split(WARN_TAG).join(''); // TODO: Can't use our new split here for some reason + msg = split(msg, WARN_TAG).join(''); logger.warn(formatLog(msg, EXTENSION_HOST_NAME, 'warning')); } else logger.error(formatLog(msg, EXTENSION_HOST_NAME, 'error')); } diff --git a/src/node/utils/util.ts b/src/node/utils/util.ts index 6f4438ebbc..e89f9dde61 100644 --- a/src/node/utils/util.ts +++ b/src/node/utils/util.ts @@ -4,6 +4,7 @@ import path from 'path'; import os from 'os'; import { Uri } from '@shared/data/file-system.model'; import memoizeOne from 'memoize-one'; +import { split } from 'platform-bible-utils'; // FOR SCHEME DOCUMENTATION, SEE Uri JSDOC const APP_SCHEME = 'app'; @@ -62,7 +63,7 @@ function getPathInfoFromUri(uri: Uri): { scheme: string; uriPath: string } { // Add app scheme to the uri if it doesn't have one const fullUri = uri.includes(PROTOCOL_PART) ? uri : `${APP_SCHEME}${PROTOCOL_PART}${uri}`; - const [scheme, uriPath] = fullUri.split(PROTOCOL_PART); // TODO: Our new split doesn't support this return + const [scheme, uriPath] = split(fullUri, PROTOCOL_PART); return { scheme, uriPath, diff --git a/src/renderer/services/web-view.service-host.ts b/src/renderer/services/web-view.service-host.ts index d2cabf8b87..b7e95f5e2a 100644 --- a/src/renderer/services/web-view.service-host.ts +++ b/src/renderer/services/web-view.service-host.ts @@ -15,6 +15,7 @@ import { indexOf, substring, startsWith, + split, } from 'platform-bible-utils'; import { newNonce } from '@shared/utils/util'; import { createNetworkEventEmitter } from '@shared/services/network.service'; @@ -310,7 +311,7 @@ function removeNodeIfForbidden(node: Node) { removeElement(`iframe with a non-string sandbox value ${sandbox.value}`); return; } - const sandboxValues = sandbox.value.split(' '); + const sandboxValues = split(sandbox.value, ' '); const src = currentElement.attributes.getNamedItem('src'); // If the iframe has `src`, only allow `src` sandbox values because browsers that do not // support `srcdoc` fall back to `src` so we should be more strict diff --git a/src/shared/services/logger.service.ts b/src/shared/services/logger.service.ts index 7977bc0354..dbf13c158a 100644 --- a/src/shared/services/logger.service.ts +++ b/src/shared/services/logger.service.ts @@ -1,6 +1,7 @@ import chalk from 'chalk'; import log, { LogLevel } from 'electron-log'; import { getProcessType, isClient, isExtensionHost, isRenderer } from '@shared/utils/internal-util'; +import { split } from 'platform-bible-utils'; export const WARN_TAG = ''; @@ -66,7 +67,7 @@ function identifyCaller(): string | undefined { const { stack } = new Error(); if (!stack) return undefined; let details: parsedErrorLine; - const lines = stack.split('\n'); // TODO: Our new split doesn't work here + const lines = split(stack, '\n'); // Start at 3 to skip the "Error" line, this function's stack frame, and this function's caller for (let lineNumber = 3; lineNumber < lines.length; lineNumber += 1) { // Skip over all logging library frames to get to the real call From b7f9495e58996a586c1b4176fb65779441fd8ff4 Mon Sep 17 00:00:00 2001 From: Rolf Heij Date: Tue, 20 Feb 2024 14:04:14 -0500 Subject: [PATCH 19/22] Process review comments --- .../src/web-views/hello-world-2.web-view.tsx | 6 - lib/papi-dts/edit-papi-d-ts.ts | 8 +- lib/platform-bible-utils/dist/index.cjs | 2 +- lib/platform-bible-utils/dist/index.cjs.map | 2 +- lib/platform-bible-utils/dist/index.d.ts | 114 ++++++------ lib/platform-bible-utils/dist/index.js | 42 ++--- lib/platform-bible-utils/dist/index.js.map | 2 +- .../src/string-util.test.ts | 7 +- lib/platform-bible-utils/src/string-util.ts | 165 +++++++++--------- 9 files changed, 171 insertions(+), 177 deletions(-) diff --git a/extensions/src/hello-world/src/web-views/hello-world-2.web-view.tsx b/extensions/src/hello-world/src/web-views/hello-world-2.web-view.tsx index 668c5d9111..b9a3fafd88 100644 --- a/extensions/src/hello-world/src/web-views/hello-world-2.web-view.tsx +++ b/extensions/src/hello-world/src/web-views/hello-world-2.web-view.tsx @@ -1,6 +1,5 @@ import papi from '@papi/frontend'; import { useEvent, Button } from 'platform-bible-react'; -import { indexOf } from 'platform-bible-utils'; import { useCallback, useState } from 'react'; import type { HelloWorldEvent } from 'hello-world'; import { WebViewProps } from '@papi/core'; @@ -23,13 +22,8 @@ globalThis.webViewComponent = function HelloWorld2({ useWebViewState }: WebViewP useCallback(({ times }: HelloWorldEvent) => setClicks(times), []), ); - const someIndex = indexOf('SomeStringWithABunchOfWords', 'i', 15); - return ( <> -
- Index: {someIndex} -
Hello World React 2
diff --git a/lib/papi-dts/edit-papi-d-ts.ts b/lib/papi-dts/edit-papi-d-ts.ts index 6a6bce68b4..1dd544071e 100644 --- a/lib/papi-dts/edit-papi-d-ts.ts +++ b/lib/papi-dts/edit-papi-d-ts.ts @@ -139,13 +139,13 @@ Record = tsconfig; // Replace all dynamic imports for @ path aliases with the path alias without @ if (paths) { Object.keys(paths).forEach((path) => { - if (!path.startsWith('@')) return; // TODO: Change startsWith? + if (!path.startsWith('@')) return; - const asteriskIndex = path.indexOf('*'); // TODO: Change indexOf? + const asteriskIndex = path.indexOf('*'); // Get the path alias without the * at the end but with the @ - const pathAlias = path.substring(0, asteriskIndex); // TODO: Change substring? + const pathAlias = path.substring(0, asteriskIndex); // Get the path alias without the @ at the start - const pathAliasNoAt = pathAlias.substring(1); // TODO: Change substring? + const pathAliasNoAt = pathAlias.substring(1); // Regex-escaped path alias without @ to be used in a regex string const pathAliasNoAtRegex = escapeStringRegexp(pathAliasNoAt); diff --git a/lib/platform-bible-utils/dist/index.cjs b/lib/platform-bible-utils/dist/index.cjs index bea7e40be1..4d9f0e5ce6 100644 --- a/lib/platform-bible-utils/dist/index.cjs +++ b/lib/platform-bible-utils/dist/index.cjs @@ -1,2 +1,2 @@ -"use strict";var me=Object.defineProperty;var de=(t,e,r)=>e in t?me(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var p=(t,e,r)=>(de(t,typeof e!="symbol"?e+"":e,r),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const be=require("async-mutex");class ge{constructor(e,r=1e4){p(this,"variableName");p(this,"promiseToValue");p(this,"resolver");p(this,"rejecter");this.variableName=e,this.promiseToValue=new Promise((s,n)=>{this.resolver=s,this.rejecter=n}),r>0&&setTimeout(()=>{this.rejecter&&(this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`),this.complete())},r),Object.seal(this)}get promise(){return this.promiseToValue}get hasSettled(){return Object.isFrozen(this)}resolveToValue(e,r=!1){if(this.resolver)console.debug(`${this.variableName} is being resolved now`),this.resolver(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent resolution of ${this.variableName}`)}}rejectWithReason(e,r=!1){if(this.rejecter)console.debug(`${this.variableName} is being rejected now`),this.rejecter(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent rejection of ${this.variableName}`)}}complete(){this.resolver=void 0,this.rejecter=void 0,Object.freeze(this)}}function Ne(){return"00-0-4-1-000".replace(/[^-]/g,t=>((Math.random()+~~t)*65536>>t).toString(16).padStart(4,"0"))}function F(t){return typeof t=="string"||t instanceof String}function E(t){return JSON.parse(JSON.stringify(t))}function ve(t,e=300){if(F(t))throw new Error("Tried to debounce a string! Could be XSS");let r;return(...s)=>{clearTimeout(r),r=setTimeout(()=>t(...s),e)}}function ye(t,e,r){const s=new Map;return t.forEach(n=>{const o=e(n),a=s.get(o),i=r?r(n,o):n;a?a.push(i):s.set(o,[i])}),s}function we(t){return typeof t=="object"&&t!==null&&"message"in t&&typeof t.message=="string"}function Ee(t){if(we(t))return t;try{return new Error(JSON.stringify(t))}catch{return new Error(String(t))}}function Oe(t){return Ee(t).message}function H(t){return new Promise(e=>setTimeout(e,t))}function $e(t,e){const r=H(e).then(()=>{});return Promise.any([r,t()])}function Ae(t,e="obj"){const r=new Set;Object.getOwnPropertyNames(t).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e} due to error: ${o}`)}});let s=Object.getPrototypeOf(t);for(;s&&Object.getPrototypeOf(s);)Object.getOwnPropertyNames(s).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e}'s prototype due to error: ${o}`)}}),s=Object.getPrototypeOf(s);return r}function Se(t,e={}){return new Proxy(e,{get(r,s){return s in r?r[s]:async(...n)=>(await t())[s](...n)}})}class Me{constructor(e,r){p(this,"baseDocument");p(this,"contributions",new Map);p(this,"latestOutput");p(this,"options");this.baseDocument=e,this.options=r,this.updateBaseDocument(e)}updateBaseDocument(e){return this.validateStartingDocument(e),this.baseDocument=this.options.copyDocuments?E(e):e,this.rebuild()}addOrUpdateContribution(e,r){this.validateContribution(e,r);const s=this.contributions.get(e),n=this.options.copyDocuments&&r?E(r):r;this.contributions.set(e,n);try{return this.rebuild()}catch(o){throw s?this.contributions.set(e,s):this.contributions.delete(e),new Error(`Error when setting the document named ${e}: ${o}`)}}deleteContribution(e){const r=this.contributions.get(e);if(!r)throw new Error("{documentKey} does not exist");this.contributions.delete(e);try{return this.rebuild()}catch(s){throw this.contributions.set(e,r),new Error(`Error when deleting the document named ${e}: ${s}`)}}rebuild(){if(this.contributions.size===0){let r=E(this.baseDocument);return r=this.transformFinalOutput(r),this.validateOutput(r),this.latestOutput=r,this.latestOutput}let e=this.baseDocument;return this.contributions.forEach(r=>{e=k(e,r,this.options.ignoreDuplicateProperties),this.validateOutput(e)}),e=this.transformFinalOutput(e),this.validateOutput(e),this.latestOutput=e,this.latestOutput}}function qe(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||Array.isArray(r))&&(e=!1)}),e}function je(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||!Array.isArray(r))&&(e=!1)}),e}function k(t,e,r){const s=E(t);return e&&Object.keys(e).forEach(n=>{if(Object.hasOwn(t,n)){if(qe(t[n],e[n]))s[n]=k(t[n],e[n],r);else if(je(t[n],e[n]))s[n]=s[n].concat(e[n]);else if(!r)throw new Error(`Cannot merge objects: key "${n}" already exists in the target object`)}else s[n]=e[n]}),s}class Ce{constructor(e="Anonymous"){p(this,"unsubscribers",new Set);this.name=e}add(...e){e.forEach(r=>{"dispose"in r?this.unsubscribers.add(r.dispose):this.unsubscribers.add(r)})}async runAllUnsubscribers(){const e=[...this.unsubscribers].map(s=>s()),r=await Promise.all(e);return this.unsubscribers.clear(),r.every((s,n)=>(s||console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${n} failed!`),s))}}class Pe{constructor(){p(this,"subscribe",this.event);p(this,"subscriptions");p(this,"lazyEvent");p(this,"isDisposed",!1);p(this,"dispose",()=>this.disposeFn());p(this,"emit",e=>{this.emitFn(e)})}get event(){return this.assertNotDisposed(),this.lazyEvent||(this.lazyEvent=e=>{if(!e||typeof e!="function")throw new Error("Event handler callback must be a function!");return this.subscriptions||(this.subscriptions=[]),this.subscriptions.push(e),()=>{if(!this.subscriptions)return!1;const r=this.subscriptions.indexOf(e);return r<0?!1:(this.subscriptions.splice(r,1),!0)}}),this.lazyEvent}emitFn(e){var r;this.assertNotDisposed(),(r=this.subscriptions)==null||r.forEach(s=>s(e))}assertNotDisposed(){if(this.isDisposed)throw new Error("Emitter is disposed")}disposeFn(){return this.assertNotDisposed(),this.isDisposed=!0,this.subscriptions=void 0,this.lazyEvent=void 0,Promise.resolve(!0)}}class W extends be.Mutex{}class Te{constructor(){p(this,"mutexesByID",new Map)}get(e){let r=this.mutexesByID.get(e);return r||(r=new W,this.mutexesByID.set(e,r),r)}}const K=[{shortName:"ERR",fullNames:["ERROR"],chapters:-1},{shortName:"GEN",fullNames:["Genesis"],chapters:50},{shortName:"EXO",fullNames:["Exodus"],chapters:40},{shortName:"LEV",fullNames:["Leviticus"],chapters:27},{shortName:"NUM",fullNames:["Numbers"],chapters:36},{shortName:"DEU",fullNames:["Deuteronomy"],chapters:34},{shortName:"JOS",fullNames:["Joshua"],chapters:24},{shortName:"JDG",fullNames:["Judges"],chapters:21},{shortName:"RUT",fullNames:["Ruth"],chapters:4},{shortName:"1SA",fullNames:["1 Samuel"],chapters:31},{shortName:"2SA",fullNames:["2 Samuel"],chapters:24},{shortName:"1KI",fullNames:["1 Kings"],chapters:22},{shortName:"2KI",fullNames:["2 Kings"],chapters:25},{shortName:"1CH",fullNames:["1 Chronicles"],chapters:29},{shortName:"2CH",fullNames:["2 Chronicles"],chapters:36},{shortName:"EZR",fullNames:["Ezra"],chapters:10},{shortName:"NEH",fullNames:["Nehemiah"],chapters:13},{shortName:"EST",fullNames:["Esther"],chapters:10},{shortName:"JOB",fullNames:["Job"],chapters:42},{shortName:"PSA",fullNames:["Psalm","Psalms"],chapters:150},{shortName:"PRO",fullNames:["Proverbs"],chapters:31},{shortName:"ECC",fullNames:["Ecclesiastes"],chapters:12},{shortName:"SNG",fullNames:["Song of Solomon","Song of Songs"],chapters:8},{shortName:"ISA",fullNames:["Isaiah"],chapters:66},{shortName:"JER",fullNames:["Jeremiah"],chapters:52},{shortName:"LAM",fullNames:["Lamentations"],chapters:5},{shortName:"EZK",fullNames:["Ezekiel"],chapters:48},{shortName:"DAN",fullNames:["Daniel"],chapters:12},{shortName:"HOS",fullNames:["Hosea"],chapters:14},{shortName:"JOL",fullNames:["Joel"],chapters:3},{shortName:"AMO",fullNames:["Amos"],chapters:9},{shortName:"OBA",fullNames:["Obadiah"],chapters:1},{shortName:"JON",fullNames:["Jonah"],chapters:4},{shortName:"MIC",fullNames:["Micah"],chapters:7},{shortName:"NAM",fullNames:["Nahum"],chapters:3},{shortName:"HAB",fullNames:["Habakkuk"],chapters:3},{shortName:"ZEP",fullNames:["Zephaniah"],chapters:3},{shortName:"HAG",fullNames:["Haggai"],chapters:2},{shortName:"ZEC",fullNames:["Zechariah"],chapters:14},{shortName:"MAL",fullNames:["Malachi"],chapters:4},{shortName:"MAT",fullNames:["Matthew"],chapters:28},{shortName:"MRK",fullNames:["Mark"],chapters:16},{shortName:"LUK",fullNames:["Luke"],chapters:24},{shortName:"JHN",fullNames:["John"],chapters:21},{shortName:"ACT",fullNames:["Acts"],chapters:28},{shortName:"ROM",fullNames:["Romans"],chapters:16},{shortName:"1CO",fullNames:["1 Corinthians"],chapters:16},{shortName:"2CO",fullNames:["2 Corinthians"],chapters:13},{shortName:"GAL",fullNames:["Galatians"],chapters:6},{shortName:"EPH",fullNames:["Ephesians"],chapters:6},{shortName:"PHP",fullNames:["Philippians"],chapters:4},{shortName:"COL",fullNames:["Colossians"],chapters:4},{shortName:"1TH",fullNames:["1 Thessalonians"],chapters:5},{shortName:"2TH",fullNames:["2 Thessalonians"],chapters:3},{shortName:"1TI",fullNames:["1 Timothy"],chapters:6},{shortName:"2TI",fullNames:["2 Timothy"],chapters:4},{shortName:"TIT",fullNames:["Titus"],chapters:3},{shortName:"PHM",fullNames:["Philemon"],chapters:1},{shortName:"HEB",fullNames:["Hebrews"],chapters:13},{shortName:"JAS",fullNames:["James"],chapters:5},{shortName:"1PE",fullNames:["1 Peter"],chapters:5},{shortName:"2PE",fullNames:["2 Peter"],chapters:3},{shortName:"1JN",fullNames:["1 John"],chapters:5},{shortName:"2JN",fullNames:["2 John"],chapters:1},{shortName:"3JN",fullNames:["3 John"],chapters:1},{shortName:"JUD",fullNames:["Jude"],chapters:1},{shortName:"REV",fullNames:["Revelation"],chapters:22}],L=1,Z=K.length-1,X=1,Q=1,Y=t=>{var e;return((e=K[t])==null?void 0:e.chapters)??-1},Re=(t,e)=>({bookNum:Math.max(L,Math.min(t.bookNum+e,Z)),chapterNum:1,verseNum:1}),De=(t,e)=>({...t,chapterNum:Math.min(Math.max(X,t.chapterNum+e),Y(t.bookNum)),verseNum:1}),Ie=(t,e)=>({...t,verseNum:Math.max(Q,t.verseNum+e)}),xe=t=>(...e)=>t.map(s=>s(...e)).every(s=>s),_e=t=>async(...e)=>{const r=t.map(async s=>s(...e));return(await Promise.all(r)).every(s=>s)};var D=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},N={},ze=()=>{const t="\\ud800-\\udfff",e="\\u0300-\\u036f",r="\\ufe20-\\ufe2f",s="\\u20d0-\\u20ff",n="\\u1ab0-\\u1aff",o="\\u1dc0-\\u1dff",a=e+r+s+n+o,i="\\ufe0e\\ufe0f",c="\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93",h=`[${t}]`,u=`[${a}]`,l="\\ud83c[\\udffb-\\udfff]",f=`(?:${u}|${l})`,b=`[^${t}]`,d="(?:\\uD83C[\\uDDE6-\\uDDFF]){2}",y="[\\ud800-\\udbff][\\udc00-\\udfff]",q="\\u200d",le="(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)",ce=`[${c}]`,T=`${f}?`,R=`[${i}]?`,fe=`(?:${q}(?:${[b,d,y].join("|")})${R+T})*`,he=R+T+fe,pe=`(?:${[`${b}${u}?`,u,d,y,h,ce].join("|")})`;return new RegExp(`${le}|${l}(?=${l})|${pe+he}`,"g")},Be=D&&D.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(N,"__esModule",{value:!0});var A=Be(ze);function j(t){if(typeof t!="string")throw new Error("A string is expected as input");return t.match(A.default())||[]}var Je=N.toArray=j;function P(t){if(typeof t!="string")throw new Error("Input must be a string");var e=t.match(A.default());return e===null?0:e.length}var Ge=N.length=P;function ee(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");(typeof e!="number"||e<0)&&(e=0),typeof r=="number"&&r<0&&(r=0);var s=t.match(A.default());return s?s.slice(e,r).join(""):""}var Ue=N.substring=ee;function Ve(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");var s=P(t);if(typeof e!="number"&&(e=parseInt(e,10)),e>=s)return"";e<0&&(e+=s);var n;typeof r>"u"?n=s:(typeof r!="number"&&(r=parseInt(r,10)),n=r>=0?r+e:e);var o=t.match(A.default());return o?o.slice(e,n).join(""):""}var Fe=N.substr=Ve;function He(t,e,r,s){if(e===void 0&&(e=16),r===void 0&&(r="#"),s===void 0&&(s="right"),typeof t!="string"||typeof e!="number")throw new Error("Invalid arguments specified");if(["left","right"].indexOf(s)===-1)throw new Error("Pad position should be either left or right");typeof r!="string"&&(r=String(r));var n=P(t);if(n>e)return ee(t,0,e);if(n=s.length)return e===""?s.length:-1;if(e==="")return r;var n=j(e),o=!1,a;for(a=r;am(t)||e<-m(t)))return M(t,e,1)}function Le(t,e){return e<0||e>m(t)-1?"":M(t,e,1)}function Ze(t,e){if(!(e<0||e>m(t)-1))return M(t,e,1).codePointAt(0)}function Xe(t,e,r=m(t)){const s=se(t,e);return!(s===-1||s+m(e)!==r)}function re(t,e,r=0){const s=O(t,r);return S(s,e)!==-1}function S(t,e,r=0){return We(t,e,r)}function se(t,e,r=1/0){let s=r;s<0?s=0:s>=m(t)&&(s=m(t)-1);for(let n=s;n>=0;n--)if(M(t,n,m(e))===e)return n;return-1}function m(t){return Ge(t)}function Qe(t,e){const r=e.toUpperCase();return r==="NONE"?t:t.normalize(r)}function Ye(t,e,r=" "){return e<=m(t)?t:te(t,e,r,"right")}function et(t,e,r=" "){return e<=m(t)?t:te(t,e,r,"left")}function I(t,e){return e>t?t:e<-t?0:e<0?e+t:e}function tt(t,e,r){const s=m(t);if(e>s||r&&(e>r&&!(e>0&&e-s)||r<-s||e<0&&e>-s&&r>0))return"";const n=I(s,e),o=r?I(s,r):void 0;return O(t,n,o)}function rt(t,e,r){const s=[];if(r!==void 0&&r<=0)return[t];if(e==="")return ne(t).slice(0,r);let n=e;(typeof e=="string"||e instanceof RegExp&&!re(e.flags,"g"))&&(n=new RegExp(e,"g"));const o=t.match(n);let a=0;if(!o)return[t];for(let i=0;i<(r?r-1:o.length);i++){const c=S(t,o[i],a),h=m(o[i]);if(s.push(O(t,a,c)),a=c+h,r!==void 0&&s.length===r)break}return s.push(O(t,a)),s}function st(t,e,r=0){return S(t,e,r)===r}function M(t,e=0,r=m(t)-e){return Fe(t,e,r)}function O(t,e,r=m(t)){return Ue(t,e,r)}function ne(t){return Je(t)}var nt=Object.getOwnPropertyNames,ot=Object.getOwnPropertySymbols,at=Object.prototype.hasOwnProperty;function x(t,e){return function(s,n,o){return t(s,n,o)&&e(s,n,o)}}function $(t){return function(r,s,n){if(!r||!s||typeof r!="object"||typeof s!="object")return t(r,s,n);var o=n.cache,a=o.get(r),i=o.get(s);if(a&&i)return a===s&&i===r;o.set(r,s),o.set(s,r);var c=t(r,s,n);return o.delete(r),o.delete(s),c}}function _(t){return nt(t).concat(ot(t))}var oe=Object.hasOwn||function(t,e){return at.call(t,e)};function v(t,e){return t||e?t===e:t===e||t!==t&&e!==e}var ae="_owner",z=Object.getOwnPropertyDescriptor,B=Object.keys;function it(t,e,r){var s=t.length;if(e.length!==s)return!1;for(;s-- >0;)if(!r.equals(t[s],e[s],s,s,t,e,r))return!1;return!0}function ut(t,e){return v(t.getTime(),e.getTime())}function J(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.entries(),o=0,a,i;(a=n.next())&&!a.done;){for(var c=e.entries(),h=!1,u=0;(i=c.next())&&!i.done;){var l=a.value,f=l[0],b=l[1],d=i.value,y=d[0],q=d[1];!h&&!s[u]&&(h=r.equals(f,y,o,u,t,e,r)&&r.equals(b,q,f,y,t,e,r))&&(s[u]=!0),u++}if(!h)return!1;o++}return!0}function lt(t,e,r){var s=B(t),n=s.length;if(B(e).length!==n)return!1;for(var o;n-- >0;)if(o=s[n],o===ae&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!oe(e,o)||!r.equals(t[o],e[o],o,o,t,e,r))return!1;return!0}function w(t,e,r){var s=_(t),n=s.length;if(_(e).length!==n)return!1;for(var o,a,i;n-- >0;)if(o=s[n],o===ae&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!oe(e,o)||!r.equals(t[o],e[o],o,o,t,e,r)||(a=z(t,o),i=z(e,o),(a||i)&&(!a||!i||a.configurable!==i.configurable||a.enumerable!==i.enumerable||a.writable!==i.writable)))return!1;return!0}function ct(t,e){return v(t.valueOf(),e.valueOf())}function ft(t,e){return t.source===e.source&&t.flags===e.flags}function G(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.values(),o,a;(o=n.next())&&!o.done;){for(var i=e.values(),c=!1,h=0;(a=i.next())&&!a.done;)!c&&!s[h]&&(c=r.equals(o.value,a.value,o.value,a.value,t,e,r))&&(s[h]=!0),h++;if(!c)return!1}return!0}function ht(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}var pt="[object Arguments]",mt="[object Boolean]",dt="[object Date]",bt="[object Map]",gt="[object Number]",Nt="[object Object]",vt="[object RegExp]",yt="[object Set]",wt="[object String]",Et=Array.isArray,U=typeof ArrayBuffer=="function"&&ArrayBuffer.isView?ArrayBuffer.isView:null,V=Object.assign,Ot=Object.prototype.toString.call.bind(Object.prototype.toString);function $t(t){var e=t.areArraysEqual,r=t.areDatesEqual,s=t.areMapsEqual,n=t.areObjectsEqual,o=t.arePrimitiveWrappersEqual,a=t.areRegExpsEqual,i=t.areSetsEqual,c=t.areTypedArraysEqual;return function(u,l,f){if(u===l)return!0;if(u==null||l==null||typeof u!="object"||typeof l!="object")return u!==u&&l!==l;var b=u.constructor;if(b!==l.constructor)return!1;if(b===Object)return n(u,l,f);if(Et(u))return e(u,l,f);if(U!=null&&U(u))return c(u,l,f);if(b===Date)return r(u,l,f);if(b===RegExp)return a(u,l,f);if(b===Map)return s(u,l,f);if(b===Set)return i(u,l,f);var d=Ot(u);return d===dt?r(u,l,f):d===vt?a(u,l,f):d===bt?s(u,l,f):d===yt?i(u,l,f):d===Nt?typeof u.then!="function"&&typeof l.then!="function"&&n(u,l,f):d===pt?n(u,l,f):d===mt||d===gt||d===wt?o(u,l,f):!1}}function At(t){var e=t.circular,r=t.createCustomConfig,s=t.strict,n={areArraysEqual:s?w:it,areDatesEqual:ut,areMapsEqual:s?x(J,w):J,areObjectsEqual:s?w:lt,arePrimitiveWrappersEqual:ct,areRegExpsEqual:ft,areSetsEqual:s?x(G,w):G,areTypedArraysEqual:s?w:ht};if(r&&(n=V({},n,r(n))),e){var o=$(n.areArraysEqual),a=$(n.areMapsEqual),i=$(n.areObjectsEqual),c=$(n.areSetsEqual);n=V({},n,{areArraysEqual:o,areMapsEqual:a,areObjectsEqual:i,areSetsEqual:c})}return n}function St(t){return function(e,r,s,n,o,a,i){return t(e,r,i)}}function Mt(t){var e=t.circular,r=t.comparator,s=t.createState,n=t.equals,o=t.strict;if(s)return function(c,h){var u=s(),l=u.cache,f=l===void 0?e?new WeakMap:void 0:l,b=u.meta;return r(c,h,{cache:f,equals:n,meta:b,strict:o})};if(e)return function(c,h){return r(c,h,{cache:new WeakMap,equals:n,meta:void 0,strict:o})};var a={cache:void 0,equals:n,meta:void 0,strict:o};return function(c,h){return r(c,h,a)}}var qt=g();g({strict:!0});g({circular:!0});g({circular:!0,strict:!0});g({createInternalComparator:function(){return v}});g({strict:!0,createInternalComparator:function(){return v}});g({circular:!0,createInternalComparator:function(){return v}});g({circular:!0,createInternalComparator:function(){return v},strict:!0});function g(t){t===void 0&&(t={});var e=t.circular,r=e===void 0?!1:e,s=t.createInternalComparator,n=t.createState,o=t.strict,a=o===void 0?!1:o,i=At(t),c=$t(i),h=s?s(c):St(c);return Mt({circular:r,comparator:c,createState:n,equals:h,strict:a})}function jt(t,e){return qt(t,e)}function C(t,e,r){return JSON.stringify(t,(n,o)=>{let a=o;return e&&(a=e(n,a)),a===void 0&&(a=null),a},r)}function ie(t,e){function r(n){return Object.keys(n).forEach(o=>{n[o]===null?n[o]=void 0:typeof n[o]=="object"&&(n[o]=r(n[o]))}),n}const s=JSON.parse(t,e);if(s!==null)return typeof s=="object"?r(s):s}function Ct(t){try{const e=C(t);return e===C(ie(e))}catch{return!1}}const Pt=t=>t.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/"),ue={title:"Platform.Bible menus",type:"object",properties:{mainMenu:{description:"Top level menu for the application",$ref:"#/$defs/multiColumnMenu"},defaultWebViewTopMenu:{description:"Default top menu for web views that don't specify their own",$ref:"#/$defs/multiColumnMenu"},defaultWebViewContextMenu:{description:"Default context menu for web views that don't specify their own",$ref:"#/$defs/singleColumnMenu"},webViewMenus:{description:"Menus that apply per web view in the application",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{$ref:"#/$defs/menusForOneWebView"}},additionalProperties:!1}},required:["mainMenu","defaultWebViewTopMenu","defaultWebViewContextMenu","webViewMenus"],additionalProperties:!1,$defs:{localizeKey:{description:"Identifier for a string that will be localized in a menu based on the user's UI language",type:"string",pattern:"^%[\\w\\-\\.]+%$"},referencedItem:{description:"Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)",type:"string",pattern:"^[\\w\\-]+\\.[\\w\\-]+$"},columnsWithHeaders:{description:"Group of columns that can be combined with other columns to form a multi-column menu",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single column with a header string",type:"object",properties:{label:{description:"Header text for this this column in the UI",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},order:{description:"Relative order of this column compared to other columns (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu groups to this column",type:"boolean"}},required:["label","order"],additionalProperties:!1}},properties:{isExtensible:{description:"Defines whether contributions are allowed to add columns to this multi-column menu",type:"boolean"}}},menuGroups:{description:"Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single group that contains menu items",type:"object",oneOf:[{properties:{column:{description:"Column where this group belongs, not required for single column menus",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["order"],additionalProperties:!1},{properties:{menuItem:{description:"Menu item that anchors the submenu where this group belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["menuItem","order"],additionalProperties:!1}]}},additionalProperties:!1},menuItem:{description:"Single item in a menu that can be clicked on to take an action or can be the parent of a submenu",type:"object",oneOf:[{properties:{id:{description:"ID for this menu item that holds a submenu",$ref:"#/$defs/referencedItem"}},required:["id"]},{properties:{command:{description:"Name of the PAPI command to run when this menu item is selected.",$ref:"#/$defs/referencedItem"},iconPathBefore:{description:"Path to the icon to display before the menu text",type:"string"},iconPathAfter:{description:"Path to the icon to display after the menu text",type:"string"}},required:["command"]}],properties:{label:{description:"Key that represents the text of this menu item to display",$ref:"#/$defs/localizeKey"},tooltip:{description:"Key that represents the text to display if a mouse pointer hovers over the menu item",$ref:"#/$defs/localizeKey"},searchTerms:{description:"Key that represents additional words the platform should reference when users are searching for menu items",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},group:{description:"Group to which this menu item belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this menu item compared to other menu items in the same group (sorted ascending)",type:"number"}},required:["label","group","order"],unevaluatedProperties:!1},groupsAndItems:{description:"Core schema for a column",type:"object",properties:{groups:{description:"Groups that belong in this menu",$ref:"#/$defs/menuGroups"},items:{description:"List of menu items that belong in this menu",type:"array",items:{$ref:"#/$defs/menuItem"},uniqueItems:!0}},required:["groups","items"]},singleColumnMenu:{description:"Menu that contains a column without a header",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"}],unevaluatedProperties:!1},multiColumnMenu:{description:"Menu that can contain multiple columns with headers",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"},{properties:{columns:{description:"Columns that belong in this menu",$ref:"#/$defs/columnsWithHeaders"}},required:["columns"]}],unevaluatedProperties:!1},menusForOneWebView:{description:"Set of menus that are associated with a single tab",type:"object",properties:{includeDefaults:{description:"Indicates whether the platform default menus should be included for this webview",type:"boolean"},topMenu:{description:"Menu that opens when you click on the top left corner of a tab",$ref:"#/$defs/multiColumnMenu"},contextMenu:{description:"Menu that opens when you right click on the main body/area of a tab",$ref:"#/$defs/singleColumnMenu"}},additionalProperties:!1}}};Object.freeze(ue);exports.AsyncVariable=ge;exports.DocumentCombinerEngine=Me;exports.FIRST_SCR_BOOK_NUM=L;exports.FIRST_SCR_CHAPTER_NUM=X;exports.FIRST_SCR_VERSE_NUM=Q;exports.LAST_SCR_BOOK_NUM=Z;exports.Mutex=W;exports.MutexMap=Te;exports.PlatformEventEmitter=Pe;exports.UnsubscriberAsyncList=Ce;exports.aggregateUnsubscriberAsyncs=_e;exports.aggregateUnsubscribers=xe;exports.at=Ke;exports.charAt=Le;exports.codePointAt=Ze;exports.createSyncProxyForAsyncObject=Se;exports.debounce=ve;exports.deepClone=E;exports.deepEqual=jt;exports.deserialize=ie;exports.endsWith=Xe;exports.getAllObjectFunctionNames=Ae;exports.getChaptersForBook=Y;exports.getErrorMessage=Oe;exports.groupBy=ye;exports.htmlEncode=Pt;exports.includes=re;exports.indexOf=S;exports.isSerializable=Ct;exports.isString=F;exports.lastIndexOf=se;exports.length=m;exports.menuDocumentSchema=ue;exports.newGuid=Ne;exports.normalize=Qe;exports.offsetBook=Re;exports.offsetChapter=De;exports.offsetVerse=Ie;exports.padEnd=Ye;exports.padStart=et;exports.serialize=C;exports.slice=tt;exports.split=rt;exports.startsWith=st;exports.substring=O;exports.toArray=ne;exports.wait=H;exports.waitForDuration=$e; +"use strict";var me=Object.defineProperty;var de=(t,e,r)=>e in t?me(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var p=(t,e,r)=>(de(t,typeof e!="symbol"?e+"":e,r),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const be=require("async-mutex");class ge{constructor(e,r=1e4){p(this,"variableName");p(this,"promiseToValue");p(this,"resolver");p(this,"rejecter");this.variableName=e,this.promiseToValue=new Promise((s,n)=>{this.resolver=s,this.rejecter=n}),r>0&&setTimeout(()=>{this.rejecter&&(this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`),this.complete())},r),Object.seal(this)}get promise(){return this.promiseToValue}get hasSettled(){return Object.isFrozen(this)}resolveToValue(e,r=!1){if(this.resolver)console.debug(`${this.variableName} is being resolved now`),this.resolver(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent resolution of ${this.variableName}`)}}rejectWithReason(e,r=!1){if(this.rejecter)console.debug(`${this.variableName} is being rejected now`),this.rejecter(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent rejection of ${this.variableName}`)}}complete(){this.resolver=void 0,this.rejecter=void 0,Object.freeze(this)}}function Ne(){return"00-0-4-1-000".replace(/[^-]/g,t=>((Math.random()+~~t)*65536>>t).toString(16).padStart(4,"0"))}function F(t){return typeof t=="string"||t instanceof String}function E(t){return JSON.parse(JSON.stringify(t))}function ve(t,e=300){if(F(t))throw new Error("Tried to debounce a string! Could be XSS");let r;return(...s)=>{clearTimeout(r),r=setTimeout(()=>t(...s),e)}}function ye(t,e,r){const s=new Map;return t.forEach(n=>{const o=e(n),a=s.get(o),i=r?r(n,o):n;a?a.push(i):s.set(o,[i])}),s}function we(t){return typeof t=="object"&&t!==null&&"message"in t&&typeof t.message=="string"}function Ee(t){if(we(t))return t;try{return new Error(JSON.stringify(t))}catch{return new Error(String(t))}}function Oe(t){return Ee(t).message}function H(t){return new Promise(e=>setTimeout(e,t))}function $e(t,e){const r=H(e).then(()=>{});return Promise.any([r,t()])}function Ae(t,e="obj"){const r=new Set;Object.getOwnPropertyNames(t).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e} due to error: ${o}`)}});let s=Object.getPrototypeOf(t);for(;s&&Object.getPrototypeOf(s);)Object.getOwnPropertyNames(s).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e}'s prototype due to error: ${o}`)}}),s=Object.getPrototypeOf(s);return r}function Se(t,e={}){return new Proxy(e,{get(r,s){return s in r?r[s]:async(...n)=>(await t())[s](...n)}})}class Me{constructor(e,r){p(this,"baseDocument");p(this,"contributions",new Map);p(this,"latestOutput");p(this,"options");this.baseDocument=e,this.options=r,this.updateBaseDocument(e)}updateBaseDocument(e){return this.validateStartingDocument(e),this.baseDocument=this.options.copyDocuments?E(e):e,this.rebuild()}addOrUpdateContribution(e,r){this.validateContribution(e,r);const s=this.contributions.get(e),n=this.options.copyDocuments&&r?E(r):r;this.contributions.set(e,n);try{return this.rebuild()}catch(o){throw s?this.contributions.set(e,s):this.contributions.delete(e),new Error(`Error when setting the document named ${e}: ${o}`)}}deleteContribution(e){const r=this.contributions.get(e);if(!r)throw new Error("{documentKey} does not exist");this.contributions.delete(e);try{return this.rebuild()}catch(s){throw this.contributions.set(e,r),new Error(`Error when deleting the document named ${e}: ${s}`)}}rebuild(){if(this.contributions.size===0){let r=E(this.baseDocument);return r=this.transformFinalOutput(r),this.validateOutput(r),this.latestOutput=r,this.latestOutput}let e=this.baseDocument;return this.contributions.forEach(r=>{e=k(e,r,this.options.ignoreDuplicateProperties),this.validateOutput(e)}),e=this.transformFinalOutput(e),this.validateOutput(e),this.latestOutput=e,this.latestOutput}}function qe(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||Array.isArray(r))&&(e=!1)}),e}function je(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||!Array.isArray(r))&&(e=!1)}),e}function k(t,e,r){const s=E(t);return e&&Object.keys(e).forEach(n=>{if(Object.hasOwn(t,n)){if(qe(t[n],e[n]))s[n]=k(t[n],e[n],r);else if(je(t[n],e[n]))s[n]=s[n].concat(e[n]);else if(!r)throw new Error(`Cannot merge objects: key "${n}" already exists in the target object`)}else s[n]=e[n]}),s}class Ce{constructor(e="Anonymous"){p(this,"unsubscribers",new Set);this.name=e}add(...e){e.forEach(r=>{"dispose"in r?this.unsubscribers.add(r.dispose):this.unsubscribers.add(r)})}async runAllUnsubscribers(){const e=[...this.unsubscribers].map(s=>s()),r=await Promise.all(e);return this.unsubscribers.clear(),r.every((s,n)=>(s||console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${n} failed!`),s))}}class Pe{constructor(){p(this,"subscribe",this.event);p(this,"subscriptions");p(this,"lazyEvent");p(this,"isDisposed",!1);p(this,"dispose",()=>this.disposeFn());p(this,"emit",e=>{this.emitFn(e)})}get event(){return this.assertNotDisposed(),this.lazyEvent||(this.lazyEvent=e=>{if(!e||typeof e!="function")throw new Error("Event handler callback must be a function!");return this.subscriptions||(this.subscriptions=[]),this.subscriptions.push(e),()=>{if(!this.subscriptions)return!1;const r=this.subscriptions.indexOf(e);return r<0?!1:(this.subscriptions.splice(r,1),!0)}}),this.lazyEvent}emitFn(e){var r;this.assertNotDisposed(),(r=this.subscriptions)==null||r.forEach(s=>s(e))}assertNotDisposed(){if(this.isDisposed)throw new Error("Emitter is disposed")}disposeFn(){return this.assertNotDisposed(),this.isDisposed=!0,this.subscriptions=void 0,this.lazyEvent=void 0,Promise.resolve(!0)}}class W extends be.Mutex{}class Te{constructor(){p(this,"mutexesByID",new Map)}get(e){let r=this.mutexesByID.get(e);return r||(r=new W,this.mutexesByID.set(e,r),r)}}const K=[{shortName:"ERR",fullNames:["ERROR"],chapters:-1},{shortName:"GEN",fullNames:["Genesis"],chapters:50},{shortName:"EXO",fullNames:["Exodus"],chapters:40},{shortName:"LEV",fullNames:["Leviticus"],chapters:27},{shortName:"NUM",fullNames:["Numbers"],chapters:36},{shortName:"DEU",fullNames:["Deuteronomy"],chapters:34},{shortName:"JOS",fullNames:["Joshua"],chapters:24},{shortName:"JDG",fullNames:["Judges"],chapters:21},{shortName:"RUT",fullNames:["Ruth"],chapters:4},{shortName:"1SA",fullNames:["1 Samuel"],chapters:31},{shortName:"2SA",fullNames:["2 Samuel"],chapters:24},{shortName:"1KI",fullNames:["1 Kings"],chapters:22},{shortName:"2KI",fullNames:["2 Kings"],chapters:25},{shortName:"1CH",fullNames:["1 Chronicles"],chapters:29},{shortName:"2CH",fullNames:["2 Chronicles"],chapters:36},{shortName:"EZR",fullNames:["Ezra"],chapters:10},{shortName:"NEH",fullNames:["Nehemiah"],chapters:13},{shortName:"EST",fullNames:["Esther"],chapters:10},{shortName:"JOB",fullNames:["Job"],chapters:42},{shortName:"PSA",fullNames:["Psalm","Psalms"],chapters:150},{shortName:"PRO",fullNames:["Proverbs"],chapters:31},{shortName:"ECC",fullNames:["Ecclesiastes"],chapters:12},{shortName:"SNG",fullNames:["Song of Solomon","Song of Songs"],chapters:8},{shortName:"ISA",fullNames:["Isaiah"],chapters:66},{shortName:"JER",fullNames:["Jeremiah"],chapters:52},{shortName:"LAM",fullNames:["Lamentations"],chapters:5},{shortName:"EZK",fullNames:["Ezekiel"],chapters:48},{shortName:"DAN",fullNames:["Daniel"],chapters:12},{shortName:"HOS",fullNames:["Hosea"],chapters:14},{shortName:"JOL",fullNames:["Joel"],chapters:3},{shortName:"AMO",fullNames:["Amos"],chapters:9},{shortName:"OBA",fullNames:["Obadiah"],chapters:1},{shortName:"JON",fullNames:["Jonah"],chapters:4},{shortName:"MIC",fullNames:["Micah"],chapters:7},{shortName:"NAM",fullNames:["Nahum"],chapters:3},{shortName:"HAB",fullNames:["Habakkuk"],chapters:3},{shortName:"ZEP",fullNames:["Zephaniah"],chapters:3},{shortName:"HAG",fullNames:["Haggai"],chapters:2},{shortName:"ZEC",fullNames:["Zechariah"],chapters:14},{shortName:"MAL",fullNames:["Malachi"],chapters:4},{shortName:"MAT",fullNames:["Matthew"],chapters:28},{shortName:"MRK",fullNames:["Mark"],chapters:16},{shortName:"LUK",fullNames:["Luke"],chapters:24},{shortName:"JHN",fullNames:["John"],chapters:21},{shortName:"ACT",fullNames:["Acts"],chapters:28},{shortName:"ROM",fullNames:["Romans"],chapters:16},{shortName:"1CO",fullNames:["1 Corinthians"],chapters:16},{shortName:"2CO",fullNames:["2 Corinthians"],chapters:13},{shortName:"GAL",fullNames:["Galatians"],chapters:6},{shortName:"EPH",fullNames:["Ephesians"],chapters:6},{shortName:"PHP",fullNames:["Philippians"],chapters:4},{shortName:"COL",fullNames:["Colossians"],chapters:4},{shortName:"1TH",fullNames:["1 Thessalonians"],chapters:5},{shortName:"2TH",fullNames:["2 Thessalonians"],chapters:3},{shortName:"1TI",fullNames:["1 Timothy"],chapters:6},{shortName:"2TI",fullNames:["2 Timothy"],chapters:4},{shortName:"TIT",fullNames:["Titus"],chapters:3},{shortName:"PHM",fullNames:["Philemon"],chapters:1},{shortName:"HEB",fullNames:["Hebrews"],chapters:13},{shortName:"JAS",fullNames:["James"],chapters:5},{shortName:"1PE",fullNames:["1 Peter"],chapters:5},{shortName:"2PE",fullNames:["2 Peter"],chapters:3},{shortName:"1JN",fullNames:["1 John"],chapters:5},{shortName:"2JN",fullNames:["2 John"],chapters:1},{shortName:"3JN",fullNames:["3 John"],chapters:1},{shortName:"JUD",fullNames:["Jude"],chapters:1},{shortName:"REV",fullNames:["Revelation"],chapters:22}],L=1,Z=K.length-1,X=1,Q=1,Y=t=>{var e;return((e=K[t])==null?void 0:e.chapters)??-1},Re=(t,e)=>({bookNum:Math.max(L,Math.min(t.bookNum+e,Z)),chapterNum:1,verseNum:1}),De=(t,e)=>({...t,chapterNum:Math.min(Math.max(X,t.chapterNum+e),Y(t.bookNum)),verseNum:1}),Ie=(t,e)=>({...t,verseNum:Math.max(Q,t.verseNum+e)}),xe=t=>(...e)=>t.map(s=>s(...e)).every(s=>s),_e=t=>async(...e)=>{const r=t.map(async s=>s(...e));return(await Promise.all(r)).every(s=>s)};var D=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},N={},ze=()=>{const t="\\ud800-\\udfff",e="\\u0300-\\u036f",r="\\ufe20-\\ufe2f",s="\\u20d0-\\u20ff",n="\\u1ab0-\\u1aff",o="\\u1dc0-\\u1dff",a=e+r+s+n+o,i="\\ufe0e\\ufe0f",c="\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93",h=`[${t}]`,u=`[${a}]`,l="\\ud83c[\\udffb-\\udfff]",f=`(?:${u}|${l})`,b=`[^${t}]`,d="(?:\\uD83C[\\uDDE6-\\uDDFF]){2}",y="[\\ud800-\\udbff][\\udc00-\\udfff]",q="\\u200d",le="(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)",ce=`[${c}]`,T=`${f}?`,R=`[${i}]?`,fe=`(?:${q}(?:${[b,d,y].join("|")})${R+T})*`,he=R+T+fe,pe=`(?:${[`${b}${u}?`,u,d,y,h,ce].join("|")})`;return new RegExp(`${le}|${l}(?=${l})|${pe+he}`,"g")},Be=D&&D.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(N,"__esModule",{value:!0});var A=Be(ze);function j(t){if(typeof t!="string")throw new Error("A string is expected as input");return t.match(A.default())||[]}var Je=N.toArray=j;function P(t){if(typeof t!="string")throw new Error("Input must be a string");var e=t.match(A.default());return e===null?0:e.length}var Ge=N.length=P;function ee(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");(typeof e!="number"||e<0)&&(e=0),typeof r=="number"&&r<0&&(r=0);var s=t.match(A.default());return s?s.slice(e,r).join(""):""}var Ue=N.substring=ee;function Ve(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");var s=P(t);if(typeof e!="number"&&(e=parseInt(e,10)),e>=s)return"";e<0&&(e+=s);var n;typeof r>"u"?n=s:(typeof r!="number"&&(r=parseInt(r,10)),n=r>=0?r+e:e);var o=t.match(A.default());return o?o.slice(e,n).join(""):""}var Fe=N.substr=Ve;function He(t,e,r,s){if(e===void 0&&(e=16),r===void 0&&(r="#"),s===void 0&&(s="right"),typeof t!="string"||typeof e!="number")throw new Error("Invalid arguments specified");if(["left","right"].indexOf(s)===-1)throw new Error("Pad position should be either left or right");typeof r!="string"&&(r=String(r));var n=P(t);if(n>e)return ee(t,0,e);if(n=s.length)return e===""?s.length:-1;if(e==="")return r;var n=j(e),o=!1,a;for(a=r;am(t)||e<-m(t)))return M(t,e,1)}function Le(t,e){return e<0||e>m(t)-1?"":M(t,e,1)}function Ze(t,e){if(!(e<0||e>m(t)-1))return M(t,e,1).codePointAt(0)}function Xe(t,e,r=m(t)){const s=se(t,e);return!(s===-1||s+m(e)!==r)}function re(t,e,r=0){const s=O(t,r);return S(s,e)!==-1}function S(t,e,r=0){return We(t,e,r)}function se(t,e,r){let s=r||m(t);s<0?s=0:s>=m(t)&&(s=m(t)-1);for(let n=s;n>=0;n--)if(M(t,n,m(e))===e)return n;return-1}function m(t){return Ge(t)}function Qe(t,e){const r=e.toUpperCase();return r==="NONE"?t:t.normalize(r)}function Ye(t,e,r=" "){return e<=m(t)?t:te(t,e,r,"right")}function et(t,e,r=" "){return e<=m(t)?t:te(t,e,r,"left")}function I(t,e){return e>t?t:e<-t?0:e<0?e+t:e}function tt(t,e,r){const s=m(t);if(e>s||r&&(e>r&&!(e>0&&e-s)||r<-s||e<0&&e>-s&&r>0))return"";const n=I(s,e),o=r?I(s,r):void 0;return O(t,n,o)}function rt(t,e,r){const s=[];if(r!==void 0&&r<=0)return[t];if(e==="")return ne(t).slice(0,r);let n=e;(typeof e=="string"||e instanceof RegExp&&!re(e.flags,"g"))&&(n=new RegExp(e,"g"));const o=t.match(n);let a=0;if(!o)return[t];for(let i=0;i<(r?r-1:o.length);i++){const c=S(t,o[i],a),h=m(o[i]);if(s.push(O(t,a,c)),a=c+h,r!==void 0&&s.length===r)break}return s.push(O(t,a)),s}function st(t,e,r=0){return S(t,e,r)===r}function M(t,e=0,r=m(t)-e){return Fe(t,e,r)}function O(t,e,r=m(t)){return Ue(t,e,r)}function ne(t){return Je(t)}var nt=Object.getOwnPropertyNames,ot=Object.getOwnPropertySymbols,at=Object.prototype.hasOwnProperty;function x(t,e){return function(s,n,o){return t(s,n,o)&&e(s,n,o)}}function $(t){return function(r,s,n){if(!r||!s||typeof r!="object"||typeof s!="object")return t(r,s,n);var o=n.cache,a=o.get(r),i=o.get(s);if(a&&i)return a===s&&i===r;o.set(r,s),o.set(s,r);var c=t(r,s,n);return o.delete(r),o.delete(s),c}}function _(t){return nt(t).concat(ot(t))}var oe=Object.hasOwn||function(t,e){return at.call(t,e)};function v(t,e){return t||e?t===e:t===e||t!==t&&e!==e}var ae="_owner",z=Object.getOwnPropertyDescriptor,B=Object.keys;function it(t,e,r){var s=t.length;if(e.length!==s)return!1;for(;s-- >0;)if(!r.equals(t[s],e[s],s,s,t,e,r))return!1;return!0}function ut(t,e){return v(t.getTime(),e.getTime())}function J(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.entries(),o=0,a,i;(a=n.next())&&!a.done;){for(var c=e.entries(),h=!1,u=0;(i=c.next())&&!i.done;){var l=a.value,f=l[0],b=l[1],d=i.value,y=d[0],q=d[1];!h&&!s[u]&&(h=r.equals(f,y,o,u,t,e,r)&&r.equals(b,q,f,y,t,e,r))&&(s[u]=!0),u++}if(!h)return!1;o++}return!0}function lt(t,e,r){var s=B(t),n=s.length;if(B(e).length!==n)return!1;for(var o;n-- >0;)if(o=s[n],o===ae&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!oe(e,o)||!r.equals(t[o],e[o],o,o,t,e,r))return!1;return!0}function w(t,e,r){var s=_(t),n=s.length;if(_(e).length!==n)return!1;for(var o,a,i;n-- >0;)if(o=s[n],o===ae&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!oe(e,o)||!r.equals(t[o],e[o],o,o,t,e,r)||(a=z(t,o),i=z(e,o),(a||i)&&(!a||!i||a.configurable!==i.configurable||a.enumerable!==i.enumerable||a.writable!==i.writable)))return!1;return!0}function ct(t,e){return v(t.valueOf(),e.valueOf())}function ft(t,e){return t.source===e.source&&t.flags===e.flags}function G(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.values(),o,a;(o=n.next())&&!o.done;){for(var i=e.values(),c=!1,h=0;(a=i.next())&&!a.done;)!c&&!s[h]&&(c=r.equals(o.value,a.value,o.value,a.value,t,e,r))&&(s[h]=!0),h++;if(!c)return!1}return!0}function ht(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}var pt="[object Arguments]",mt="[object Boolean]",dt="[object Date]",bt="[object Map]",gt="[object Number]",Nt="[object Object]",vt="[object RegExp]",yt="[object Set]",wt="[object String]",Et=Array.isArray,U=typeof ArrayBuffer=="function"&&ArrayBuffer.isView?ArrayBuffer.isView:null,V=Object.assign,Ot=Object.prototype.toString.call.bind(Object.prototype.toString);function $t(t){var e=t.areArraysEqual,r=t.areDatesEqual,s=t.areMapsEqual,n=t.areObjectsEqual,o=t.arePrimitiveWrappersEqual,a=t.areRegExpsEqual,i=t.areSetsEqual,c=t.areTypedArraysEqual;return function(u,l,f){if(u===l)return!0;if(u==null||l==null||typeof u!="object"||typeof l!="object")return u!==u&&l!==l;var b=u.constructor;if(b!==l.constructor)return!1;if(b===Object)return n(u,l,f);if(Et(u))return e(u,l,f);if(U!=null&&U(u))return c(u,l,f);if(b===Date)return r(u,l,f);if(b===RegExp)return a(u,l,f);if(b===Map)return s(u,l,f);if(b===Set)return i(u,l,f);var d=Ot(u);return d===dt?r(u,l,f):d===vt?a(u,l,f):d===bt?s(u,l,f):d===yt?i(u,l,f):d===Nt?typeof u.then!="function"&&typeof l.then!="function"&&n(u,l,f):d===pt?n(u,l,f):d===mt||d===gt||d===wt?o(u,l,f):!1}}function At(t){var e=t.circular,r=t.createCustomConfig,s=t.strict,n={areArraysEqual:s?w:it,areDatesEqual:ut,areMapsEqual:s?x(J,w):J,areObjectsEqual:s?w:lt,arePrimitiveWrappersEqual:ct,areRegExpsEqual:ft,areSetsEqual:s?x(G,w):G,areTypedArraysEqual:s?w:ht};if(r&&(n=V({},n,r(n))),e){var o=$(n.areArraysEqual),a=$(n.areMapsEqual),i=$(n.areObjectsEqual),c=$(n.areSetsEqual);n=V({},n,{areArraysEqual:o,areMapsEqual:a,areObjectsEqual:i,areSetsEqual:c})}return n}function St(t){return function(e,r,s,n,o,a,i){return t(e,r,i)}}function Mt(t){var e=t.circular,r=t.comparator,s=t.createState,n=t.equals,o=t.strict;if(s)return function(c,h){var u=s(),l=u.cache,f=l===void 0?e?new WeakMap:void 0:l,b=u.meta;return r(c,h,{cache:f,equals:n,meta:b,strict:o})};if(e)return function(c,h){return r(c,h,{cache:new WeakMap,equals:n,meta:void 0,strict:o})};var a={cache:void 0,equals:n,meta:void 0,strict:o};return function(c,h){return r(c,h,a)}}var qt=g();g({strict:!0});g({circular:!0});g({circular:!0,strict:!0});g({createInternalComparator:function(){return v}});g({strict:!0,createInternalComparator:function(){return v}});g({circular:!0,createInternalComparator:function(){return v}});g({circular:!0,createInternalComparator:function(){return v},strict:!0});function g(t){t===void 0&&(t={});var e=t.circular,r=e===void 0?!1:e,s=t.createInternalComparator,n=t.createState,o=t.strict,a=o===void 0?!1:o,i=At(t),c=$t(i),h=s?s(c):St(c);return Mt({circular:r,comparator:c,createState:n,equals:h,strict:a})}function jt(t,e){return qt(t,e)}function C(t,e,r){return JSON.stringify(t,(n,o)=>{let a=o;return e&&(a=e(n,a)),a===void 0&&(a=null),a},r)}function ie(t,e){function r(n){return Object.keys(n).forEach(o=>{n[o]===null?n[o]=void 0:typeof n[o]=="object"&&(n[o]=r(n[o]))}),n}const s=JSON.parse(t,e);if(s!==null)return typeof s=="object"?r(s):s}function Ct(t){try{const e=C(t);return e===C(ie(e))}catch{return!1}}const Pt=t=>t.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/"),ue={title:"Platform.Bible menus",type:"object",properties:{mainMenu:{description:"Top level menu for the application",$ref:"#/$defs/multiColumnMenu"},defaultWebViewTopMenu:{description:"Default top menu for web views that don't specify their own",$ref:"#/$defs/multiColumnMenu"},defaultWebViewContextMenu:{description:"Default context menu for web views that don't specify their own",$ref:"#/$defs/singleColumnMenu"},webViewMenus:{description:"Menus that apply per web view in the application",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{$ref:"#/$defs/menusForOneWebView"}},additionalProperties:!1}},required:["mainMenu","defaultWebViewTopMenu","defaultWebViewContextMenu","webViewMenus"],additionalProperties:!1,$defs:{localizeKey:{description:"Identifier for a string that will be localized in a menu based on the user's UI language",type:"string",pattern:"^%[\\w\\-\\.]+%$"},referencedItem:{description:"Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)",type:"string",pattern:"^[\\w\\-]+\\.[\\w\\-]+$"},columnsWithHeaders:{description:"Group of columns that can be combined with other columns to form a multi-column menu",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single column with a header string",type:"object",properties:{label:{description:"Header text for this this column in the UI",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},order:{description:"Relative order of this column compared to other columns (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu groups to this column",type:"boolean"}},required:["label","order"],additionalProperties:!1}},properties:{isExtensible:{description:"Defines whether contributions are allowed to add columns to this multi-column menu",type:"boolean"}}},menuGroups:{description:"Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single group that contains menu items",type:"object",oneOf:[{properties:{column:{description:"Column where this group belongs, not required for single column menus",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["order"],additionalProperties:!1},{properties:{menuItem:{description:"Menu item that anchors the submenu where this group belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["menuItem","order"],additionalProperties:!1}]}},additionalProperties:!1},menuItem:{description:"Single item in a menu that can be clicked on to take an action or can be the parent of a submenu",type:"object",oneOf:[{properties:{id:{description:"ID for this menu item that holds a submenu",$ref:"#/$defs/referencedItem"}},required:["id"]},{properties:{command:{description:"Name of the PAPI command to run when this menu item is selected.",$ref:"#/$defs/referencedItem"},iconPathBefore:{description:"Path to the icon to display before the menu text",type:"string"},iconPathAfter:{description:"Path to the icon to display after the menu text",type:"string"}},required:["command"]}],properties:{label:{description:"Key that represents the text of this menu item to display",$ref:"#/$defs/localizeKey"},tooltip:{description:"Key that represents the text to display if a mouse pointer hovers over the menu item",$ref:"#/$defs/localizeKey"},searchTerms:{description:"Key that represents additional words the platform should reference when users are searching for menu items",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},group:{description:"Group to which this menu item belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this menu item compared to other menu items in the same group (sorted ascending)",type:"number"}},required:["label","group","order"],unevaluatedProperties:!1},groupsAndItems:{description:"Core schema for a column",type:"object",properties:{groups:{description:"Groups that belong in this menu",$ref:"#/$defs/menuGroups"},items:{description:"List of menu items that belong in this menu",type:"array",items:{$ref:"#/$defs/menuItem"},uniqueItems:!0}},required:["groups","items"]},singleColumnMenu:{description:"Menu that contains a column without a header",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"}],unevaluatedProperties:!1},multiColumnMenu:{description:"Menu that can contain multiple columns with headers",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"},{properties:{columns:{description:"Columns that belong in this menu",$ref:"#/$defs/columnsWithHeaders"}},required:["columns"]}],unevaluatedProperties:!1},menusForOneWebView:{description:"Set of menus that are associated with a single tab",type:"object",properties:{includeDefaults:{description:"Indicates whether the platform default menus should be included for this webview",type:"boolean"},topMenu:{description:"Menu that opens when you click on the top left corner of a tab",$ref:"#/$defs/multiColumnMenu"},contextMenu:{description:"Menu that opens when you right click on the main body/area of a tab",$ref:"#/$defs/singleColumnMenu"}},additionalProperties:!1}}};Object.freeze(ue);exports.AsyncVariable=ge;exports.DocumentCombinerEngine=Me;exports.FIRST_SCR_BOOK_NUM=L;exports.FIRST_SCR_CHAPTER_NUM=X;exports.FIRST_SCR_VERSE_NUM=Q;exports.LAST_SCR_BOOK_NUM=Z;exports.Mutex=W;exports.MutexMap=Te;exports.PlatformEventEmitter=Pe;exports.UnsubscriberAsyncList=Ce;exports.aggregateUnsubscriberAsyncs=_e;exports.aggregateUnsubscribers=xe;exports.at=Ke;exports.charAt=Le;exports.codePointAt=Ze;exports.createSyncProxyForAsyncObject=Se;exports.debounce=ve;exports.deepClone=E;exports.deepEqual=jt;exports.deserialize=ie;exports.endsWith=Xe;exports.getAllObjectFunctionNames=Ae;exports.getChaptersForBook=Y;exports.getErrorMessage=Oe;exports.groupBy=ye;exports.htmlEncode=Pt;exports.includes=re;exports.indexOf=S;exports.isSerializable=Ct;exports.isString=F;exports.lastIndexOf=se;exports.length=m;exports.menuDocumentSchema=ue;exports.newGuid=Ne;exports.normalize=Qe;exports.offsetBook=Re;exports.offsetChapter=De;exports.offsetVerse=Ie;exports.padEnd=Ye;exports.padStart=et;exports.serialize=C;exports.slice=tt;exports.split=rt;exports.startsWith=st;exports.substring=O;exports.toArray=ne;exports.wait=H;exports.waitForDuration=$e; //# sourceMappingURL=index.cjs.map diff --git a/lib/platform-bible-utils/dist/index.cjs.map b/lib/platform-bible-utils/dist/index.cjs.map index 61f77f16ff..185424047d 100644 --- a/lib/platform-bible-utils/dist/index.cjs.map +++ b/lib/platform-bible-utils/dist/index.cjs.map @@ -1 +1 @@ -{"version":3,"file":"index.cjs","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/mutex.ts","../src/mutex-map.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { Mutex as AsyncMutex } from 'async-mutex';\n\n// Extending Mutex from async-mutex so we can add JSDoc\n\n/**\n * Class that allows calling asynchronous functions multiple times at once while only running one at\n * a time.\n *\n * @example\n *\n * ```typescript\n * const mutex = new Mutex();\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n * ```\n *\n * See [`async-mutex`](https://www.npmjs.com/package/async-mutex) for more information.\n */\nclass Mutex extends AsyncMutex {}\n\nexport default Mutex;\n","import Mutex from './mutex';\n\n/** Map of {@link Mutex}es that automatically (lazily) generates a new {@link Mutex} for any new key */\nclass MutexMap {\n private mutexesByID = new Map();\n\n get(mutexID: string): Mutex {\n let retVal = this.mutexesByID.get(mutexID);\n if (retVal) return retVal;\n\n retVal = new Mutex();\n this.mutexesByID.set(mutexID, retVal);\n return retVal;\n }\n}\n\nexport default MutexMap;\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * Finds the Unicode code point at the given index\n *\n * @param {string} string String to index\n * @param {number} index Position of the character to be returned in range of 0 to -length(string)\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > length(string) || index < -length(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * Always indexes string as a sequence of Unicode code points\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, empty string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > length(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to index\n * @param {number} index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {number | undefined} Non-negative integer representing the code point value of the\n * character at the given index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > length(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * Determines whether a string ends with the characters of this string. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Characters to search for at the end of the string\n * @param {number} [endPosition=length(string)] End position where searchString is expected to be\n * found. Default is `length(string)`\n * @returns {boolean} True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = length(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + length(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * Performs a case-sensitive search to determine if searchString is found in string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString String to search for\n * @param {string} [position=0] Position within the string to start searching for searchString.\n * Default is `0`\n * @returns {boolean} True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * Returns the index of the first occurrence of a given string. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The string to search for\n * @param {number} [position=0] Start of searching. Default is `0`\n * @returns {number} Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * Searches this string and returns the index of the last occurrence of the specified substring.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Substring to search for\n * @param {number} [position=+Infinity] The method returns the index of the last occurrence of the\n * specified substring at a position less than or equal to position. . Default is `+Infinity`\n * @returns {number} Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(\n string: string,\n searchString: string,\n position: number = +Infinity,\n): number {\n let validatedPosition = position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= length(string)) {\n validatedPosition = length(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, length(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * Returns the length of a string. This function handles Unicode code points instead of UTF-16\n * character codes.\n *\n * @param {string} string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function length(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * Returns the Unicode Normalization Form of this string.\n *\n * @param {string} string The starting string\n * @param {'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'} [form='NFC'] Form specifying the Unicode\n * Normalization Form. Default is `'NFC'`\n * @returns {string} A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within targetLength, it will be truncated. Default is `\" \"`\n * @returns {string} String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\nfunction correctSliceIndex(stringLength: number, index: number) {\n if (index > stringLength) return stringLength;\n if (index < -stringLength) return 0;\n if (index < 0) return index + stringLength;\n return index;\n}\n\n/**\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The starting string\n * @param {number} indexStart The index of the first character to include in the returned substring.\n * @param {number} indexEnd The index of the first character to exclude from the returned substring.\n * @returns {string} A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const stringLength: number = length(string);\n if (\n indexStart > stringLength ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(\n indexStart > 0 &&\n indexStart < stringLength &&\n indexEnd < 0 &&\n indexEnd > -stringLength\n )) ||\n indexEnd < -stringLength ||\n (indexStart < 0 && indexStart > -stringLength && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(stringLength, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The string to split\n * @param {string | RegExp} separator The pattern describing where each split should occur\n * @param {number} splitLimit Limit on the number of substrings to be included in the array. Splits\n * the string at each occurrence of specified separator, but stops when limit entries have been\n * placed in the array.\n * @returns {string[] | undefined} An array of strings, split at each point where separator occurs\n * in the starting string. Returns undefined if separator is not found in string.\n */\nexport function split(string: string, separator: string | RegExp, splitLimit?: number): string[] {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !includes(separator.flags, 'g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return [string];\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = length(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate. This function handles Unicode code points instead of UTF-16 character\n * codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The characters to be searched for at the start of this string.\n * @param {number} [position=0] The start position at which searchString is expected to be found\n * (the index of searchString's first character). Default is `0`\n * @returns {boolean} True if the given characters are found at the beginning of the string,\n * including when searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * Returns a substring by providing start and length. This function handles Unicode code points\n * instead of UTF-16 character codes. This function is not exported because it is considered\n * deprecated, however it is still useful as a local helper function.\n *\n * @param {string} string String to be divided\n * @param {number} [begin=Start of string] Start position. Default is `Start of string`\n * @param {number} [len=String length minus start parameter] Length of result. Default is `String\n * length minus start parameter`. Default is `String length minus start parameter`\n * @returns {string} Substring from starting string\n */\nfunction substr(string: string, begin: number = 0, len: number = length(string) - begin): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * Returns a substring by providing start and end position. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to be divided\n * @param {string} begin Start position\n * @param {number} [end=End of string] End position. Default is `End of string`\n * @returns {string} Substring from starting string\n */\nexport function substring(\n string: string,\n begin?: number | undefined,\n end: number | undefined = length(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * Converts a string to an array of string characters. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param {string} string String to convert to array\n * @returns {string[]} An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","Mutex","AsyncMutex","MutexMap","mutexID","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","stringLength","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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,EACA,CACE,WAAY,CACV,SAAU,CACR,YAAa,8DACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,WAAY,OAAO,EAC9B,qBAAsB,EACxB,CACF,CACF,CACF,EACA,qBAAsB,EACxB,EACA,SAAU,CACR,YACE,mGACF,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,GAAI,CACF,YAAa,6CACb,KAAM,wBACR,CACF,EACA,SAAU,CAAC,IAAI,CACjB,EACA,CACE,WAAY,CACV,QAAS,CACP,YAAa,mEACb,KAAM,wBACR,EACA,eAAgB,CACd,YAAa,mDACb,KAAM,QACR,EACA,cAAe,CACb,YAAa,kDACb,KAAM,QACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,WAAY,CACV,MAAO,CACL,YAAa,4DACb,KAAM,qBACR,EACA,QAAS,CACP,YACE,uFACF,KAAM,qBACR,EACA,YAAa,CACX,YACE,6GACF,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YAAa,wCACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,qGACF,KAAM,QACR,CACF,EACA,SAAU,CAAC,QAAS,QAAS,OAAO,EACpC,sBAAuB,EACzB,EACA,eAAgB,CACd,YAAa,2BACb,KAAM,SACN,WAAY,CACV,OAAQ,CACN,YAAa,kCACb,KAAM,oBACR,EACA,MAAO,CACL,YAAa,8CACb,KAAM,QACN,MAAO,CAAE,KAAM,kBAAmB,EAClC,YAAa,EACf,CACF,EACA,SAAU,CAAC,SAAU,OAAO,CAC9B,EACA,iBAAkB,CAChB,YAAa,+CACb,KAAM,SACN,MAAO,CAAC,CAAE,KAAM,yBAA0B,EAC1C,sBAAuB,EACzB,EACA,gBAAiB,CACf,YAAa,sDACb,KAAM,SACN,MAAO,CACL,CAAE,KAAM,wBAAyB,EACjC,CACE,WAAY,CACV,QAAS,CACP,YAAa,mCACb,KAAM,4BACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,sBAAuB,EACzB,EACA,mBAAoB,CAClB,YAAa,qDACb,KAAM,SACN,WAAY,CACV,gBAAiB,CACf,YACE,mFACF,KAAM,SACR,EACA,QAAS,CACP,YAAa,iEACb,KAAM,yBACR,EACA,YAAa,CACX,YAAa,sEACb,KAAM,0BACR,CACF,EACA,qBAAsB,EACxB,CACF,CACF,EAEA,OAAO,OAAOA,EAAkB","x_google_ignoreList":[9,10,12]} \ No newline at end of file +{"version":3,"file":"index.cjs","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/mutex.ts","../src/mutex-map.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { Mutex as AsyncMutex } from 'async-mutex';\n\n// Extending Mutex from async-mutex so we can add JSDoc\n\n/**\n * Class that allows calling asynchronous functions multiple times at once while only running one at\n * a time.\n *\n * @example\n *\n * ```typescript\n * const mutex = new Mutex();\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n * ```\n *\n * See [`async-mutex`](https://www.npmjs.com/package/async-mutex) for more information.\n */\nclass Mutex extends AsyncMutex {}\n\nexport default Mutex;\n","import Mutex from './mutex';\n\n/** Map of {@link Mutex}es that automatically (lazily) generates a new {@link Mutex} for any new key */\nclass MutexMap {\n private mutexesByID = new Map();\n\n get(mutexID: string): Mutex {\n let retVal = this.mutexesByID.get(mutexID);\n if (retVal) return retVal;\n\n retVal = new Mutex();\n this.mutexesByID.set(mutexID, retVal);\n return retVal;\n }\n}\n\nexport default MutexMap;\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * Finds the Unicode code point at the given index. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param string String to index\n * @param index Position of the character to be returned in range of -length(string) to\n * length(string)\n * @returns New string consisting of the Unicode code point located at the specified\n * offset, undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > length(string) || index < -length(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * Returns a new string consisting of the single UTF-16 code unit at the given index.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns New string consisting of the Unicode code point located at the specified\n * offset, empty string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > length(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns Non-negative integer representing the code point value of the\n * character at the given index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > length(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * Determines whether a string ends with the characters of this string. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to search through\n * @param searchString Characters to search for at the end of the string\n * @param endPosition End position where searchString is expected to be\n * found. Default is `length(string)`\n * @returns True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = length(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + length(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * Performs a case-sensitive search to determine if searchString is found in string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to search through\n * @param searchString String to search for\n * @param position Position within the string to start searching for searchString.\n * Default is `0`\n * @returns True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * Returns the index of the first occurrence of a given string. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param string String to search through\n * @param searchString The string to search for\n * @param position Start of searching. Default is `0`\n * @returns Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * Searches this string and returns the index of the last occurrence of the specified substring.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to search through\n * @param searchString Substring to search for\n * @param position The index at which to begin searching. If omitted, the search begins at the end\n * of the string. Default is `undefined`\n * @returns Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(\n string: string,\n searchString: string,\n position?: number,\n): number {\n let validatedPosition = position ? position : length(string);\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= length(string)) {\n validatedPosition = length(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, length(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * Returns the length of a string. This function handles Unicode code points instead of UTF-16\n * character codes.\n *\n * @param string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function length(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * Returns the Unicode Normalization Form of this string.\n *\n * @param string The starting string\n * @param form Form specifying the Unicode Normalization Form. Default is `'NFC'`\n * @returns A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to add padding too\n * @param targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param padString The string to pad the current string with. If padString is too\n * long to stay within targetLength, it will be truncated. Default is `\" \"`\n * @returns String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to add padding too\n * @param targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param padString The string to pad the current string with. If padString is too\n * long to stay within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\nfunction correctSliceIndex(stringLength: number, index: number) {\n if (index > stringLength) return stringLength;\n if (index < -stringLength) return 0;\n if (index < 0) return index + stringLength;\n return index;\n}\n\n/**\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string The starting string\n * @param indexStart The index of the first character to include in the returned substring.\n * @param indexEnd The index of the first character to exclude from the returned substring.\n * @returns A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const stringLength: number = length(string);\n if (\n indexStart > stringLength ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(\n indexStart > 0 &&\n indexStart < stringLength &&\n indexEnd < 0 &&\n indexEnd > -stringLength\n )) ||\n indexEnd < -stringLength ||\n (indexStart < 0 && indexStart > -stringLength && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(stringLength, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param string The string to split\n * @param separator The pattern describing where each split should occur\n * @param splitLimit Limit on the number of substrings to be included in the array. Splits\n * the string at each occurrence of specified separator, but stops when limit entries have been\n * placed in the array.\n * @returns An array of strings, split at each point where separator occurs\n * in the starting string. Returns undefined if separator is not found in string.\n */\nexport function split(string: string, separator: string | RegExp, splitLimit?: number): string[] {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !includes(separator.flags, 'g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return [string];\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = length(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate. This function handles Unicode code points instead of UTF-16 character\n * codes.\n *\n * @param string String to search through\n * @param searchString The characters to be searched for at the start of this string.\n * @param position The start position at which searchString is expected to be found\n * (the index of searchString's first character). Default is `0`\n * @returns True if the given characters are found at the beginning of the string,\n * including when searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * Returns a substring by providing start and length. This function handles Unicode code points\n * instead of UTF-16 character codes. This function is not exported because it is considered\n * deprecated, however it is still useful as a local helper function.\n *\n * @param string String to be divided\n * @param begin Start position. Default is `Start of string`\n * @param len Length of result. Default is `String\n * length minus start parameter`. Default is `String length minus start parameter`\n * @returns Substring from starting string\n */\nfunction substr(string: string, begin: number = 0, len: number = length(string) - begin): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * Returns a substring by providing start and end position. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param string String to be divided\n * @param begin Start position\n * @param end End position. Default is `End of string`\n * @returns Substring from starting string\n */\nexport function substring(\n string: string,\n begin: number,\n end: number = length(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * Converts a string to an array of string characters. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param string String to convert to array\n * @returns An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","Mutex","AsyncMutex","MutexMap","mutexID","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","stringLength","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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B,qBAAsB,EACxB,EACA,CACE,WAAY,CACV,SAAU,CACR,YAAa,8DACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,WAAY,OAAO,EAC9B,qBAAsB,EACxB,CACF,CACF,CACF,EACA,qBAAsB,EACxB,EACA,SAAU,CACR,YACE,mGACF,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,GAAI,CACF,YAAa,6CACb,KAAM,wBACR,CACF,EACA,SAAU,CAAC,IAAI,CACjB,EACA,CACE,WAAY,CACV,QAAS,CACP,YAAa,mEACb,KAAM,wBACR,EACA,eAAgB,CACd,YAAa,mDACb,KAAM,QACR,EACA,cAAe,CACb,YAAa,kDACb,KAAM,QACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,WAAY,CACV,MAAO,CACL,YAAa,4DACb,KAAM,qBACR,EACA,QAAS,CACP,YACE,uFACF,KAAM,qBACR,EACA,YAAa,CACX,YACE,6GACF,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YAAa,wCACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,qGACF,KAAM,QACR,CACF,EACA,SAAU,CAAC,QAAS,QAAS,OAAO,EACpC,sBAAuB,EACzB,EACA,eAAgB,CACd,YAAa,2BACb,KAAM,SACN,WAAY,CACV,OAAQ,CACN,YAAa,kCACb,KAAM,oBACR,EACA,MAAO,CACL,YAAa,8CACb,KAAM,QACN,MAAO,CAAE,KAAM,kBAAmB,EAClC,YAAa,EACf,CACF,EACA,SAAU,CAAC,SAAU,OAAO,CAC9B,EACA,iBAAkB,CAChB,YAAa,+CACb,KAAM,SACN,MAAO,CAAC,CAAE,KAAM,yBAA0B,EAC1C,sBAAuB,EACzB,EACA,gBAAiB,CACf,YAAa,sDACb,KAAM,SACN,MAAO,CACL,CAAE,KAAM,wBAAyB,EACjC,CACE,WAAY,CACV,QAAS,CACP,YAAa,mCACb,KAAM,4BACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,sBAAuB,EACzB,EACA,mBAAoB,CAClB,YAAa,qDACb,KAAM,SACN,WAAY,CACV,gBAAiB,CACf,YACE,mFACF,KAAM,SACR,EACA,QAAS,CACP,YAAa,iEACb,KAAM,yBACR,EACA,YAAa,CACX,YAAa,sEACb,KAAM,0BACR,CACF,EACA,qBAAsB,EACxB,CACF,CACF,EAEA,OAAO,OAAOA,EAAkB","x_google_ignoreList":[9,10,12]} \ No newline at end of file diff --git a/lib/platform-bible-utils/dist/index.d.ts b/lib/platform-bible-utils/dist/index.d.ts index a3c597e697..798be2391f 100644 --- a/lib/platform-bible-utils/dist/index.d.ts +++ b/lib/platform-bible-utils/dist/index.d.ts @@ -404,21 +404,24 @@ export declare function getAllObjectFunctionNames(obj: { */ export declare function createSyncProxyForAsyncObject(getObject: (args?: unknown[]) => Promise, objectToProxy?: Partial): T; /** - * Finds the Unicode code point at the given index + * Finds the Unicode code point at the given index. This function handles Unicode code points + * instead of UTF-16 character codes. * - * @param {string} string String to index - * @param {number} index Position of the character to be returned in range of 0 to -length(string) - * @returns {string} New string consisting of the Unicode code point located at the specified + * @param string String to index + * @param index Position of the character to be returned in range of -length(string) to + * length(string) + * @returns New string consisting of the Unicode code point located at the specified * offset, undefined if index is out of bounds */ export declare function at(string: string, index: number): string | undefined; /** - * Always indexes string as a sequence of Unicode code points + * Returns a new string consisting of the single UTF-16 code unit at the given index. + * This function handles Unicode code points instead of UTF-16 character codes. * * @param string String to index * @param index Position of the string character to be returned, in the range of 0 to * length(string)-1 - * @returns {string} New string consisting of the Unicode code point located at the specified + * @returns New string consisting of the Unicode code point located at the specified * offset, empty string if index is out of bounds */ export declare function charAt(string: string, index: number): string; @@ -426,10 +429,10 @@ export declare function charAt(string: string, index: number): string; * Returns a non-negative integer that is the Unicode code point value of the character starting at * the given index. This function handles Unicode code points instead of UTF-16 character codes. * - * @param {string} string String to index - * @param {number} index Position of the string character to be returned, in the range of 0 to + * @param string String to index + * @param index Position of the string character to be returned, in the range of 0 to * length(string)-1 - * @returns {number | undefined} Non-negative integer representing the code point value of the + * @returns Non-negative integer representing the code point value of the * character at the given index, or undefined if there is no element at that position */ export declare function codePointAt(string: string, index: number): number | undefined; @@ -437,53 +440,52 @@ export declare function codePointAt(string: string, index: number): number | und * Determines whether a string ends with the characters of this string. This function handles * Unicode code points instead of UTF-16 character codes. * - * @param {string} string String to search through - * @param {string} searchString Characters to search for at the end of the string - * @param {number} [endPosition=length(string)] End position where searchString is expected to be + * @param string String to search through + * @param searchString Characters to search for at the end of the string + * @param endPosition End position where searchString is expected to be * found. Default is `length(string)` - * @returns {boolean} True if it ends with searchString, false if it does not + * @returns True if it ends with searchString, false if it does not */ export declare function endsWith(string: string, searchString: string, endPosition?: number): boolean; /** * Performs a case-sensitive search to determine if searchString is found in string. This function * handles Unicode code points instead of UTF-16 character codes. * - * @param {string} string String to search through - * @param {string} searchString String to search for - * @param {string} [position=0] Position within the string to start searching for searchString. + * @param string String to search through + * @param searchString String to search for + * @param position Position within the string to start searching for searchString. * Default is `0` - * @returns {boolean} True if search string is found, false if it is not + * @returns True if search string is found, false if it is not */ export declare function includes(string: string, searchString: string, position?: number): boolean; /** * Returns the index of the first occurrence of a given string. This function handles Unicode code * points instead of UTF-16 character codes. * - * @param {string} string String to search through - * @param {string} searchString The string to search for - * @param {number} [position=0] Start of searching. Default is `0` - * @returns {number} Index of the first occurrence of a given string + * @param string String to search through + * @param searchString The string to search for + * @param position Start of searching. Default is `0` + * @returns Index of the first occurrence of a given string */ export declare function indexOf(string: string, searchString: string, position?: number | undefined): number; /** * Searches this string and returns the index of the last occurrence of the specified substring. * This function handles Unicode code points instead of UTF-16 character codes. * - * @param {string} string String to search through - * @param {string} searchString Substring to search for - * @param {number} [position=+Infinity] The method returns the index of the last occurrence of the - * specified substring at a position less than or equal to position. . Default is `+Infinity` - * @returns {number} Index of the last occurrence of searchString found, or -1 if not found. + * @param string String to search through + * @param searchString Substring to search for + * @param position The index at which to begin searching. If omitted, the search begins at the end + * of the string. Default is `undefined` + * @returns Index of the last occurrence of searchString found, or -1 if not found. */ export declare function lastIndexOf(string: string, searchString: string, position?: number): number; declare function length$1(string: string): number; /** * Returns the Unicode Normalization Form of this string. * - * @param {string} string The starting string - * @param {'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'} [form='NFC'] Form specifying the Unicode - * Normalization Form. Default is `'NFC'` - * @returns {string} A string containing the Unicode Normalization Form of the given string. + * @param string The starting string + * @param form Form specifying the Unicode Normalization Form. Default is `'NFC'` + * @returns A string containing the Unicode Normalization Form of the given string. */ export declare function normalize(string: string, form: "NFC" | "NFD" | "NFKC" | "NFKD" | "none"): string; /** @@ -491,12 +493,12 @@ export declare function normalize(string: string, form: "NFC" | "NFD" | "NFKC" | * reaches the given length. The padding is applied from the end of this string. This function * handles Unicode code points instead of UTF-16 character codes. * - * @param {string} string String to add padding too - * @param {number} targetLength The length of the resulting string once the starting string has been + * @param string String to add padding too + * @param targetLength The length of the resulting string once the starting string has been * padded. If value is less than or equal to length(string), then string is returned as is. - * @param {string} [padString=" "] The string to pad the current string with. If padString is too + * @param padString The string to pad the current string with. If padString is too * long to stay within targetLength, it will be truncated. Default is `" "` - * @returns {string} String with appropriate padding at the end + * @returns String with appropriate padding at the end */ export declare function padEnd(string: string, targetLength: number, padString?: string): string; /** @@ -504,10 +506,10 @@ export declare function padEnd(string: string, targetLength: number, padString?: * reaches the given length. The padding is applied from the start of this string. This function * handles Unicode code points instead of UTF-16 character codes. * - * @param {string} string String to add padding too - * @param {number} targetLength The length of the resulting string once the starting string has been + * @param string String to add padding too + * @param targetLength The length of the resulting string once the starting string has been * padded. If value is less than or equal to length(string), then string is returned as is. - * @param {string} [padString=" "] The string to pad the current string with. If padString is too + * @param padString The string to pad the current string with. If padString is too * long to stay within the targetLength, it will be truncated from the end. Default is `" "` * @returns String with of specified targetLength with padString applied from the start */ @@ -516,10 +518,10 @@ export declare function padStart(string: string, targetLength: number, padString * Extracts a section of this string and returns it as a new string, without modifying the original * string. This function handles Unicode code points instead of UTF-16 character codes. * - * @param {string} string The starting string - * @param {number} indexStart The index of the first character to include in the returned substring. - * @param {number} indexEnd The index of the first character to exclude from the returned substring. - * @returns {string} A new string containing the extracted section of the string. + * @param string The starting string + * @param indexStart The index of the first character to include in the returned substring. + * @param indexEnd The index of the first character to exclude from the returned substring. + * @returns A new string containing the extracted section of the string. */ export declare function slice(string: string, indexStart: number, indexEnd?: number): string; /** @@ -527,12 +529,12 @@ export declare function slice(string: string, indexStart: number, indexEnd?: num * pattern, puts these substrings into an array, and returns the array. This function handles * Unicode code points instead of UTF-16 character codes. * - * @param {string} string The string to split - * @param {string | RegExp} separator The pattern describing where each split should occur - * @param {number} splitLimit Limit on the number of substrings to be included in the array. Splits + * @param string The string to split + * @param separator The pattern describing where each split should occur + * @param splitLimit Limit on the number of substrings to be included in the array. Splits * the string at each occurrence of specified separator, but stops when limit entries have been * placed in the array. - * @returns {string[] | undefined} An array of strings, split at each point where separator occurs + * @returns An array of strings, split at each point where separator occurs * in the starting string. Returns undefined if separator is not found in string. */ export declare function split(string: string, separator: string | RegExp, splitLimit?: number): string[]; @@ -541,11 +543,11 @@ export declare function split(string: string, separator: string | RegExp, splitL * false as appropriate. This function handles Unicode code points instead of UTF-16 character * codes. * - * @param {string} string String to search through - * @param {string} searchString The characters to be searched for at the start of this string. - * @param {number} [position=0] The start position at which searchString is expected to be found + * @param string String to search through + * @param searchString The characters to be searched for at the start of this string. + * @param position The start position at which searchString is expected to be found * (the index of searchString's first character). Default is `0` - * @returns {boolean} True if the given characters are found at the beginning of the string, + * @returns True if the given characters are found at the beginning of the string, * including when searchString is an empty string; otherwise, false. */ export declare function startsWith(string: string, searchString: string, position?: number): boolean; @@ -553,18 +555,18 @@ export declare function startsWith(string: string, searchString: string, positio * Returns a substring by providing start and end position. This function handles Unicode code * points instead of UTF-16 character codes. * - * @param {string} string String to be divided - * @param {string} begin Start position - * @param {number} [end=End of string] End position. Default is `End of string` - * @returns {string} Substring from starting string + * @param string String to be divided + * @param begin Start position + * @param end End position. Default is `End of string` + * @returns Substring from starting string */ -export declare function substring(string: string, begin?: number | undefined, end?: number | undefined): string; +export declare function substring(string: string, begin: number, end?: number): string; /** * Converts a string to an array of string characters. This function handles Unicode code points * instead of UTF-16 character codes. * - * @param {string} string String to convert to array - * @returns {string[]} An array of characters from the starting string + * @param string String to convert to array + * @returns An array of characters from the starting string */ export declare function toArray(string: string): string[]; /** diff --git a/lib/platform-bible-utils/dist/index.js b/lib/platform-bible-utils/dist/index.js index 38621009d1..955a1b03a0 100644 --- a/lib/platform-bible-utils/dist/index.js +++ b/lib/platform-bible-utils/dist/index.js @@ -468,7 +468,7 @@ const k = [ return (await Promise.all(r)).every((s) => s); }; var T = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}, g = {}, be = () => { - const t = "\\ud800-\\udfff", e = "\\u0300-\\u036f", r = "\\ufe20-\\ufe2f", s = "\\u20d0-\\u20ff", n = "\\u1ab0-\\u1aff", o = "\\u1dc0-\\u1dff", a = e + r + s + n + o, i = "\\ufe0e\\ufe0f", c = "\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93", h = `[${t}]`, u = `[${a}]`, l = "\\ud83c[\\udffb-\\udfff]", f = `(?:${u}|${l})`, b = `[^${t}]`, m = "(?:\\uD83C[\\uDDE6-\\uDDFF]){2}", y = "[\\ud800-\\udbff][\\udc00-\\udfff]", j = "\\u200d", Z = "(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)", X = `[${c}]`, P = `${f}?`, D = `[${i}]?`, Q = `(?:${j}(?:${[b, m, y].join("|")})${D + P})*`, Y = D + P + Q, ee = `(?:${[`${b}${u}?`, u, m, y, h, X].join("|")})`; + const t = "\\ud800-\\udfff", e = "\\u0300-\\u036f", r = "\\ufe20-\\ufe2f", s = "\\u20d0-\\u20ff", n = "\\u1ab0-\\u1aff", o = "\\u1dc0-\\u1dff", a = e + r + s + n + o, i = "\\ufe0e\\ufe0f", c = "\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93", h = `[${t}]`, u = `[${a}]`, l = "\\ud83c[\\udffb-\\udfff]", f = `(?:${u}|${l})`, b = `[^${t}]`, d = "(?:\\uD83C[\\uDDE6-\\uDDFF]){2}", y = "[\\ud800-\\udbff][\\udc00-\\udfff]", j = "\\u200d", Z = "(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)", X = `[${c}]`, P = `${f}?`, D = `[${i}]?`, Q = `(?:${j}(?:${[b, d, y].join("|")})${D + P})*`, Y = D + P + Q, ee = `(?:${[`${b}${u}?`, u, d, y, h, X].join("|")})`; return new RegExp(`${Z}|${l}(?=${l})|${ee + Y}`, "g"); }, Ne = T && T.__importDefault || function(t) { return t && t.__esModule ? t : { default: t }; @@ -549,19 +549,19 @@ function $e(t, e, r) { } var Ae = g.indexOf = $e; function Et(t, e) { - if (!(e > d(t) || e < -d(t))) + if (!(e > m(t) || e < -m(t))) return q(t, e, 1); } function Ot(t, e) { - return e < 0 || e > d(t) - 1 ? "" : q(t, e, 1); + return e < 0 || e > m(t) - 1 ? "" : q(t, e, 1); } function $t(t, e) { - if (!(e < 0 || e > d(t) - 1)) + if (!(e < 0 || e > m(t) - 1)) return q(t, e, 1).codePointAt(0); } -function At(t, e, r = d(t)) { +function At(t, e, r = m(t)) { const s = je(t, e); - return !(s === -1 || s + d(e) !== r); + return !(s === -1 || s + m(e) !== r); } function qe(t, e, r = 0) { const s = $(t, r); @@ -570,15 +570,15 @@ function qe(t, e, r = 0) { function C(t, e, r = 0) { return Ae(t, e, r); } -function je(t, e, r = 1 / 0) { - let s = r; - s < 0 ? s = 0 : s >= d(t) && (s = d(t) - 1); +function je(t, e, r) { + let s = r || m(t); + s < 0 ? s = 0 : s >= m(t) && (s = m(t) - 1); for (let n = s; n >= 0; n--) - if (q(t, n, d(e)) === e) + if (q(t, n, m(e)) === e) return n; return -1; } -function d(t) { +function m(t) { return ve(t); } function qt(t, e) { @@ -586,16 +586,16 @@ function qt(t, e) { return r === "NONE" ? t : t.normalize(r); } function jt(t, e, r = " ") { - return e <= d(t) ? t : W(t, e, r, "right"); + return e <= m(t) ? t : W(t, e, r, "right"); } function Mt(t, e, r = " ") { - return e <= d(t) ? t : W(t, e, r, "left"); + return e <= m(t) ? t : W(t, e, r, "left"); } function R(t, e) { return e > t ? t : e < -t ? 0 : e < 0 ? e + t : e; } function St(t, e, r) { - const s = d(t); + const s = m(t); if (e > s || r && (e > r && !(e > 0 && e < s && r < 0 && r > -s) || r < -s || e < 0 && e > -s && r > 0)) return ""; const n = R(s, e), o = r ? R(s, r) : void 0; @@ -614,7 +614,7 @@ function Ct(t, e, r) { if (!o) return [t]; for (let i = 0; i < (r ? r - 1 : o.length); i++) { - const c = C(t, o[i], a), h = d(o[i]); + const c = C(t, o[i], a), h = m(o[i]); if (s.push($(t, a, c)), a = c + h, r !== void 0 && s.length === r) break; } @@ -623,10 +623,10 @@ function Ct(t, e, r) { function Pt(t, e, r = 0) { return C(t, e, r) === r; } -function q(t, e = 0, r = d(t) - e) { +function q(t, e = 0, r = m(t) - e) { return Ee(t, e, r); } -function $(t, e, r = d(t)) { +function $(t, e, r = m(t)) { return ye(t, e, r); } function Me(t) { @@ -677,7 +677,7 @@ function J(t, e, r) { return !1; for (var s = {}, n = t.entries(), o = 0, a, i; (a = n.next()) && !a.done; ) { for (var c = e.entries(), h = !1, u = 0; (i = c.next()) && !i.done; ) { - var l = a.value, f = l[0], b = l[1], m = i.value, y = m[0], j = m[1]; + var l = a.value, f = l[0], b = l[1], d = i.value, y = d[0], j = d[1]; !h && !s[u] && (h = r.equals(f, y, o, u, t, e, r) && r.equals(b, j, f, y, t, e, r)) && (s[u] = !0), u++; } if (!h) @@ -755,8 +755,8 @@ function Le(t) { return s(u, l, f); if (b === Set) return i(u, l, f); - var m = Ke(u); - return m === Be ? r(u, l, f) : m === Ue ? a(u, l, f) : m === Ge ? s(u, l, f) : m === ke ? i(u, l, f) : m === He ? typeof u.then != "function" && typeof l.then != "function" && n(u, l, f) : m === _e ? n(u, l, f) : m === Je || m === Ve || m === Fe ? o(u, l, f) : !1; + var d = Ke(u); + return d === Be ? r(u, l, f) : d === Ue ? a(u, l, f) : d === Ge ? s(u, l, f) : d === ke ? i(u, l, f) : d === He ? typeof u.then != "function" && typeof l.then != "function" && n(u, l, f) : d === _e ? n(u, l, f) : d === Je || d === Ve || d === Fe ? o(u, l, f) : !1; }; } function Ze(t) { @@ -1159,7 +1159,7 @@ export { Tt as isSerializable, ne as isString, je as lastIndexOf, - d as length, + m as length, tt as menuDocumentSchema, at as newGuid, qt as normalize, diff --git a/lib/platform-bible-utils/dist/index.js.map b/lib/platform-bible-utils/dist/index.js.map index b12188eb65..d12e38b4be 100644 --- a/lib/platform-bible-utils/dist/index.js.map +++ b/lib/platform-bible-utils/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/mutex.ts","../src/mutex-map.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { Mutex as AsyncMutex } from 'async-mutex';\n\n// Extending Mutex from async-mutex so we can add JSDoc\n\n/**\n * Class that allows calling asynchronous functions multiple times at once while only running one at\n * a time.\n *\n * @example\n *\n * ```typescript\n * const mutex = new Mutex();\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n * ```\n *\n * See [`async-mutex`](https://www.npmjs.com/package/async-mutex) for more information.\n */\nclass Mutex extends AsyncMutex {}\n\nexport default Mutex;\n","import Mutex from './mutex';\n\n/** Map of {@link Mutex}es that automatically (lazily) generates a new {@link Mutex} for any new key */\nclass MutexMap {\n private mutexesByID = new Map();\n\n get(mutexID: string): Mutex {\n let retVal = this.mutexesByID.get(mutexID);\n if (retVal) return retVal;\n\n retVal = new Mutex();\n this.mutexesByID.set(mutexID, retVal);\n return retVal;\n }\n}\n\nexport default MutexMap;\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * Finds the Unicode code point at the given index\n *\n * @param {string} string String to index\n * @param {number} index Position of the character to be returned in range of 0 to -length(string)\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > length(string) || index < -length(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * Always indexes string as a sequence of Unicode code points\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {string} New string consisting of the Unicode code point located at the specified\n * offset, empty string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > length(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to index\n * @param {number} index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns {number | undefined} Non-negative integer representing the code point value of the\n * character at the given index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > length(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * Determines whether a string ends with the characters of this string. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Characters to search for at the end of the string\n * @param {number} [endPosition=length(string)] End position where searchString is expected to be\n * found. Default is `length(string)`\n * @returns {boolean} True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = length(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + length(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * Performs a case-sensitive search to determine if searchString is found in string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString String to search for\n * @param {string} [position=0] Position within the string to start searching for searchString.\n * Default is `0`\n * @returns {boolean} True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * Returns the index of the first occurrence of a given string. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The string to search for\n * @param {number} [position=0] Start of searching. Default is `0`\n * @returns {number} Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * Searches this string and returns the index of the last occurrence of the specified substring.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString Substring to search for\n * @param {number} [position=+Infinity] The method returns the index of the last occurrence of the\n * specified substring at a position less than or equal to position. . Default is `+Infinity`\n * @returns {number} Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(\n string: string,\n searchString: string,\n position: number = +Infinity,\n): number {\n let validatedPosition = position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= length(string)) {\n validatedPosition = length(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, length(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * Returns the length of a string. This function handles Unicode code points instead of UTF-16\n * character codes.\n *\n * @param {string} string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function length(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * Returns the Unicode Normalization Form of this string.\n *\n * @param {string} string The starting string\n * @param {'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'} [form='NFC'] Form specifying the Unicode\n * Normalization Form. Default is `'NFC'`\n * @returns {string} A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within targetLength, it will be truncated. Default is `\" \"`\n * @returns {string} String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string String to add padding too\n * @param {number} targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param {string} [padString=\" \"] The string to pad the current string with. If padString is too\n * long to stay within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\nfunction correctSliceIndex(stringLength: number, index: number) {\n if (index > stringLength) return stringLength;\n if (index < -stringLength) return 0;\n if (index < 0) return index + stringLength;\n return index;\n}\n\n/**\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The starting string\n * @param {number} indexStart The index of the first character to include in the returned substring.\n * @param {number} indexEnd The index of the first character to exclude from the returned substring.\n * @returns {string} A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const stringLength: number = length(string);\n if (\n indexStart > stringLength ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(\n indexStart > 0 &&\n indexStart < stringLength &&\n indexEnd < 0 &&\n indexEnd > -stringLength\n )) ||\n indexEnd < -stringLength ||\n (indexStart < 0 && indexStart > -stringLength && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(stringLength, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param {string} string The string to split\n * @param {string | RegExp} separator The pattern describing where each split should occur\n * @param {number} splitLimit Limit on the number of substrings to be included in the array. Splits\n * the string at each occurrence of specified separator, but stops when limit entries have been\n * placed in the array.\n * @returns {string[] | undefined} An array of strings, split at each point where separator occurs\n * in the starting string. Returns undefined if separator is not found in string.\n */\nexport function split(string: string, separator: string | RegExp, splitLimit?: number): string[] {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !includes(separator.flags, 'g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return [string];\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = length(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate. This function handles Unicode code points instead of UTF-16 character\n * codes.\n *\n * @param {string} string String to search through\n * @param {string} searchString The characters to be searched for at the start of this string.\n * @param {number} [position=0] The start position at which searchString is expected to be found\n * (the index of searchString's first character). Default is `0`\n * @returns {boolean} True if the given characters are found at the beginning of the string,\n * including when searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * Returns a substring by providing start and length. This function handles Unicode code points\n * instead of UTF-16 character codes. This function is not exported because it is considered\n * deprecated, however it is still useful as a local helper function.\n *\n * @param {string} string String to be divided\n * @param {number} [begin=Start of string] Start position. Default is `Start of string`\n * @param {number} [len=String length minus start parameter] Length of result. Default is `String\n * length minus start parameter`. Default is `String length minus start parameter`\n * @returns {string} Substring from starting string\n */\nfunction substr(string: string, begin: number = 0, len: number = length(string) - begin): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * Returns a substring by providing start and end position. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param {string} string String to be divided\n * @param {string} begin Start position\n * @param {number} [end=End of string] End position. Default is `End of string`\n * @returns {string} Substring from starting string\n */\nexport function substring(\n string: string,\n begin?: number | undefined,\n end: number | undefined = length(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * Converts a string to an array of string characters. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param {string} string String to convert to array\n * @returns {string[]} An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","Mutex","AsyncMutex","MutexMap","mutexID","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","stringLength","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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","x_google_ignoreList":[9,10,12]} \ No newline at end of file +{"version":3,"file":"index.js","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/mutex.ts","../src/mutex-map.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { Mutex as AsyncMutex } from 'async-mutex';\n\n// Extending Mutex from async-mutex so we can add JSDoc\n\n/**\n * Class that allows calling asynchronous functions multiple times at once while only running one at\n * a time.\n *\n * @example\n *\n * ```typescript\n * const mutex = new Mutex();\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n * ```\n *\n * See [`async-mutex`](https://www.npmjs.com/package/async-mutex) for more information.\n */\nclass Mutex extends AsyncMutex {}\n\nexport default Mutex;\n","import Mutex from './mutex';\n\n/** Map of {@link Mutex}es that automatically (lazily) generates a new {@link Mutex} for any new key */\nclass MutexMap {\n private mutexesByID = new Map();\n\n get(mutexID: string): Mutex {\n let retVal = this.mutexesByID.get(mutexID);\n if (retVal) return retVal;\n\n retVal = new Mutex();\n this.mutexesByID.set(mutexID, retVal);\n return retVal;\n }\n}\n\nexport default MutexMap;\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * Finds the Unicode code point at the given index. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param string String to index\n * @param index Position of the character to be returned in range of -length(string) to\n * length(string)\n * @returns New string consisting of the Unicode code point located at the specified\n * offset, undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > length(string) || index < -length(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * Returns a new string consisting of the single UTF-16 code unit at the given index.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns New string consisting of the Unicode code point located at the specified\n * offset, empty string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > length(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns Non-negative integer representing the code point value of the\n * character at the given index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > length(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * Determines whether a string ends with the characters of this string. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to search through\n * @param searchString Characters to search for at the end of the string\n * @param endPosition End position where searchString is expected to be\n * found. Default is `length(string)`\n * @returns True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = length(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + length(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * Performs a case-sensitive search to determine if searchString is found in string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to search through\n * @param searchString String to search for\n * @param position Position within the string to start searching for searchString.\n * Default is `0`\n * @returns True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * Returns the index of the first occurrence of a given string. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param string String to search through\n * @param searchString The string to search for\n * @param position Start of searching. Default is `0`\n * @returns Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * Searches this string and returns the index of the last occurrence of the specified substring.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to search through\n * @param searchString Substring to search for\n * @param position The index at which to begin searching. If omitted, the search begins at the end\n * of the string. Default is `undefined`\n * @returns Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(\n string: string,\n searchString: string,\n position?: number,\n): number {\n let validatedPosition = position ? position : length(string);\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= length(string)) {\n validatedPosition = length(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, length(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * Returns the length of a string. This function handles Unicode code points instead of UTF-16\n * character codes.\n *\n * @param string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function length(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * Returns the Unicode Normalization Form of this string.\n *\n * @param string The starting string\n * @param form Form specifying the Unicode Normalization Form. Default is `'NFC'`\n * @returns A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to add padding too\n * @param targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param padString The string to pad the current string with. If padString is too\n * long to stay within targetLength, it will be truncated. Default is `\" \"`\n * @returns String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to add padding too\n * @param targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param padString The string to pad the current string with. If padString is too\n * long to stay within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\nfunction correctSliceIndex(stringLength: number, index: number) {\n if (index > stringLength) return stringLength;\n if (index < -stringLength) return 0;\n if (index < 0) return index + stringLength;\n return index;\n}\n\n/**\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string The starting string\n * @param indexStart The index of the first character to include in the returned substring.\n * @param indexEnd The index of the first character to exclude from the returned substring.\n * @returns A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const stringLength: number = length(string);\n if (\n indexStart > stringLength ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(\n indexStart > 0 &&\n indexStart < stringLength &&\n indexEnd < 0 &&\n indexEnd > -stringLength\n )) ||\n indexEnd < -stringLength ||\n (indexStart < 0 && indexStart > -stringLength && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(stringLength, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param string The string to split\n * @param separator The pattern describing where each split should occur\n * @param splitLimit Limit on the number of substrings to be included in the array. Splits\n * the string at each occurrence of specified separator, but stops when limit entries have been\n * placed in the array.\n * @returns An array of strings, split at each point where separator occurs\n * in the starting string. Returns undefined if separator is not found in string.\n */\nexport function split(string: string, separator: string | RegExp, splitLimit?: number): string[] {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !includes(separator.flags, 'g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return [string];\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = length(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate. This function handles Unicode code points instead of UTF-16 character\n * codes.\n *\n * @param string String to search through\n * @param searchString The characters to be searched for at the start of this string.\n * @param position The start position at which searchString is expected to be found\n * (the index of searchString's first character). Default is `0`\n * @returns True if the given characters are found at the beginning of the string,\n * including when searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * Returns a substring by providing start and length. This function handles Unicode code points\n * instead of UTF-16 character codes. This function is not exported because it is considered\n * deprecated, however it is still useful as a local helper function.\n *\n * @param string String to be divided\n * @param begin Start position. Default is `Start of string`\n * @param len Length of result. Default is `String\n * length minus start parameter`. Default is `String length minus start parameter`\n * @returns Substring from starting string\n */\nfunction substr(string: string, begin: number = 0, len: number = length(string) - begin): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * Returns a substring by providing start and end position. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param string String to be divided\n * @param begin Start position\n * @param end End position. Default is `End of string`\n * @returns Substring from starting string\n */\nexport function substring(\n string: string,\n begin: number,\n end: number = length(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * Converts a string to an array of string characters. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param string String to convert to array\n * @returns An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","Mutex","AsyncMutex","MutexMap","mutexID","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","stringLength","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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","x_google_ignoreList":[9,10,12]} \ No newline at end of file diff --git a/lib/platform-bible-utils/src/string-util.test.ts b/lib/platform-bible-utils/src/string-util.test.ts index b96c0f1a50..4a74c7a43e 100644 --- a/lib/platform-bible-utils/src/string-util.test.ts +++ b/lib/platform-bible-utils/src/string-util.test.ts @@ -50,6 +50,11 @@ describe('at', () => { const result = at(LONG_SURROGATE_PAIRS_STRING, length(LONG_SURROGATE_PAIRS_STRING) + 10); expect(result).toEqual(undefined); }); + + test('at with index smaller than -length returns undefined', () => { + const result = at(LONG_SURROGATE_PAIRS_STRING, -length(LONG_SURROGATE_PAIRS_STRING) - 10); + expect(result).toEqual(undefined); + }); }); describe('charAt', () => { @@ -382,7 +387,7 @@ describe('substring', () => { }); test('substring with end', () => { - const result = substring(LONG_SURROGATE_PAIRS_STRING, undefined, POS_FIRST_PIZZA); + const result = substring(LONG_SURROGATE_PAIRS_STRING, 0, POS_FIRST_PIZZA); expect(result).toEqual('Look𐐷At🦄All😎These😁Awesome'); }); diff --git a/lib/platform-bible-utils/src/string-util.ts b/lib/platform-bible-utils/src/string-util.ts index 4b6e4c4c5e..30a982e2b7 100644 --- a/lib/platform-bible-utils/src/string-util.ts +++ b/lib/platform-bible-utils/src/string-util.ts @@ -8,12 +8,14 @@ import { } from 'stringz'; /** - * Finds the Unicode code point at the given index + * Finds the Unicode code point at the given index. This function handles Unicode code points + * instead of UTF-16 character codes. * - * @param {string} string String to index - * @param {number} index Position of the character to be returned in range of 0 to -length(string) - * @returns {string} New string consisting of the Unicode code point located at the specified - * offset, undefined if index is out of bounds + * @param string String to index + * @param index Position of the character to be returned in range of -length(string) to + * length(string) + * @returns New string consisting of the Unicode code point located at the specified offset, + * undefined if index is out of bounds */ export function at(string: string, index: number): string | undefined { if (index > length(string) || index < -length(string)) return undefined; @@ -21,13 +23,14 @@ export function at(string: string, index: number): string | undefined { } /** - * Always indexes string as a sequence of Unicode code points + * Returns a new string consisting of the single UTF-16 code unit at the given index. This function + * handles Unicode code points instead of UTF-16 character codes. * * @param string String to index * @param index Position of the string character to be returned, in the range of 0 to * length(string)-1 - * @returns {string} New string consisting of the Unicode code point located at the specified - * offset, empty string if index is out of bounds + * @returns New string consisting of the Unicode code point located at the specified offset, empty + * string if index is out of bounds */ export function charAt(string: string, index: number): string { if (index < 0 || index > length(string) - 1) return ''; @@ -38,11 +41,11 @@ export function charAt(string: string, index: number): string { * Returns a non-negative integer that is the Unicode code point value of the character starting at * the given index. This function handles Unicode code points instead of UTF-16 character codes. * - * @param {string} string String to index - * @param {number} index Position of the string character to be returned, in the range of 0 to + * @param string String to index + * @param index Position of the string character to be returned, in the range of 0 to * length(string)-1 - * @returns {number | undefined} Non-negative integer representing the code point value of the - * character at the given index, or undefined if there is no element at that position + * @returns Non-negative integer representing the code point value of the character at the given + * index, or undefined if there is no element at that position */ export function codePointAt(string: string, index: number): number | undefined { if (index < 0 || index > length(string) - 1) return undefined; @@ -53,11 +56,11 @@ export function codePointAt(string: string, index: number): number | undefined { * Determines whether a string ends with the characters of this string. This function handles * Unicode code points instead of UTF-16 character codes. * - * @param {string} string String to search through - * @param {string} searchString Characters to search for at the end of the string - * @param {number} [endPosition=length(string)] End position where searchString is expected to be - * found. Default is `length(string)` - * @returns {boolean} True if it ends with searchString, false if it does not + * @param string String to search through + * @param searchString Characters to search for at the end of the string + * @param endPosition End position where searchString is expected to be found. Default is + * `length(string)` + * @returns True if it ends with searchString, false if it does not */ export function endsWith( string: string, @@ -74,11 +77,10 @@ export function endsWith( * Performs a case-sensitive search to determine if searchString is found in string. This function * handles Unicode code points instead of UTF-16 character codes. * - * @param {string} string String to search through - * @param {string} searchString String to search for - * @param {string} [position=0] Position within the string to start searching for searchString. - * Default is `0` - * @returns {boolean} True if search string is found, false if it is not + * @param string String to search through + * @param searchString String to search for + * @param position Position within the string to start searching for searchString. Default is `0` + * @returns True if search string is found, false if it is not */ export function includes(string: string, searchString: string, position: number = 0): boolean { const partialString = substring(string, position); @@ -91,10 +93,10 @@ export function includes(string: string, searchString: string, position: number * Returns the index of the first occurrence of a given string. This function handles Unicode code * points instead of UTF-16 character codes. * - * @param {string} string String to search through - * @param {string} searchString The string to search for - * @param {number} [position=0] Start of searching. Default is `0` - * @returns {number} Index of the first occurrence of a given string + * @param string String to search through + * @param searchString The string to search for + * @param position Start of searching. Default is `0` + * @returns Index of the first occurrence of a given string */ export function indexOf( string: string, @@ -108,18 +110,14 @@ export function indexOf( * Searches this string and returns the index of the last occurrence of the specified substring. * This function handles Unicode code points instead of UTF-16 character codes. * - * @param {string} string String to search through - * @param {string} searchString Substring to search for - * @param {number} [position=+Infinity] The method returns the index of the last occurrence of the - * specified substring at a position less than or equal to position. . Default is `+Infinity` - * @returns {number} Index of the last occurrence of searchString found, or -1 if not found. + * @param string String to search through + * @param searchString Substring to search for + * @param position The index at which to begin searching. If omitted, the search begins at the end + * of the string. Default is `undefined` + * @returns Index of the last occurrence of searchString found, or -1 if not found. */ -export function lastIndexOf( - string: string, - searchString: string, - position: number = +Infinity, -): number { - let validatedPosition = position; +export function lastIndexOf(string: string, searchString: string, position?: number): number { + let validatedPosition = position === undefined ? length(string) : position; if (validatedPosition < 0) { validatedPosition = 0; @@ -140,7 +138,7 @@ export function lastIndexOf( * Returns the length of a string. This function handles Unicode code points instead of UTF-16 * character codes. * - * @param {string} string String to return the length for + * @param string String to return the length for * @returns Number that is length of the starting string */ export function length(string: string): number { @@ -150,10 +148,9 @@ export function length(string: string): number { /** * Returns the Unicode Normalization Form of this string. * - * @param {string} string The starting string - * @param {'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'} [form='NFC'] Form specifying the Unicode - * Normalization Form. Default is `'NFC'` - * @returns {string} A string containing the Unicode Normalization Form of the given string. + * @param string The starting string + * @param form Form specifying the Unicode Normalization Form. Default is `'NFC'` + * @returns A string containing the Unicode Normalization Form of the given string. */ export function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string { const upperCaseForm = form.toUpperCase(); @@ -168,12 +165,12 @@ export function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' * reaches the given length. The padding is applied from the end of this string. This function * handles Unicode code points instead of UTF-16 character codes. * - * @param {string} string String to add padding too - * @param {number} targetLength The length of the resulting string once the starting string has been - * padded. If value is less than or equal to length(string), then string is returned as is. - * @param {string} [padString=" "] The string to pad the current string with. If padString is too - * long to stay within targetLength, it will be truncated. Default is `" "` - * @returns {string} String with appropriate padding at the end + * @param string String to add padding too + * @param targetLength The length of the resulting string once the starting string has been padded. + * If value is less than or equal to length(string), then string is returned as is. + * @param padString The string to pad the current string with. If padString is too long to stay + * within targetLength, it will be truncated. Default is `" "` + * @returns String with appropriate padding at the end */ // Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59 export function padEnd(string: string, targetLength: number, padString: string = ' '): string { @@ -186,11 +183,11 @@ export function padEnd(string: string, targetLength: number, padString: string = * reaches the given length. The padding is applied from the start of this string. This function * handles Unicode code points instead of UTF-16 character codes. * - * @param {string} string String to add padding too - * @param {number} targetLength The length of the resulting string once the starting string has been - * padded. If value is less than or equal to length(string), then string is returned as is. - * @param {string} [padString=" "] The string to pad the current string with. If padString is too - * long to stay within the targetLength, it will be truncated from the end. Default is `" "` + * @param string String to add padding too + * @param targetLength The length of the resulting string once the starting string has been padded. + * If value is less than or equal to length(string), then string is returned as is. + * @param padString The string to pad the current string with. If padString is too long to stay + * within the targetLength, it will be truncated from the end. Default is `" "` * @returns String with of specified targetLength with padString applied from the start */ // Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59 @@ -210,10 +207,10 @@ function correctSliceIndex(stringLength: number, index: number) { * Extracts a section of this string and returns it as a new string, without modifying the original * string. This function handles Unicode code points instead of UTF-16 character codes. * - * @param {string} string The starting string - * @param {number} indexStart The index of the first character to include in the returned substring. - * @param {number} indexEnd The index of the first character to exclude from the returned substring. - * @returns {string} A new string containing the extracted section of the string. + * @param string The starting string + * @param indexStart The index of the first character to include in the returned substring. + * @param indexEnd The index of the first character to exclude from the returned substring. + * @returns A new string containing the extracted section of the string. */ export function slice(string: string, indexStart: number, indexEnd?: number): string { const stringLength: number = length(string); @@ -243,13 +240,13 @@ export function slice(string: string, indexStart: number, indexEnd?: number): st * pattern, puts these substrings into an array, and returns the array. This function handles * Unicode code points instead of UTF-16 character codes. * - * @param {string} string The string to split - * @param {string | RegExp} separator The pattern describing where each split should occur - * @param {number} splitLimit Limit on the number of substrings to be included in the array. Splits - * the string at each occurrence of specified separator, but stops when limit entries have been - * placed in the array. - * @returns {string[] | undefined} An array of strings, split at each point where separator occurs - * in the starting string. Returns undefined if separator is not found in string. + * @param string The string to split + * @param separator The pattern describing where each split should occur + * @param splitLimit Limit on the number of substrings to be included in the array. Splits the + * string at each occurrence of specified separator, but stops when limit entries have been placed + * in the array. + * @returns An array of strings, split at each point where separator occurs in the starting string. + * Returns undefined if separator is not found in string. */ export function split(string: string, separator: string | RegExp, splitLimit?: number): string[] { const result: string[] = []; @@ -296,12 +293,12 @@ export function split(string: string, separator: string | RegExp, splitLimit?: n * false as appropriate. This function handles Unicode code points instead of UTF-16 character * codes. * - * @param {string} string String to search through - * @param {string} searchString The characters to be searched for at the start of this string. - * @param {number} [position=0] The start position at which searchString is expected to be found - * (the index of searchString's first character). Default is `0` - * @returns {boolean} True if the given characters are found at the beginning of the string, - * including when searchString is an empty string; otherwise, false. + * @param string String to search through + * @param searchString The characters to be searched for at the start of this string. + * @param position The start position at which searchString is expected to be found (the index of + * searchString's first character). Default is `0` + * @returns True if the given characters are found at the beginning of the string, including when + * searchString is an empty string; otherwise, false. */ export function startsWith(string: string, searchString: string, position: number = 0): boolean { const indexOfSearchString = indexOf(string, searchString, position); @@ -314,11 +311,11 @@ export function startsWith(string: string, searchString: string, position: numbe * instead of UTF-16 character codes. This function is not exported because it is considered * deprecated, however it is still useful as a local helper function. * - * @param {string} string String to be divided - * @param {number} [begin=Start of string] Start position. Default is `Start of string` - * @param {number} [len=String length minus start parameter] Length of result. Default is `String - * length minus start parameter`. Default is `String length minus start parameter` - * @returns {string} Substring from starting string + * @param string String to be divided + * @param begin Start position. Default is `Start of string` + * @param len Length of result. Default is `String length minus start parameter`. Default is `String + * length minus start parameter` + * @returns Substring from starting string */ function substr(string: string, begin: number = 0, len: number = length(string) - begin): string { return stringzSubstr(string, begin, len); @@ -328,16 +325,12 @@ function substr(string: string, begin: number = 0, len: number = length(string) * Returns a substring by providing start and end position. This function handles Unicode code * points instead of UTF-16 character codes. * - * @param {string} string String to be divided - * @param {string} begin Start position - * @param {number} [end=End of string] End position. Default is `End of string` - * @returns {string} Substring from starting string + * @param string String to be divided + * @param begin Start position + * @param end End position. Default is `End of string` + * @returns Substring from starting string */ -export function substring( - string: string, - begin?: number | undefined, - end: number | undefined = length(string), -): string { +export function substring(string: string, begin: number, end: number = length(string)): string { return stringzSubstring(string, begin, end); } @@ -345,8 +338,8 @@ export function substring( * Converts a string to an array of string characters. This function handles Unicode code points * instead of UTF-16 character codes. * - * @param {string} string String to convert to array - * @returns {string[]} An array of characters from the starting string + * @param string String to convert to array + * @returns An array of characters from the starting string */ export function toArray(string: string): string[] { return stringzToArray(string); From a6d19784b144ff10b4b76f6f3bf70fe13a2bcd6c Mon Sep 17 00:00:00 2001 From: Rolf Heij Date: Tue, 20 Feb 2024 16:00:54 -0500 Subject: [PATCH 20/22] Update comments to mention that the functions mirrir the standard string object function --- lib/platform-bible-utils/src/string-util.ts | 99 ++++++++++++++------- 1 file changed, 69 insertions(+), 30 deletions(-) diff --git a/lib/platform-bible-utils/src/string-util.ts b/lib/platform-bible-utils/src/string-util.ts index 30a982e2b7..2652f52d07 100644 --- a/lib/platform-bible-utils/src/string-util.ts +++ b/lib/platform-bible-utils/src/string-util.ts @@ -8,8 +8,10 @@ import { } from 'stringz'; /** - * Finds the Unicode code point at the given index. This function handles Unicode code points - * instead of UTF-16 character codes. + * This function mirrors the `at` function from the JavaScript Standard String object. + * It handles Unicode code points instead of UTF-16 character codes. + * + * Finds the Unicode code point at the given index. * * @param string String to index * @param index Position of the character to be returned in range of -length(string) to @@ -23,8 +25,10 @@ export function at(string: string, index: number): string | undefined { } /** - * Returns a new string consisting of the single UTF-16 code unit at the given index. This function - * handles Unicode code points instead of UTF-16 character codes. + * This function mirrors the `charAt` function from the JavaScript Standard String object. + * It handles Unicode code points instead of UTF-16 character codes. + * + * Returns a new string consisting of the single UTF-16 code unit at the given index. * * @param string String to index * @param index Position of the string character to be returned, in the range of 0 to @@ -38,8 +42,11 @@ export function charAt(string: string, index: number): string { } /** + * This function mirrors the `codePointAt` function from the JavaScript Standard String object. + * It handles Unicode code points instead of UTF-16 character codes. + * * Returns a non-negative integer that is the Unicode code point value of the character starting at - * the given index. This function handles Unicode code points instead of UTF-16 character codes. + * the given index. * * @param string String to index * @param index Position of the string character to be returned, in the range of 0 to @@ -53,8 +60,10 @@ export function codePointAt(string: string, index: number): number | undefined { } /** - * Determines whether a string ends with the characters of this string. This function handles - * Unicode code points instead of UTF-16 character codes. + * This function mirrors the `endsWith` function from the JavaScript Standard String object. + * It handles Unicode code points instead of UTF-16 character codes. + * + * Determines whether a string ends with the characters of this string. * * @param string String to search through * @param searchString Characters to search for at the end of the string @@ -74,8 +83,10 @@ export function endsWith( } /** - * Performs a case-sensitive search to determine if searchString is found in string. This function - * handles Unicode code points instead of UTF-16 character codes. + * This function mirrors the `includes` function from the JavaScript Standard String object. + * It handles Unicode code points instead of UTF-16 character codes. + * + * Performs a case-sensitive search to determine if searchString is found in string. * * @param string String to search through * @param searchString String to search for @@ -90,8 +101,10 @@ export function includes(string: string, searchString: string, position: number } /** - * Returns the index of the first occurrence of a given string. This function handles Unicode code - * points instead of UTF-16 character codes. + * This function mirrors the `indexOf` function from the JavaScript Standard String object. + * It handles Unicode code points instead of UTF-16 character codes. + * + * Returns the index of the first occurrence of a given string. * * @param string String to search through * @param searchString The string to search for @@ -107,8 +120,10 @@ export function indexOf( } /** + * This function mirrors the `lastIndexOf` function from the JavaScript Standard String object. + * It handles Unicode code points instead of UTF-16 character codes. + * * Searches this string and returns the index of the last occurrence of the specified substring. - * This function handles Unicode code points instead of UTF-16 character codes. * * @param string String to search through * @param searchString Substring to search for @@ -135,8 +150,10 @@ export function lastIndexOf(string: string, searchString: string, position?: num } /** - * Returns the length of a string. This function handles Unicode code points instead of UTF-16 - * character codes. + * This function mirrors the `length` function from the JavaScript Standard String object. + * It handles Unicode code points instead of UTF-16 character codes. + * + * Returns the length of a string. * * @param string String to return the length for * @returns Number that is length of the starting string @@ -146,6 +163,9 @@ export function length(string: string): number { } /** + * This function mirrors the `normalize` function from the JavaScript Standard String object. + * It handles Unicode code points instead of UTF-16 character codes. + * * Returns the Unicode Normalization Form of this string. * * @param string The starting string @@ -161,9 +181,11 @@ export function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' } /** + * This function mirrors the `padEnd` function from the JavaScript Standard String object. + * It handles Unicode code points instead of UTF-16 character codes. + * * Pads this string with another string (multiple times, if needed) until the resulting string - * reaches the given length. The padding is applied from the end of this string. This function - * handles Unicode code points instead of UTF-16 character codes. + * reaches the given length. The padding is applied from the end of this string. * * @param string String to add padding too * @param targetLength The length of the resulting string once the starting string has been padded. @@ -179,9 +201,11 @@ export function padEnd(string: string, targetLength: number, padString: string = } /** + * This function mirrors the `padStart` function from the JavaScript Standard String object. + * It handles Unicode code points instead of UTF-16 character codes. + * * Pads this string with another string (multiple times, if needed) until the resulting string - * reaches the given length. The padding is applied from the start of this string. This function - * handles Unicode code points instead of UTF-16 character codes. + * reaches the given length. The padding is applied from the start of this string. * * @param string String to add padding too * @param targetLength The length of the resulting string once the starting string has been padded. @@ -196,6 +220,8 @@ export function padStart(string: string, targetLength: number, padString: string return stringzLimit(string, targetLength, padString, 'left'); } +// This is a helper function that performs a correction on the slice index to make sure it +// cannot go out of bounds function correctSliceIndex(stringLength: number, index: number) { if (index > stringLength) return stringLength; if (index < -stringLength) return 0; @@ -204,8 +230,11 @@ function correctSliceIndex(stringLength: number, index: number) { } /** + * This function mirrors the `slice` function from the JavaScript Standard String object. + * It handles Unicode code points instead of UTF-16 character codes. + * * Extracts a section of this string and returns it as a new string, without modifying the original - * string. This function handles Unicode code points instead of UTF-16 character codes. + * string. * * @param string The starting string * @param indexStart The index of the first character to include in the returned substring. @@ -236,9 +265,11 @@ export function slice(string: string, indexStart: number, indexEnd?: number): st } /** + * This function mirrors the `split` function from the JavaScript Standard String object. + * It handles Unicode code points instead of UTF-16 character codes. + * * Takes a pattern and divides the string into an ordered list of substrings by searching for the - * pattern, puts these substrings into an array, and returns the array. This function handles - * Unicode code points instead of UTF-16 character codes. + * pattern, puts these substrings into an array, and returns the array. * * @param string The string to split * @param separator The pattern describing where each split should occur @@ -289,9 +320,11 @@ export function split(string: string, separator: string | RegExp, splitLimit?: n } /** + * This function mirrors the `startsWith` function from the JavaScript Standard String object. + * It handles Unicode code points instead of UTF-16 character codes. + * * Determines whether the string begins with the characters of a specified string, returning true or - * false as appropriate. This function handles Unicode code points instead of UTF-16 character - * codes. + * false as appropriate. * * @param string String to search through * @param searchString The characters to be searched for at the start of this string. @@ -307,9 +340,11 @@ export function startsWith(string: string, searchString: string, position: numbe } /** - * Returns a substring by providing start and length. This function handles Unicode code points - * instead of UTF-16 character codes. This function is not exported because it is considered - * deprecated, however it is still useful as a local helper function. + * This function mirrors the `substr` function from the JavaScript Standard String object. + * It handles Unicode code points instead of UTF-16 character codes. + * + * Returns a substring by providing start and length. This function is not exported because it is + * considered deprecated, however it is still useful as a local helper function. * * @param string String to be divided * @param begin Start position. Default is `Start of string` @@ -322,8 +357,10 @@ function substr(string: string, begin: number = 0, len: number = length(string) } /** - * Returns a substring by providing start and end position. This function handles Unicode code - * points instead of UTF-16 character codes. + * This function mirrors the `substring` function from the JavaScript Standard String object. + * It handles Unicode code points instead of UTF-16 character codes. + * + * Returns a substring by providing start and end position. * * @param string String to be divided * @param begin Start position @@ -335,8 +372,10 @@ export function substring(string: string, begin: number, end: number = length(st } /** - * Converts a string to an array of string characters. This function handles Unicode code points - * instead of UTF-16 character codes. + * This function mirrors the `toArray` function from the JavaScript Standard String object. + * It handles Unicode code points instead of UTF-16 character codes. + * + * Converts a string to an array of string characters. * * @param string String to convert to array * @returns An array of characters from the starting string From c0d36b846dd446dbad008330f65eb3212321e952 Mon Sep 17 00:00:00 2001 From: Rolf Heij Date: Tue, 20 Feb 2024 17:06:13 -0500 Subject: [PATCH 21/22] Fix comment --- lib/platform-bible-utils/src/string-util.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/platform-bible-utils/src/string-util.ts b/lib/platform-bible-utils/src/string-util.ts index 2652f52d07..5f87a8fb8c 100644 --- a/lib/platform-bible-utils/src/string-util.ts +++ b/lib/platform-bible-utils/src/string-util.ts @@ -28,7 +28,7 @@ export function at(string: string, index: number): string | undefined { * This function mirrors the `charAt` function from the JavaScript Standard String object. * It handles Unicode code points instead of UTF-16 character codes. * - * Returns a new string consisting of the single UTF-16 code unit at the given index. + * Returns a new string consisting of the single unicode code point at the given index. * * @param string String to index * @param index Position of the string character to be returned, in the range of 0 to From 36479d8e713dcaa9b90d2c2d78d59aa302d05f8d Mon Sep 17 00:00:00 2001 From: Rolf Heij Date: Wed, 21 Feb 2024 11:52:36 -0500 Subject: [PATCH 22/22] rename length -> stringLength --- lib/platform-bible-utils/dist/index.cjs | 2 +- lib/platform-bible-utils/dist/index.cjs.map | 2 +- lib/platform-bible-utils/dist/index.d.ts | 153 +++++++++++------- lib/platform-bible-utils/dist/index.js | 4 +- lib/platform-bible-utils/dist/index.js.map | 2 +- lib/platform-bible-utils/src/index.ts | 2 +- .../src/string-util.test.ts | 8 +- lib/platform-bible-utils/src/string-util.ts | 134 +++++++-------- .../services/extension-storage.service.ts | 4 +- .../services/extension.service.ts | 4 +- .../extension-asset-protocol.service.ts | 6 +- src/node/models/execution-token.model.ts | 4 +- src/node/services/execution-token.service.ts | 6 +- src/shared/models/data-provider.model.ts | 4 +- src/shared/services/network.service.ts | 4 +- src/shared/utils/util.ts | 6 +- 16 files changed, 193 insertions(+), 152 deletions(-) diff --git a/lib/platform-bible-utils/dist/index.cjs b/lib/platform-bible-utils/dist/index.cjs index 4d9f0e5ce6..022f8e2ce8 100644 --- a/lib/platform-bible-utils/dist/index.cjs +++ b/lib/platform-bible-utils/dist/index.cjs @@ -1,2 +1,2 @@ -"use strict";var me=Object.defineProperty;var de=(t,e,r)=>e in t?me(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var p=(t,e,r)=>(de(t,typeof e!="symbol"?e+"":e,r),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const be=require("async-mutex");class ge{constructor(e,r=1e4){p(this,"variableName");p(this,"promiseToValue");p(this,"resolver");p(this,"rejecter");this.variableName=e,this.promiseToValue=new Promise((s,n)=>{this.resolver=s,this.rejecter=n}),r>0&&setTimeout(()=>{this.rejecter&&(this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`),this.complete())},r),Object.seal(this)}get promise(){return this.promiseToValue}get hasSettled(){return Object.isFrozen(this)}resolveToValue(e,r=!1){if(this.resolver)console.debug(`${this.variableName} is being resolved now`),this.resolver(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent resolution of ${this.variableName}`)}}rejectWithReason(e,r=!1){if(this.rejecter)console.debug(`${this.variableName} is being rejected now`),this.rejecter(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent rejection of ${this.variableName}`)}}complete(){this.resolver=void 0,this.rejecter=void 0,Object.freeze(this)}}function Ne(){return"00-0-4-1-000".replace(/[^-]/g,t=>((Math.random()+~~t)*65536>>t).toString(16).padStart(4,"0"))}function F(t){return typeof t=="string"||t instanceof String}function E(t){return JSON.parse(JSON.stringify(t))}function ve(t,e=300){if(F(t))throw new Error("Tried to debounce a string! Could be XSS");let r;return(...s)=>{clearTimeout(r),r=setTimeout(()=>t(...s),e)}}function ye(t,e,r){const s=new Map;return t.forEach(n=>{const o=e(n),a=s.get(o),i=r?r(n,o):n;a?a.push(i):s.set(o,[i])}),s}function we(t){return typeof t=="object"&&t!==null&&"message"in t&&typeof t.message=="string"}function Ee(t){if(we(t))return t;try{return new Error(JSON.stringify(t))}catch{return new Error(String(t))}}function Oe(t){return Ee(t).message}function H(t){return new Promise(e=>setTimeout(e,t))}function $e(t,e){const r=H(e).then(()=>{});return Promise.any([r,t()])}function Ae(t,e="obj"){const r=new Set;Object.getOwnPropertyNames(t).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e} due to error: ${o}`)}});let s=Object.getPrototypeOf(t);for(;s&&Object.getPrototypeOf(s);)Object.getOwnPropertyNames(s).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e}'s prototype due to error: ${o}`)}}),s=Object.getPrototypeOf(s);return r}function Se(t,e={}){return new Proxy(e,{get(r,s){return s in r?r[s]:async(...n)=>(await t())[s](...n)}})}class Me{constructor(e,r){p(this,"baseDocument");p(this,"contributions",new Map);p(this,"latestOutput");p(this,"options");this.baseDocument=e,this.options=r,this.updateBaseDocument(e)}updateBaseDocument(e){return this.validateStartingDocument(e),this.baseDocument=this.options.copyDocuments?E(e):e,this.rebuild()}addOrUpdateContribution(e,r){this.validateContribution(e,r);const s=this.contributions.get(e),n=this.options.copyDocuments&&r?E(r):r;this.contributions.set(e,n);try{return this.rebuild()}catch(o){throw s?this.contributions.set(e,s):this.contributions.delete(e),new Error(`Error when setting the document named ${e}: ${o}`)}}deleteContribution(e){const r=this.contributions.get(e);if(!r)throw new Error("{documentKey} does not exist");this.contributions.delete(e);try{return this.rebuild()}catch(s){throw this.contributions.set(e,r),new Error(`Error when deleting the document named ${e}: ${s}`)}}rebuild(){if(this.contributions.size===0){let r=E(this.baseDocument);return r=this.transformFinalOutput(r),this.validateOutput(r),this.latestOutput=r,this.latestOutput}let e=this.baseDocument;return this.contributions.forEach(r=>{e=k(e,r,this.options.ignoreDuplicateProperties),this.validateOutput(e)}),e=this.transformFinalOutput(e),this.validateOutput(e),this.latestOutput=e,this.latestOutput}}function qe(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||Array.isArray(r))&&(e=!1)}),e}function je(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||!Array.isArray(r))&&(e=!1)}),e}function k(t,e,r){const s=E(t);return e&&Object.keys(e).forEach(n=>{if(Object.hasOwn(t,n)){if(qe(t[n],e[n]))s[n]=k(t[n],e[n],r);else if(je(t[n],e[n]))s[n]=s[n].concat(e[n]);else if(!r)throw new Error(`Cannot merge objects: key "${n}" already exists in the target object`)}else s[n]=e[n]}),s}class Ce{constructor(e="Anonymous"){p(this,"unsubscribers",new Set);this.name=e}add(...e){e.forEach(r=>{"dispose"in r?this.unsubscribers.add(r.dispose):this.unsubscribers.add(r)})}async runAllUnsubscribers(){const e=[...this.unsubscribers].map(s=>s()),r=await Promise.all(e);return this.unsubscribers.clear(),r.every((s,n)=>(s||console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${n} failed!`),s))}}class Pe{constructor(){p(this,"subscribe",this.event);p(this,"subscriptions");p(this,"lazyEvent");p(this,"isDisposed",!1);p(this,"dispose",()=>this.disposeFn());p(this,"emit",e=>{this.emitFn(e)})}get event(){return this.assertNotDisposed(),this.lazyEvent||(this.lazyEvent=e=>{if(!e||typeof e!="function")throw new Error("Event handler callback must be a function!");return this.subscriptions||(this.subscriptions=[]),this.subscriptions.push(e),()=>{if(!this.subscriptions)return!1;const r=this.subscriptions.indexOf(e);return r<0?!1:(this.subscriptions.splice(r,1),!0)}}),this.lazyEvent}emitFn(e){var r;this.assertNotDisposed(),(r=this.subscriptions)==null||r.forEach(s=>s(e))}assertNotDisposed(){if(this.isDisposed)throw new Error("Emitter is disposed")}disposeFn(){return this.assertNotDisposed(),this.isDisposed=!0,this.subscriptions=void 0,this.lazyEvent=void 0,Promise.resolve(!0)}}class W extends be.Mutex{}class Te{constructor(){p(this,"mutexesByID",new Map)}get(e){let r=this.mutexesByID.get(e);return r||(r=new W,this.mutexesByID.set(e,r),r)}}const K=[{shortName:"ERR",fullNames:["ERROR"],chapters:-1},{shortName:"GEN",fullNames:["Genesis"],chapters:50},{shortName:"EXO",fullNames:["Exodus"],chapters:40},{shortName:"LEV",fullNames:["Leviticus"],chapters:27},{shortName:"NUM",fullNames:["Numbers"],chapters:36},{shortName:"DEU",fullNames:["Deuteronomy"],chapters:34},{shortName:"JOS",fullNames:["Joshua"],chapters:24},{shortName:"JDG",fullNames:["Judges"],chapters:21},{shortName:"RUT",fullNames:["Ruth"],chapters:4},{shortName:"1SA",fullNames:["1 Samuel"],chapters:31},{shortName:"2SA",fullNames:["2 Samuel"],chapters:24},{shortName:"1KI",fullNames:["1 Kings"],chapters:22},{shortName:"2KI",fullNames:["2 Kings"],chapters:25},{shortName:"1CH",fullNames:["1 Chronicles"],chapters:29},{shortName:"2CH",fullNames:["2 Chronicles"],chapters:36},{shortName:"EZR",fullNames:["Ezra"],chapters:10},{shortName:"NEH",fullNames:["Nehemiah"],chapters:13},{shortName:"EST",fullNames:["Esther"],chapters:10},{shortName:"JOB",fullNames:["Job"],chapters:42},{shortName:"PSA",fullNames:["Psalm","Psalms"],chapters:150},{shortName:"PRO",fullNames:["Proverbs"],chapters:31},{shortName:"ECC",fullNames:["Ecclesiastes"],chapters:12},{shortName:"SNG",fullNames:["Song of Solomon","Song of Songs"],chapters:8},{shortName:"ISA",fullNames:["Isaiah"],chapters:66},{shortName:"JER",fullNames:["Jeremiah"],chapters:52},{shortName:"LAM",fullNames:["Lamentations"],chapters:5},{shortName:"EZK",fullNames:["Ezekiel"],chapters:48},{shortName:"DAN",fullNames:["Daniel"],chapters:12},{shortName:"HOS",fullNames:["Hosea"],chapters:14},{shortName:"JOL",fullNames:["Joel"],chapters:3},{shortName:"AMO",fullNames:["Amos"],chapters:9},{shortName:"OBA",fullNames:["Obadiah"],chapters:1},{shortName:"JON",fullNames:["Jonah"],chapters:4},{shortName:"MIC",fullNames:["Micah"],chapters:7},{shortName:"NAM",fullNames:["Nahum"],chapters:3},{shortName:"HAB",fullNames:["Habakkuk"],chapters:3},{shortName:"ZEP",fullNames:["Zephaniah"],chapters:3},{shortName:"HAG",fullNames:["Haggai"],chapters:2},{shortName:"ZEC",fullNames:["Zechariah"],chapters:14},{shortName:"MAL",fullNames:["Malachi"],chapters:4},{shortName:"MAT",fullNames:["Matthew"],chapters:28},{shortName:"MRK",fullNames:["Mark"],chapters:16},{shortName:"LUK",fullNames:["Luke"],chapters:24},{shortName:"JHN",fullNames:["John"],chapters:21},{shortName:"ACT",fullNames:["Acts"],chapters:28},{shortName:"ROM",fullNames:["Romans"],chapters:16},{shortName:"1CO",fullNames:["1 Corinthians"],chapters:16},{shortName:"2CO",fullNames:["2 Corinthians"],chapters:13},{shortName:"GAL",fullNames:["Galatians"],chapters:6},{shortName:"EPH",fullNames:["Ephesians"],chapters:6},{shortName:"PHP",fullNames:["Philippians"],chapters:4},{shortName:"COL",fullNames:["Colossians"],chapters:4},{shortName:"1TH",fullNames:["1 Thessalonians"],chapters:5},{shortName:"2TH",fullNames:["2 Thessalonians"],chapters:3},{shortName:"1TI",fullNames:["1 Timothy"],chapters:6},{shortName:"2TI",fullNames:["2 Timothy"],chapters:4},{shortName:"TIT",fullNames:["Titus"],chapters:3},{shortName:"PHM",fullNames:["Philemon"],chapters:1},{shortName:"HEB",fullNames:["Hebrews"],chapters:13},{shortName:"JAS",fullNames:["James"],chapters:5},{shortName:"1PE",fullNames:["1 Peter"],chapters:5},{shortName:"2PE",fullNames:["2 Peter"],chapters:3},{shortName:"1JN",fullNames:["1 John"],chapters:5},{shortName:"2JN",fullNames:["2 John"],chapters:1},{shortName:"3JN",fullNames:["3 John"],chapters:1},{shortName:"JUD",fullNames:["Jude"],chapters:1},{shortName:"REV",fullNames:["Revelation"],chapters:22}],L=1,Z=K.length-1,X=1,Q=1,Y=t=>{var e;return((e=K[t])==null?void 0:e.chapters)??-1},Re=(t,e)=>({bookNum:Math.max(L,Math.min(t.bookNum+e,Z)),chapterNum:1,verseNum:1}),De=(t,e)=>({...t,chapterNum:Math.min(Math.max(X,t.chapterNum+e),Y(t.bookNum)),verseNum:1}),Ie=(t,e)=>({...t,verseNum:Math.max(Q,t.verseNum+e)}),xe=t=>(...e)=>t.map(s=>s(...e)).every(s=>s),_e=t=>async(...e)=>{const r=t.map(async s=>s(...e));return(await Promise.all(r)).every(s=>s)};var D=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},N={},ze=()=>{const t="\\ud800-\\udfff",e="\\u0300-\\u036f",r="\\ufe20-\\ufe2f",s="\\u20d0-\\u20ff",n="\\u1ab0-\\u1aff",o="\\u1dc0-\\u1dff",a=e+r+s+n+o,i="\\ufe0e\\ufe0f",c="\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93",h=`[${t}]`,u=`[${a}]`,l="\\ud83c[\\udffb-\\udfff]",f=`(?:${u}|${l})`,b=`[^${t}]`,d="(?:\\uD83C[\\uDDE6-\\uDDFF]){2}",y="[\\ud800-\\udbff][\\udc00-\\udfff]",q="\\u200d",le="(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)",ce=`[${c}]`,T=`${f}?`,R=`[${i}]?`,fe=`(?:${q}(?:${[b,d,y].join("|")})${R+T})*`,he=R+T+fe,pe=`(?:${[`${b}${u}?`,u,d,y,h,ce].join("|")})`;return new RegExp(`${le}|${l}(?=${l})|${pe+he}`,"g")},Be=D&&D.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(N,"__esModule",{value:!0});var A=Be(ze);function j(t){if(typeof t!="string")throw new Error("A string is expected as input");return t.match(A.default())||[]}var Je=N.toArray=j;function P(t){if(typeof t!="string")throw new Error("Input must be a string");var e=t.match(A.default());return e===null?0:e.length}var Ge=N.length=P;function ee(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");(typeof e!="number"||e<0)&&(e=0),typeof r=="number"&&r<0&&(r=0);var s=t.match(A.default());return s?s.slice(e,r).join(""):""}var Ue=N.substring=ee;function Ve(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");var s=P(t);if(typeof e!="number"&&(e=parseInt(e,10)),e>=s)return"";e<0&&(e+=s);var n;typeof r>"u"?n=s:(typeof r!="number"&&(r=parseInt(r,10)),n=r>=0?r+e:e);var o=t.match(A.default());return o?o.slice(e,n).join(""):""}var Fe=N.substr=Ve;function He(t,e,r,s){if(e===void 0&&(e=16),r===void 0&&(r="#"),s===void 0&&(s="right"),typeof t!="string"||typeof e!="number")throw new Error("Invalid arguments specified");if(["left","right"].indexOf(s)===-1)throw new Error("Pad position should be either left or right");typeof r!="string"&&(r=String(r));var n=P(t);if(n>e)return ee(t,0,e);if(n=s.length)return e===""?s.length:-1;if(e==="")return r;var n=j(e),o=!1,a;for(a=r;am(t)||e<-m(t)))return M(t,e,1)}function Le(t,e){return e<0||e>m(t)-1?"":M(t,e,1)}function Ze(t,e){if(!(e<0||e>m(t)-1))return M(t,e,1).codePointAt(0)}function Xe(t,e,r=m(t)){const s=se(t,e);return!(s===-1||s+m(e)!==r)}function re(t,e,r=0){const s=O(t,r);return S(s,e)!==-1}function S(t,e,r=0){return We(t,e,r)}function se(t,e,r){let s=r||m(t);s<0?s=0:s>=m(t)&&(s=m(t)-1);for(let n=s;n>=0;n--)if(M(t,n,m(e))===e)return n;return-1}function m(t){return Ge(t)}function Qe(t,e){const r=e.toUpperCase();return r==="NONE"?t:t.normalize(r)}function Ye(t,e,r=" "){return e<=m(t)?t:te(t,e,r,"right")}function et(t,e,r=" "){return e<=m(t)?t:te(t,e,r,"left")}function I(t,e){return e>t?t:e<-t?0:e<0?e+t:e}function tt(t,e,r){const s=m(t);if(e>s||r&&(e>r&&!(e>0&&e-s)||r<-s||e<0&&e>-s&&r>0))return"";const n=I(s,e),o=r?I(s,r):void 0;return O(t,n,o)}function rt(t,e,r){const s=[];if(r!==void 0&&r<=0)return[t];if(e==="")return ne(t).slice(0,r);let n=e;(typeof e=="string"||e instanceof RegExp&&!re(e.flags,"g"))&&(n=new RegExp(e,"g"));const o=t.match(n);let a=0;if(!o)return[t];for(let i=0;i<(r?r-1:o.length);i++){const c=S(t,o[i],a),h=m(o[i]);if(s.push(O(t,a,c)),a=c+h,r!==void 0&&s.length===r)break}return s.push(O(t,a)),s}function st(t,e,r=0){return S(t,e,r)===r}function M(t,e=0,r=m(t)-e){return Fe(t,e,r)}function O(t,e,r=m(t)){return Ue(t,e,r)}function ne(t){return Je(t)}var nt=Object.getOwnPropertyNames,ot=Object.getOwnPropertySymbols,at=Object.prototype.hasOwnProperty;function x(t,e){return function(s,n,o){return t(s,n,o)&&e(s,n,o)}}function $(t){return function(r,s,n){if(!r||!s||typeof r!="object"||typeof s!="object")return t(r,s,n);var o=n.cache,a=o.get(r),i=o.get(s);if(a&&i)return a===s&&i===r;o.set(r,s),o.set(s,r);var c=t(r,s,n);return o.delete(r),o.delete(s),c}}function _(t){return nt(t).concat(ot(t))}var oe=Object.hasOwn||function(t,e){return at.call(t,e)};function v(t,e){return t||e?t===e:t===e||t!==t&&e!==e}var ae="_owner",z=Object.getOwnPropertyDescriptor,B=Object.keys;function it(t,e,r){var s=t.length;if(e.length!==s)return!1;for(;s-- >0;)if(!r.equals(t[s],e[s],s,s,t,e,r))return!1;return!0}function ut(t,e){return v(t.getTime(),e.getTime())}function J(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.entries(),o=0,a,i;(a=n.next())&&!a.done;){for(var c=e.entries(),h=!1,u=0;(i=c.next())&&!i.done;){var l=a.value,f=l[0],b=l[1],d=i.value,y=d[0],q=d[1];!h&&!s[u]&&(h=r.equals(f,y,o,u,t,e,r)&&r.equals(b,q,f,y,t,e,r))&&(s[u]=!0),u++}if(!h)return!1;o++}return!0}function lt(t,e,r){var s=B(t),n=s.length;if(B(e).length!==n)return!1;for(var o;n-- >0;)if(o=s[n],o===ae&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!oe(e,o)||!r.equals(t[o],e[o],o,o,t,e,r))return!1;return!0}function w(t,e,r){var s=_(t),n=s.length;if(_(e).length!==n)return!1;for(var o,a,i;n-- >0;)if(o=s[n],o===ae&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!oe(e,o)||!r.equals(t[o],e[o],o,o,t,e,r)||(a=z(t,o),i=z(e,o),(a||i)&&(!a||!i||a.configurable!==i.configurable||a.enumerable!==i.enumerable||a.writable!==i.writable)))return!1;return!0}function ct(t,e){return v(t.valueOf(),e.valueOf())}function ft(t,e){return t.source===e.source&&t.flags===e.flags}function G(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.values(),o,a;(o=n.next())&&!o.done;){for(var i=e.values(),c=!1,h=0;(a=i.next())&&!a.done;)!c&&!s[h]&&(c=r.equals(o.value,a.value,o.value,a.value,t,e,r))&&(s[h]=!0),h++;if(!c)return!1}return!0}function ht(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}var pt="[object Arguments]",mt="[object Boolean]",dt="[object Date]",bt="[object Map]",gt="[object Number]",Nt="[object Object]",vt="[object RegExp]",yt="[object Set]",wt="[object String]",Et=Array.isArray,U=typeof ArrayBuffer=="function"&&ArrayBuffer.isView?ArrayBuffer.isView:null,V=Object.assign,Ot=Object.prototype.toString.call.bind(Object.prototype.toString);function $t(t){var e=t.areArraysEqual,r=t.areDatesEqual,s=t.areMapsEqual,n=t.areObjectsEqual,o=t.arePrimitiveWrappersEqual,a=t.areRegExpsEqual,i=t.areSetsEqual,c=t.areTypedArraysEqual;return function(u,l,f){if(u===l)return!0;if(u==null||l==null||typeof u!="object"||typeof l!="object")return u!==u&&l!==l;var b=u.constructor;if(b!==l.constructor)return!1;if(b===Object)return n(u,l,f);if(Et(u))return e(u,l,f);if(U!=null&&U(u))return c(u,l,f);if(b===Date)return r(u,l,f);if(b===RegExp)return a(u,l,f);if(b===Map)return s(u,l,f);if(b===Set)return i(u,l,f);var d=Ot(u);return d===dt?r(u,l,f):d===vt?a(u,l,f):d===bt?s(u,l,f):d===yt?i(u,l,f):d===Nt?typeof u.then!="function"&&typeof l.then!="function"&&n(u,l,f):d===pt?n(u,l,f):d===mt||d===gt||d===wt?o(u,l,f):!1}}function At(t){var e=t.circular,r=t.createCustomConfig,s=t.strict,n={areArraysEqual:s?w:it,areDatesEqual:ut,areMapsEqual:s?x(J,w):J,areObjectsEqual:s?w:lt,arePrimitiveWrappersEqual:ct,areRegExpsEqual:ft,areSetsEqual:s?x(G,w):G,areTypedArraysEqual:s?w:ht};if(r&&(n=V({},n,r(n))),e){var o=$(n.areArraysEqual),a=$(n.areMapsEqual),i=$(n.areObjectsEqual),c=$(n.areSetsEqual);n=V({},n,{areArraysEqual:o,areMapsEqual:a,areObjectsEqual:i,areSetsEqual:c})}return n}function St(t){return function(e,r,s,n,o,a,i){return t(e,r,i)}}function Mt(t){var e=t.circular,r=t.comparator,s=t.createState,n=t.equals,o=t.strict;if(s)return function(c,h){var u=s(),l=u.cache,f=l===void 0?e?new WeakMap:void 0:l,b=u.meta;return r(c,h,{cache:f,equals:n,meta:b,strict:o})};if(e)return function(c,h){return r(c,h,{cache:new WeakMap,equals:n,meta:void 0,strict:o})};var a={cache:void 0,equals:n,meta:void 0,strict:o};return function(c,h){return r(c,h,a)}}var qt=g();g({strict:!0});g({circular:!0});g({circular:!0,strict:!0});g({createInternalComparator:function(){return v}});g({strict:!0,createInternalComparator:function(){return v}});g({circular:!0,createInternalComparator:function(){return v}});g({circular:!0,createInternalComparator:function(){return v},strict:!0});function g(t){t===void 0&&(t={});var e=t.circular,r=e===void 0?!1:e,s=t.createInternalComparator,n=t.createState,o=t.strict,a=o===void 0?!1:o,i=At(t),c=$t(i),h=s?s(c):St(c);return Mt({circular:r,comparator:c,createState:n,equals:h,strict:a})}function jt(t,e){return qt(t,e)}function C(t,e,r){return JSON.stringify(t,(n,o)=>{let a=o;return e&&(a=e(n,a)),a===void 0&&(a=null),a},r)}function ie(t,e){function r(n){return Object.keys(n).forEach(o=>{n[o]===null?n[o]=void 0:typeof n[o]=="object"&&(n[o]=r(n[o]))}),n}const s=JSON.parse(t,e);if(s!==null)return typeof s=="object"?r(s):s}function Ct(t){try{const e=C(t);return e===C(ie(e))}catch{return!1}}const Pt=t=>t.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/"),ue={title:"Platform.Bible menus",type:"object",properties:{mainMenu:{description:"Top level menu for the application",$ref:"#/$defs/multiColumnMenu"},defaultWebViewTopMenu:{description:"Default top menu for web views that don't specify their own",$ref:"#/$defs/multiColumnMenu"},defaultWebViewContextMenu:{description:"Default context menu for web views that don't specify their own",$ref:"#/$defs/singleColumnMenu"},webViewMenus:{description:"Menus that apply per web view in the application",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{$ref:"#/$defs/menusForOneWebView"}},additionalProperties:!1}},required:["mainMenu","defaultWebViewTopMenu","defaultWebViewContextMenu","webViewMenus"],additionalProperties:!1,$defs:{localizeKey:{description:"Identifier for a string that will be localized in a menu based on the user's UI language",type:"string",pattern:"^%[\\w\\-\\.]+%$"},referencedItem:{description:"Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)",type:"string",pattern:"^[\\w\\-]+\\.[\\w\\-]+$"},columnsWithHeaders:{description:"Group of columns that can be combined with other columns to form a multi-column menu",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single column with a header string",type:"object",properties:{label:{description:"Header text for this this column in the UI",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},order:{description:"Relative order of this column compared to other columns (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu groups to this column",type:"boolean"}},required:["label","order"],additionalProperties:!1}},properties:{isExtensible:{description:"Defines whether contributions are allowed to add columns to this multi-column menu",type:"boolean"}}},menuGroups:{description:"Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single group that contains menu items",type:"object",oneOf:[{properties:{column:{description:"Column where this group belongs, not required for single column menus",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["order"],additionalProperties:!1},{properties:{menuItem:{description:"Menu item that anchors the submenu where this group belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["menuItem","order"],additionalProperties:!1}]}},additionalProperties:!1},menuItem:{description:"Single item in a menu that can be clicked on to take an action or can be the parent of a submenu",type:"object",oneOf:[{properties:{id:{description:"ID for this menu item that holds a submenu",$ref:"#/$defs/referencedItem"}},required:["id"]},{properties:{command:{description:"Name of the PAPI command to run when this menu item is selected.",$ref:"#/$defs/referencedItem"},iconPathBefore:{description:"Path to the icon to display before the menu text",type:"string"},iconPathAfter:{description:"Path to the icon to display after the menu text",type:"string"}},required:["command"]}],properties:{label:{description:"Key that represents the text of this menu item to display",$ref:"#/$defs/localizeKey"},tooltip:{description:"Key that represents the text to display if a mouse pointer hovers over the menu item",$ref:"#/$defs/localizeKey"},searchTerms:{description:"Key that represents additional words the platform should reference when users are searching for menu items",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},group:{description:"Group to which this menu item belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this menu item compared to other menu items in the same group (sorted ascending)",type:"number"}},required:["label","group","order"],unevaluatedProperties:!1},groupsAndItems:{description:"Core schema for a column",type:"object",properties:{groups:{description:"Groups that belong in this menu",$ref:"#/$defs/menuGroups"},items:{description:"List of menu items that belong in this menu",type:"array",items:{$ref:"#/$defs/menuItem"},uniqueItems:!0}},required:["groups","items"]},singleColumnMenu:{description:"Menu that contains a column without a header",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"}],unevaluatedProperties:!1},multiColumnMenu:{description:"Menu that can contain multiple columns with headers",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"},{properties:{columns:{description:"Columns that belong in this menu",$ref:"#/$defs/columnsWithHeaders"}},required:["columns"]}],unevaluatedProperties:!1},menusForOneWebView:{description:"Set of menus that are associated with a single tab",type:"object",properties:{includeDefaults:{description:"Indicates whether the platform default menus should be included for this webview",type:"boolean"},topMenu:{description:"Menu that opens when you click on the top left corner of a tab",$ref:"#/$defs/multiColumnMenu"},contextMenu:{description:"Menu that opens when you right click on the main body/area of a tab",$ref:"#/$defs/singleColumnMenu"}},additionalProperties:!1}}};Object.freeze(ue);exports.AsyncVariable=ge;exports.DocumentCombinerEngine=Me;exports.FIRST_SCR_BOOK_NUM=L;exports.FIRST_SCR_CHAPTER_NUM=X;exports.FIRST_SCR_VERSE_NUM=Q;exports.LAST_SCR_BOOK_NUM=Z;exports.Mutex=W;exports.MutexMap=Te;exports.PlatformEventEmitter=Pe;exports.UnsubscriberAsyncList=Ce;exports.aggregateUnsubscriberAsyncs=_e;exports.aggregateUnsubscribers=xe;exports.at=Ke;exports.charAt=Le;exports.codePointAt=Ze;exports.createSyncProxyForAsyncObject=Se;exports.debounce=ve;exports.deepClone=E;exports.deepEqual=jt;exports.deserialize=ie;exports.endsWith=Xe;exports.getAllObjectFunctionNames=Ae;exports.getChaptersForBook=Y;exports.getErrorMessage=Oe;exports.groupBy=ye;exports.htmlEncode=Pt;exports.includes=re;exports.indexOf=S;exports.isSerializable=Ct;exports.isString=F;exports.lastIndexOf=se;exports.length=m;exports.menuDocumentSchema=ue;exports.newGuid=Ne;exports.normalize=Qe;exports.offsetBook=Re;exports.offsetChapter=De;exports.offsetVerse=Ie;exports.padEnd=Ye;exports.padStart=et;exports.serialize=C;exports.slice=tt;exports.split=rt;exports.startsWith=st;exports.substring=O;exports.toArray=ne;exports.wait=H;exports.waitForDuration=$e; +"use strict";var me=Object.defineProperty;var de=(t,e,r)=>e in t?me(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var p=(t,e,r)=>(de(t,typeof e!="symbol"?e+"":e,r),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const be=require("async-mutex");class ge{constructor(e,r=1e4){p(this,"variableName");p(this,"promiseToValue");p(this,"resolver");p(this,"rejecter");this.variableName=e,this.promiseToValue=new Promise((s,n)=>{this.resolver=s,this.rejecter=n}),r>0&&setTimeout(()=>{this.rejecter&&(this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`),this.complete())},r),Object.seal(this)}get promise(){return this.promiseToValue}get hasSettled(){return Object.isFrozen(this)}resolveToValue(e,r=!1){if(this.resolver)console.debug(`${this.variableName} is being resolved now`),this.resolver(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent resolution of ${this.variableName}`)}}rejectWithReason(e,r=!1){if(this.rejecter)console.debug(`${this.variableName} is being rejected now`),this.rejecter(e),this.complete();else{if(r)throw Error(`${this.variableName} was already settled`);console.debug(`Ignoring subsequent rejection of ${this.variableName}`)}}complete(){this.resolver=void 0,this.rejecter=void 0,Object.freeze(this)}}function Ne(){return"00-0-4-1-000".replace(/[^-]/g,t=>((Math.random()+~~t)*65536>>t).toString(16).padStart(4,"0"))}function F(t){return typeof t=="string"||t instanceof String}function E(t){return JSON.parse(JSON.stringify(t))}function ve(t,e=300){if(F(t))throw new Error("Tried to debounce a string! Could be XSS");let r;return(...s)=>{clearTimeout(r),r=setTimeout(()=>t(...s),e)}}function ye(t,e,r){const s=new Map;return t.forEach(n=>{const o=e(n),a=s.get(o),i=r?r(n,o):n;a?a.push(i):s.set(o,[i])}),s}function we(t){return typeof t=="object"&&t!==null&&"message"in t&&typeof t.message=="string"}function Ee(t){if(we(t))return t;try{return new Error(JSON.stringify(t))}catch{return new Error(String(t))}}function Oe(t){return Ee(t).message}function H(t){return new Promise(e=>setTimeout(e,t))}function $e(t,e){const r=H(e).then(()=>{});return Promise.any([r,t()])}function Ae(t,e="obj"){const r=new Set;Object.getOwnPropertyNames(t).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e} due to error: ${o}`)}});let s=Object.getPrototypeOf(t);for(;s&&Object.getPrototypeOf(s);)Object.getOwnPropertyNames(s).forEach(n=>{try{typeof t[n]=="function"&&r.add(n)}catch(o){console.debug(`Skipping ${n} on ${e}'s prototype due to error: ${o}`)}}),s=Object.getPrototypeOf(s);return r}function Se(t,e={}){return new Proxy(e,{get(r,s){return s in r?r[s]:async(...n)=>(await t())[s](...n)}})}class Me{constructor(e,r){p(this,"baseDocument");p(this,"contributions",new Map);p(this,"latestOutput");p(this,"options");this.baseDocument=e,this.options=r,this.updateBaseDocument(e)}updateBaseDocument(e){return this.validateStartingDocument(e),this.baseDocument=this.options.copyDocuments?E(e):e,this.rebuild()}addOrUpdateContribution(e,r){this.validateContribution(e,r);const s=this.contributions.get(e),n=this.options.copyDocuments&&r?E(r):r;this.contributions.set(e,n);try{return this.rebuild()}catch(o){throw s?this.contributions.set(e,s):this.contributions.delete(e),new Error(`Error when setting the document named ${e}: ${o}`)}}deleteContribution(e){const r=this.contributions.get(e);if(!r)throw new Error("{documentKey} does not exist");this.contributions.delete(e);try{return this.rebuild()}catch(s){throw this.contributions.set(e,r),new Error(`Error when deleting the document named ${e}: ${s}`)}}rebuild(){if(this.contributions.size===0){let r=E(this.baseDocument);return r=this.transformFinalOutput(r),this.validateOutput(r),this.latestOutput=r,this.latestOutput}let e=this.baseDocument;return this.contributions.forEach(r=>{e=k(e,r,this.options.ignoreDuplicateProperties),this.validateOutput(e)}),e=this.transformFinalOutput(e),this.validateOutput(e),this.latestOutput=e,this.latestOutput}}function qe(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||Array.isArray(r))&&(e=!1)}),e}function je(...t){let e=!0;return t.forEach(r=>{(!r||typeof r!="object"||!Array.isArray(r))&&(e=!1)}),e}function k(t,e,r){const s=E(t);return e&&Object.keys(e).forEach(n=>{if(Object.hasOwn(t,n)){if(qe(t[n],e[n]))s[n]=k(t[n],e[n],r);else if(je(t[n],e[n]))s[n]=s[n].concat(e[n]);else if(!r)throw new Error(`Cannot merge objects: key "${n}" already exists in the target object`)}else s[n]=e[n]}),s}class Ce{constructor(e="Anonymous"){p(this,"unsubscribers",new Set);this.name=e}add(...e){e.forEach(r=>{"dispose"in r?this.unsubscribers.add(r.dispose):this.unsubscribers.add(r)})}async runAllUnsubscribers(){const e=[...this.unsubscribers].map(s=>s()),r=await Promise.all(e);return this.unsubscribers.clear(),r.every((s,n)=>(s||console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${n} failed!`),s))}}class Pe{constructor(){p(this,"subscribe",this.event);p(this,"subscriptions");p(this,"lazyEvent");p(this,"isDisposed",!1);p(this,"dispose",()=>this.disposeFn());p(this,"emit",e=>{this.emitFn(e)})}get event(){return this.assertNotDisposed(),this.lazyEvent||(this.lazyEvent=e=>{if(!e||typeof e!="function")throw new Error("Event handler callback must be a function!");return this.subscriptions||(this.subscriptions=[]),this.subscriptions.push(e),()=>{if(!this.subscriptions)return!1;const r=this.subscriptions.indexOf(e);return r<0?!1:(this.subscriptions.splice(r,1),!0)}}),this.lazyEvent}emitFn(e){var r;this.assertNotDisposed(),(r=this.subscriptions)==null||r.forEach(s=>s(e))}assertNotDisposed(){if(this.isDisposed)throw new Error("Emitter is disposed")}disposeFn(){return this.assertNotDisposed(),this.isDisposed=!0,this.subscriptions=void 0,this.lazyEvent=void 0,Promise.resolve(!0)}}class W extends be.Mutex{}class Te{constructor(){p(this,"mutexesByID",new Map)}get(e){let r=this.mutexesByID.get(e);return r||(r=new W,this.mutexesByID.set(e,r),r)}}const K=[{shortName:"ERR",fullNames:["ERROR"],chapters:-1},{shortName:"GEN",fullNames:["Genesis"],chapters:50},{shortName:"EXO",fullNames:["Exodus"],chapters:40},{shortName:"LEV",fullNames:["Leviticus"],chapters:27},{shortName:"NUM",fullNames:["Numbers"],chapters:36},{shortName:"DEU",fullNames:["Deuteronomy"],chapters:34},{shortName:"JOS",fullNames:["Joshua"],chapters:24},{shortName:"JDG",fullNames:["Judges"],chapters:21},{shortName:"RUT",fullNames:["Ruth"],chapters:4},{shortName:"1SA",fullNames:["1 Samuel"],chapters:31},{shortName:"2SA",fullNames:["2 Samuel"],chapters:24},{shortName:"1KI",fullNames:["1 Kings"],chapters:22},{shortName:"2KI",fullNames:["2 Kings"],chapters:25},{shortName:"1CH",fullNames:["1 Chronicles"],chapters:29},{shortName:"2CH",fullNames:["2 Chronicles"],chapters:36},{shortName:"EZR",fullNames:["Ezra"],chapters:10},{shortName:"NEH",fullNames:["Nehemiah"],chapters:13},{shortName:"EST",fullNames:["Esther"],chapters:10},{shortName:"JOB",fullNames:["Job"],chapters:42},{shortName:"PSA",fullNames:["Psalm","Psalms"],chapters:150},{shortName:"PRO",fullNames:["Proverbs"],chapters:31},{shortName:"ECC",fullNames:["Ecclesiastes"],chapters:12},{shortName:"SNG",fullNames:["Song of Solomon","Song of Songs"],chapters:8},{shortName:"ISA",fullNames:["Isaiah"],chapters:66},{shortName:"JER",fullNames:["Jeremiah"],chapters:52},{shortName:"LAM",fullNames:["Lamentations"],chapters:5},{shortName:"EZK",fullNames:["Ezekiel"],chapters:48},{shortName:"DAN",fullNames:["Daniel"],chapters:12},{shortName:"HOS",fullNames:["Hosea"],chapters:14},{shortName:"JOL",fullNames:["Joel"],chapters:3},{shortName:"AMO",fullNames:["Amos"],chapters:9},{shortName:"OBA",fullNames:["Obadiah"],chapters:1},{shortName:"JON",fullNames:["Jonah"],chapters:4},{shortName:"MIC",fullNames:["Micah"],chapters:7},{shortName:"NAM",fullNames:["Nahum"],chapters:3},{shortName:"HAB",fullNames:["Habakkuk"],chapters:3},{shortName:"ZEP",fullNames:["Zephaniah"],chapters:3},{shortName:"HAG",fullNames:["Haggai"],chapters:2},{shortName:"ZEC",fullNames:["Zechariah"],chapters:14},{shortName:"MAL",fullNames:["Malachi"],chapters:4},{shortName:"MAT",fullNames:["Matthew"],chapters:28},{shortName:"MRK",fullNames:["Mark"],chapters:16},{shortName:"LUK",fullNames:["Luke"],chapters:24},{shortName:"JHN",fullNames:["John"],chapters:21},{shortName:"ACT",fullNames:["Acts"],chapters:28},{shortName:"ROM",fullNames:["Romans"],chapters:16},{shortName:"1CO",fullNames:["1 Corinthians"],chapters:16},{shortName:"2CO",fullNames:["2 Corinthians"],chapters:13},{shortName:"GAL",fullNames:["Galatians"],chapters:6},{shortName:"EPH",fullNames:["Ephesians"],chapters:6},{shortName:"PHP",fullNames:["Philippians"],chapters:4},{shortName:"COL",fullNames:["Colossians"],chapters:4},{shortName:"1TH",fullNames:["1 Thessalonians"],chapters:5},{shortName:"2TH",fullNames:["2 Thessalonians"],chapters:3},{shortName:"1TI",fullNames:["1 Timothy"],chapters:6},{shortName:"2TI",fullNames:["2 Timothy"],chapters:4},{shortName:"TIT",fullNames:["Titus"],chapters:3},{shortName:"PHM",fullNames:["Philemon"],chapters:1},{shortName:"HEB",fullNames:["Hebrews"],chapters:13},{shortName:"JAS",fullNames:["James"],chapters:5},{shortName:"1PE",fullNames:["1 Peter"],chapters:5},{shortName:"2PE",fullNames:["2 Peter"],chapters:3},{shortName:"1JN",fullNames:["1 John"],chapters:5},{shortName:"2JN",fullNames:["2 John"],chapters:1},{shortName:"3JN",fullNames:["3 John"],chapters:1},{shortName:"JUD",fullNames:["Jude"],chapters:1},{shortName:"REV",fullNames:["Revelation"],chapters:22}],L=1,Z=K.length-1,X=1,Q=1,Y=t=>{var e;return((e=K[t])==null?void 0:e.chapters)??-1},Re=(t,e)=>({bookNum:Math.max(L,Math.min(t.bookNum+e,Z)),chapterNum:1,verseNum:1}),De=(t,e)=>({...t,chapterNum:Math.min(Math.max(X,t.chapterNum+e),Y(t.bookNum)),verseNum:1}),Ie=(t,e)=>({...t,verseNum:Math.max(Q,t.verseNum+e)}),xe=t=>(...e)=>t.map(s=>s(...e)).every(s=>s),_e=t=>async(...e)=>{const r=t.map(async s=>s(...e));return(await Promise.all(r)).every(s=>s)};var D=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},N={},ze=()=>{const t="\\ud800-\\udfff",e="\\u0300-\\u036f",r="\\ufe20-\\ufe2f",s="\\u20d0-\\u20ff",n="\\u1ab0-\\u1aff",o="\\u1dc0-\\u1dff",a=e+r+s+n+o,i="\\ufe0e\\ufe0f",c="\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83C\\uDF93",h=`[${t}]`,u=`[${a}]`,l="\\ud83c[\\udffb-\\udfff]",f=`(?:${u}|${l})`,b=`[^${t}]`,d="(?:\\uD83C[\\uDDE6-\\uDDFF]){2}",y="[\\ud800-\\udbff][\\udc00-\\udfff]",q="\\u200d",le="(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40(?:\\udc65|\\udc73|\\udc77)\\udb40(?:\\udc6e|\\udc63|\\udc6c)\\udb40(?:\\udc67|\\udc74|\\udc73)\\udb40\\udc7f)",ce=`[${c}]`,T=`${f}?`,R=`[${i}]?`,fe=`(?:${q}(?:${[b,d,y].join("|")})${R+T})*`,he=R+T+fe,pe=`(?:${[`${b}${u}?`,u,d,y,h,ce].join("|")})`;return new RegExp(`${le}|${l}(?=${l})|${pe+he}`,"g")},Be=D&&D.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(N,"__esModule",{value:!0});var A=Be(ze);function j(t){if(typeof t!="string")throw new Error("A string is expected as input");return t.match(A.default())||[]}var Je=N.toArray=j;function P(t){if(typeof t!="string")throw new Error("Input must be a string");var e=t.match(A.default());return e===null?0:e.length}var Ge=N.length=P;function ee(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");(typeof e!="number"||e<0)&&(e=0),typeof r=="number"&&r<0&&(r=0);var s=t.match(A.default());return s?s.slice(e,r).join(""):""}var Ue=N.substring=ee;function Ve(t,e,r){if(e===void 0&&(e=0),typeof t!="string")throw new Error("Input must be a string");var s=P(t);if(typeof e!="number"&&(e=parseInt(e,10)),e>=s)return"";e<0&&(e+=s);var n;typeof r>"u"?n=s:(typeof r!="number"&&(r=parseInt(r,10)),n=r>=0?r+e:e);var o=t.match(A.default());return o?o.slice(e,n).join(""):""}var Fe=N.substr=Ve;function He(t,e,r,s){if(e===void 0&&(e=16),r===void 0&&(r="#"),s===void 0&&(s="right"),typeof t!="string"||typeof e!="number")throw new Error("Invalid arguments specified");if(["left","right"].indexOf(s)===-1)throw new Error("Pad position should be either left or right");typeof r!="string"&&(r=String(r));var n=P(t);if(n>e)return ee(t,0,e);if(n=s.length)return e===""?s.length:-1;if(e==="")return r;var n=j(e),o=!1,a;for(a=r;am(t)||e<-m(t)))return M(t,e,1)}function Le(t,e){return e<0||e>m(t)-1?"":M(t,e,1)}function Ze(t,e){if(!(e<0||e>m(t)-1))return M(t,e,1).codePointAt(0)}function Xe(t,e,r=m(t)){const s=se(t,e);return!(s===-1||s+m(e)!==r)}function re(t,e,r=0){const s=O(t,r);return S(s,e)!==-1}function S(t,e,r=0){return We(t,e,r)}function se(t,e,r){let s=r===void 0?m(t):r;s<0?s=0:s>=m(t)&&(s=m(t)-1);for(let n=s;n>=0;n--)if(M(t,n,m(e))===e)return n;return-1}function m(t){return Ge(t)}function Qe(t,e){const r=e.toUpperCase();return r==="NONE"?t:t.normalize(r)}function Ye(t,e,r=" "){return e<=m(t)?t:te(t,e,r,"right")}function et(t,e,r=" "){return e<=m(t)?t:te(t,e,r,"left")}function I(t,e){return e>t?t:e<-t?0:e<0?e+t:e}function tt(t,e,r){const s=m(t);if(e>s||r&&(e>r&&!(e>0&&e-s)||r<-s||e<0&&e>-s&&r>0))return"";const n=I(s,e),o=r?I(s,r):void 0;return O(t,n,o)}function rt(t,e,r){const s=[];if(r!==void 0&&r<=0)return[t];if(e==="")return ne(t).slice(0,r);let n=e;(typeof e=="string"||e instanceof RegExp&&!re(e.flags,"g"))&&(n=new RegExp(e,"g"));const o=t.match(n);let a=0;if(!o)return[t];for(let i=0;i<(r?r-1:o.length);i++){const c=S(t,o[i],a),h=m(o[i]);if(s.push(O(t,a,c)),a=c+h,r!==void 0&&s.length===r)break}return s.push(O(t,a)),s}function st(t,e,r=0){return S(t,e,r)===r}function M(t,e=0,r=m(t)-e){return Fe(t,e,r)}function O(t,e,r=m(t)){return Ue(t,e,r)}function ne(t){return Je(t)}var nt=Object.getOwnPropertyNames,ot=Object.getOwnPropertySymbols,at=Object.prototype.hasOwnProperty;function x(t,e){return function(s,n,o){return t(s,n,o)&&e(s,n,o)}}function $(t){return function(r,s,n){if(!r||!s||typeof r!="object"||typeof s!="object")return t(r,s,n);var o=n.cache,a=o.get(r),i=o.get(s);if(a&&i)return a===s&&i===r;o.set(r,s),o.set(s,r);var c=t(r,s,n);return o.delete(r),o.delete(s),c}}function _(t){return nt(t).concat(ot(t))}var oe=Object.hasOwn||function(t,e){return at.call(t,e)};function v(t,e){return t||e?t===e:t===e||t!==t&&e!==e}var ae="_owner",z=Object.getOwnPropertyDescriptor,B=Object.keys;function it(t,e,r){var s=t.length;if(e.length!==s)return!1;for(;s-- >0;)if(!r.equals(t[s],e[s],s,s,t,e,r))return!1;return!0}function ut(t,e){return v(t.getTime(),e.getTime())}function J(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.entries(),o=0,a,i;(a=n.next())&&!a.done;){for(var c=e.entries(),h=!1,u=0;(i=c.next())&&!i.done;){var l=a.value,f=l[0],b=l[1],d=i.value,y=d[0],q=d[1];!h&&!s[u]&&(h=r.equals(f,y,o,u,t,e,r)&&r.equals(b,q,f,y,t,e,r))&&(s[u]=!0),u++}if(!h)return!1;o++}return!0}function lt(t,e,r){var s=B(t),n=s.length;if(B(e).length!==n)return!1;for(var o;n-- >0;)if(o=s[n],o===ae&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!oe(e,o)||!r.equals(t[o],e[o],o,o,t,e,r))return!1;return!0}function w(t,e,r){var s=_(t),n=s.length;if(_(e).length!==n)return!1;for(var o,a,i;n-- >0;)if(o=s[n],o===ae&&(t.$$typeof||e.$$typeof)&&t.$$typeof!==e.$$typeof||!oe(e,o)||!r.equals(t[o],e[o],o,o,t,e,r)||(a=z(t,o),i=z(e,o),(a||i)&&(!a||!i||a.configurable!==i.configurable||a.enumerable!==i.enumerable||a.writable!==i.writable)))return!1;return!0}function ct(t,e){return v(t.valueOf(),e.valueOf())}function ft(t,e){return t.source===e.source&&t.flags===e.flags}function G(t,e,r){if(t.size!==e.size)return!1;for(var s={},n=t.values(),o,a;(o=n.next())&&!o.done;){for(var i=e.values(),c=!1,h=0;(a=i.next())&&!a.done;)!c&&!s[h]&&(c=r.equals(o.value,a.value,o.value,a.value,t,e,r))&&(s[h]=!0),h++;if(!c)return!1}return!0}function ht(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}var pt="[object Arguments]",mt="[object Boolean]",dt="[object Date]",bt="[object Map]",gt="[object Number]",Nt="[object Object]",vt="[object RegExp]",yt="[object Set]",wt="[object String]",Et=Array.isArray,U=typeof ArrayBuffer=="function"&&ArrayBuffer.isView?ArrayBuffer.isView:null,V=Object.assign,Ot=Object.prototype.toString.call.bind(Object.prototype.toString);function $t(t){var e=t.areArraysEqual,r=t.areDatesEqual,s=t.areMapsEqual,n=t.areObjectsEqual,o=t.arePrimitiveWrappersEqual,a=t.areRegExpsEqual,i=t.areSetsEqual,c=t.areTypedArraysEqual;return function(u,l,f){if(u===l)return!0;if(u==null||l==null||typeof u!="object"||typeof l!="object")return u!==u&&l!==l;var b=u.constructor;if(b!==l.constructor)return!1;if(b===Object)return n(u,l,f);if(Et(u))return e(u,l,f);if(U!=null&&U(u))return c(u,l,f);if(b===Date)return r(u,l,f);if(b===RegExp)return a(u,l,f);if(b===Map)return s(u,l,f);if(b===Set)return i(u,l,f);var d=Ot(u);return d===dt?r(u,l,f):d===vt?a(u,l,f):d===bt?s(u,l,f):d===yt?i(u,l,f):d===Nt?typeof u.then!="function"&&typeof l.then!="function"&&n(u,l,f):d===pt?n(u,l,f):d===mt||d===gt||d===wt?o(u,l,f):!1}}function At(t){var e=t.circular,r=t.createCustomConfig,s=t.strict,n={areArraysEqual:s?w:it,areDatesEqual:ut,areMapsEqual:s?x(J,w):J,areObjectsEqual:s?w:lt,arePrimitiveWrappersEqual:ct,areRegExpsEqual:ft,areSetsEqual:s?x(G,w):G,areTypedArraysEqual:s?w:ht};if(r&&(n=V({},n,r(n))),e){var o=$(n.areArraysEqual),a=$(n.areMapsEqual),i=$(n.areObjectsEqual),c=$(n.areSetsEqual);n=V({},n,{areArraysEqual:o,areMapsEqual:a,areObjectsEqual:i,areSetsEqual:c})}return n}function St(t){return function(e,r,s,n,o,a,i){return t(e,r,i)}}function Mt(t){var e=t.circular,r=t.comparator,s=t.createState,n=t.equals,o=t.strict;if(s)return function(c,h){var u=s(),l=u.cache,f=l===void 0?e?new WeakMap:void 0:l,b=u.meta;return r(c,h,{cache:f,equals:n,meta:b,strict:o})};if(e)return function(c,h){return r(c,h,{cache:new WeakMap,equals:n,meta:void 0,strict:o})};var a={cache:void 0,equals:n,meta:void 0,strict:o};return function(c,h){return r(c,h,a)}}var qt=g();g({strict:!0});g({circular:!0});g({circular:!0,strict:!0});g({createInternalComparator:function(){return v}});g({strict:!0,createInternalComparator:function(){return v}});g({circular:!0,createInternalComparator:function(){return v}});g({circular:!0,createInternalComparator:function(){return v},strict:!0});function g(t){t===void 0&&(t={});var e=t.circular,r=e===void 0?!1:e,s=t.createInternalComparator,n=t.createState,o=t.strict,a=o===void 0?!1:o,i=At(t),c=$t(i),h=s?s(c):St(c);return Mt({circular:r,comparator:c,createState:n,equals:h,strict:a})}function jt(t,e){return qt(t,e)}function C(t,e,r){return JSON.stringify(t,(n,o)=>{let a=o;return e&&(a=e(n,a)),a===void 0&&(a=null),a},r)}function ie(t,e){function r(n){return Object.keys(n).forEach(o=>{n[o]===null?n[o]=void 0:typeof n[o]=="object"&&(n[o]=r(n[o]))}),n}const s=JSON.parse(t,e);if(s!==null)return typeof s=="object"?r(s):s}function Ct(t){try{const e=C(t);return e===C(ie(e))}catch{return!1}}const Pt=t=>t.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/"),ue={title:"Platform.Bible menus",type:"object",properties:{mainMenu:{description:"Top level menu for the application",$ref:"#/$defs/multiColumnMenu"},defaultWebViewTopMenu:{description:"Default top menu for web views that don't specify their own",$ref:"#/$defs/multiColumnMenu"},defaultWebViewContextMenu:{description:"Default context menu for web views that don't specify their own",$ref:"#/$defs/singleColumnMenu"},webViewMenus:{description:"Menus that apply per web view in the application",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{$ref:"#/$defs/menusForOneWebView"}},additionalProperties:!1}},required:["mainMenu","defaultWebViewTopMenu","defaultWebViewContextMenu","webViewMenus"],additionalProperties:!1,$defs:{localizeKey:{description:"Identifier for a string that will be localized in a menu based on the user's UI language",type:"string",pattern:"^%[\\w\\-\\.]+%$"},referencedItem:{description:"Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)",type:"string",pattern:"^[\\w\\-]+\\.[\\w\\-]+$"},columnsWithHeaders:{description:"Group of columns that can be combined with other columns to form a multi-column menu",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single column with a header string",type:"object",properties:{label:{description:"Header text for this this column in the UI",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},order:{description:"Relative order of this column compared to other columns (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu groups to this column",type:"boolean"}},required:["label","order"],additionalProperties:!1}},properties:{isExtensible:{description:"Defines whether contributions are allowed to add columns to this multi-column menu",type:"boolean"}}},menuGroups:{description:"Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.",type:"object",patternProperties:{"^[\\w\\-]+\\.[\\w\\-]+$":{description:"Single group that contains menu items",type:"object",oneOf:[{properties:{column:{description:"Column where this group belongs, not required for single column menus",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["order"],additionalProperties:!1},{properties:{menuItem:{description:"Menu item that anchors the submenu where this group belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this group compared to other groups in the same column or submenu (sorted ascending)",type:"number"},isExtensible:{description:"Defines whether contributions are allowed to add menu items to this menu group",type:"boolean"}},required:["menuItem","order"],additionalProperties:!1}]}},additionalProperties:!1},menuItem:{description:"Single item in a menu that can be clicked on to take an action or can be the parent of a submenu",type:"object",oneOf:[{properties:{id:{description:"ID for this menu item that holds a submenu",$ref:"#/$defs/referencedItem"}},required:["id"]},{properties:{command:{description:"Name of the PAPI command to run when this menu item is selected.",$ref:"#/$defs/referencedItem"},iconPathBefore:{description:"Path to the icon to display before the menu text",type:"string"},iconPathAfter:{description:"Path to the icon to display after the menu text",type:"string"}},required:["command"]}],properties:{label:{description:"Key that represents the text of this menu item to display",$ref:"#/$defs/localizeKey"},tooltip:{description:"Key that represents the text to display if a mouse pointer hovers over the menu item",$ref:"#/$defs/localizeKey"},searchTerms:{description:"Key that represents additional words the platform should reference when users are searching for menu items",$ref:"#/$defs/localizeKey"},localizeNotes:{description:"Additional information provided by developers to help people who perform localization",type:"string"},group:{description:"Group to which this menu item belongs",$ref:"#/$defs/referencedItem"},order:{description:"Relative order of this menu item compared to other menu items in the same group (sorted ascending)",type:"number"}},required:["label","group","order"],unevaluatedProperties:!1},groupsAndItems:{description:"Core schema for a column",type:"object",properties:{groups:{description:"Groups that belong in this menu",$ref:"#/$defs/menuGroups"},items:{description:"List of menu items that belong in this menu",type:"array",items:{$ref:"#/$defs/menuItem"},uniqueItems:!0}},required:["groups","items"]},singleColumnMenu:{description:"Menu that contains a column without a header",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"}],unevaluatedProperties:!1},multiColumnMenu:{description:"Menu that can contain multiple columns with headers",type:"object",allOf:[{$ref:"#/$defs/groupsAndItems"},{properties:{columns:{description:"Columns that belong in this menu",$ref:"#/$defs/columnsWithHeaders"}},required:["columns"]}],unevaluatedProperties:!1},menusForOneWebView:{description:"Set of menus that are associated with a single tab",type:"object",properties:{includeDefaults:{description:"Indicates whether the platform default menus should be included for this webview",type:"boolean"},topMenu:{description:"Menu that opens when you click on the top left corner of a tab",$ref:"#/$defs/multiColumnMenu"},contextMenu:{description:"Menu that opens when you right click on the main body/area of a tab",$ref:"#/$defs/singleColumnMenu"}},additionalProperties:!1}}};Object.freeze(ue);exports.AsyncVariable=ge;exports.DocumentCombinerEngine=Me;exports.FIRST_SCR_BOOK_NUM=L;exports.FIRST_SCR_CHAPTER_NUM=X;exports.FIRST_SCR_VERSE_NUM=Q;exports.LAST_SCR_BOOK_NUM=Z;exports.Mutex=W;exports.MutexMap=Te;exports.PlatformEventEmitter=Pe;exports.UnsubscriberAsyncList=Ce;exports.aggregateUnsubscriberAsyncs=_e;exports.aggregateUnsubscribers=xe;exports.at=Ke;exports.charAt=Le;exports.codePointAt=Ze;exports.createSyncProxyForAsyncObject=Se;exports.debounce=ve;exports.deepClone=E;exports.deepEqual=jt;exports.deserialize=ie;exports.endsWith=Xe;exports.getAllObjectFunctionNames=Ae;exports.getChaptersForBook=Y;exports.getErrorMessage=Oe;exports.groupBy=ye;exports.htmlEncode=Pt;exports.includes=re;exports.indexOf=S;exports.isSerializable=Ct;exports.isString=F;exports.lastIndexOf=se;exports.menuDocumentSchema=ue;exports.newGuid=Ne;exports.normalize=Qe;exports.offsetBook=Re;exports.offsetChapter=De;exports.offsetVerse=Ie;exports.padEnd=Ye;exports.padStart=et;exports.serialize=C;exports.slice=tt;exports.split=rt;exports.startsWith=st;exports.stringLength=m;exports.substring=O;exports.toArray=ne;exports.wait=H;exports.waitForDuration=$e; //# sourceMappingURL=index.cjs.map diff --git a/lib/platform-bible-utils/dist/index.cjs.map b/lib/platform-bible-utils/dist/index.cjs.map index 185424047d..ab65f685f7 100644 --- a/lib/platform-bible-utils/dist/index.cjs.map +++ b/lib/platform-bible-utils/dist/index.cjs.map @@ -1 +1 @@ -{"version":3,"file":"index.cjs","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/mutex.ts","../src/mutex-map.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { Mutex as AsyncMutex } from 'async-mutex';\n\n// Extending Mutex from async-mutex so we can add JSDoc\n\n/**\n * Class that allows calling asynchronous functions multiple times at once while only running one at\n * a time.\n *\n * @example\n *\n * ```typescript\n * const mutex = new Mutex();\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n * ```\n *\n * See [`async-mutex`](https://www.npmjs.com/package/async-mutex) for more information.\n */\nclass Mutex extends AsyncMutex {}\n\nexport default Mutex;\n","import Mutex from './mutex';\n\n/** Map of {@link Mutex}es that automatically (lazily) generates a new {@link Mutex} for any new key */\nclass MutexMap {\n private mutexesByID = new Map();\n\n get(mutexID: string): Mutex {\n let retVal = this.mutexesByID.get(mutexID);\n if (retVal) return retVal;\n\n retVal = new Mutex();\n this.mutexesByID.set(mutexID, retVal);\n return retVal;\n }\n}\n\nexport default MutexMap;\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * Finds the Unicode code point at the given index. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param string String to index\n * @param index Position of the character to be returned in range of -length(string) to\n * length(string)\n * @returns New string consisting of the Unicode code point located at the specified\n * offset, undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > length(string) || index < -length(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * Returns a new string consisting of the single UTF-16 code unit at the given index.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns New string consisting of the Unicode code point located at the specified\n * offset, empty string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > length(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns Non-negative integer representing the code point value of the\n * character at the given index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > length(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * Determines whether a string ends with the characters of this string. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to search through\n * @param searchString Characters to search for at the end of the string\n * @param endPosition End position where searchString is expected to be\n * found. Default is `length(string)`\n * @returns True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = length(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + length(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * Performs a case-sensitive search to determine if searchString is found in string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to search through\n * @param searchString String to search for\n * @param position Position within the string to start searching for searchString.\n * Default is `0`\n * @returns True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * Returns the index of the first occurrence of a given string. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param string String to search through\n * @param searchString The string to search for\n * @param position Start of searching. Default is `0`\n * @returns Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * Searches this string and returns the index of the last occurrence of the specified substring.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to search through\n * @param searchString Substring to search for\n * @param position The index at which to begin searching. If omitted, the search begins at the end\n * of the string. Default is `undefined`\n * @returns Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(\n string: string,\n searchString: string,\n position?: number,\n): number {\n let validatedPosition = position ? position : length(string);\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= length(string)) {\n validatedPosition = length(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, length(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * Returns the length of a string. This function handles Unicode code points instead of UTF-16\n * character codes.\n *\n * @param string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function length(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * Returns the Unicode Normalization Form of this string.\n *\n * @param string The starting string\n * @param form Form specifying the Unicode Normalization Form. Default is `'NFC'`\n * @returns A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to add padding too\n * @param targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param padString The string to pad the current string with. If padString is too\n * long to stay within targetLength, it will be truncated. Default is `\" \"`\n * @returns String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to add padding too\n * @param targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param padString The string to pad the current string with. If padString is too\n * long to stay within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\nfunction correctSliceIndex(stringLength: number, index: number) {\n if (index > stringLength) return stringLength;\n if (index < -stringLength) return 0;\n if (index < 0) return index + stringLength;\n return index;\n}\n\n/**\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string The starting string\n * @param indexStart The index of the first character to include in the returned substring.\n * @param indexEnd The index of the first character to exclude from the returned substring.\n * @returns A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const stringLength: number = length(string);\n if (\n indexStart > stringLength ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(\n indexStart > 0 &&\n indexStart < stringLength &&\n indexEnd < 0 &&\n indexEnd > -stringLength\n )) ||\n indexEnd < -stringLength ||\n (indexStart < 0 && indexStart > -stringLength && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(stringLength, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param string The string to split\n * @param separator The pattern describing where each split should occur\n * @param splitLimit Limit on the number of substrings to be included in the array. Splits\n * the string at each occurrence of specified separator, but stops when limit entries have been\n * placed in the array.\n * @returns An array of strings, split at each point where separator occurs\n * in the starting string. Returns undefined if separator is not found in string.\n */\nexport function split(string: string, separator: string | RegExp, splitLimit?: number): string[] {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !includes(separator.flags, 'g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return [string];\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = length(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate. This function handles Unicode code points instead of UTF-16 character\n * codes.\n *\n * @param string String to search through\n * @param searchString The characters to be searched for at the start of this string.\n * @param position The start position at which searchString is expected to be found\n * (the index of searchString's first character). Default is `0`\n * @returns True if the given characters are found at the beginning of the string,\n * including when searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * Returns a substring by providing start and length. This function handles Unicode code points\n * instead of UTF-16 character codes. This function is not exported because it is considered\n * deprecated, however it is still useful as a local helper function.\n *\n * @param string String to be divided\n * @param begin Start position. Default is `Start of string`\n * @param len Length of result. Default is `String\n * length minus start parameter`. Default is `String length minus start parameter`\n * @returns Substring from starting string\n */\nfunction substr(string: string, begin: number = 0, len: number = length(string) - begin): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * Returns a substring by providing start and end position. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param string String to be divided\n * @param begin Start position\n * @param end End position. Default is `End of string`\n * @returns Substring from starting string\n */\nexport function substring(\n string: string,\n begin: number,\n end: number = length(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * Converts a string to an array of string characters. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param string String to convert to array\n * @returns An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","Mutex","AsyncMutex","MutexMap","mutexID","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","stringLength","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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B,qBAAsB,EACxB,EACA,CACE,WAAY,CACV,SAAU,CACR,YAAa,8DACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,WAAY,OAAO,EAC9B,qBAAsB,EACxB,CACF,CACF,CACF,EACA,qBAAsB,EACxB,EACA,SAAU,CACR,YACE,mGACF,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,GAAI,CACF,YAAa,6CACb,KAAM,wBACR,CACF,EACA,SAAU,CAAC,IAAI,CACjB,EACA,CACE,WAAY,CACV,QAAS,CACP,YAAa,mEACb,KAAM,wBACR,EACA,eAAgB,CACd,YAAa,mDACb,KAAM,QACR,EACA,cAAe,CACb,YAAa,kDACb,KAAM,QACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,WAAY,CACV,MAAO,CACL,YAAa,4DACb,KAAM,qBACR,EACA,QAAS,CACP,YACE,uFACF,KAAM,qBACR,EACA,YAAa,CACX,YACE,6GACF,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YAAa,wCACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,qGACF,KAAM,QACR,CACF,EACA,SAAU,CAAC,QAAS,QAAS,OAAO,EACpC,sBAAuB,EACzB,EACA,eAAgB,CACd,YAAa,2BACb,KAAM,SACN,WAAY,CACV,OAAQ,CACN,YAAa,kCACb,KAAM,oBACR,EACA,MAAO,CACL,YAAa,8CACb,KAAM,QACN,MAAO,CAAE,KAAM,kBAAmB,EAClC,YAAa,EACf,CACF,EACA,SAAU,CAAC,SAAU,OAAO,CAC9B,EACA,iBAAkB,CAChB,YAAa,+CACb,KAAM,SACN,MAAO,CAAC,CAAE,KAAM,yBAA0B,EAC1C,sBAAuB,EACzB,EACA,gBAAiB,CACf,YAAa,sDACb,KAAM,SACN,MAAO,CACL,CAAE,KAAM,wBAAyB,EACjC,CACE,WAAY,CACV,QAAS,CACP,YAAa,mCACb,KAAM,4BACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,sBAAuB,EACzB,EACA,mBAAoB,CAClB,YAAa,qDACb,KAAM,SACN,WAAY,CACV,gBAAiB,CACf,YACE,mFACF,KAAM,SACR,EACA,QAAS,CACP,YAAa,iEACb,KAAM,yBACR,EACA,YAAa,CACX,YAAa,sEACb,KAAM,0BACR,CACF,EACA,qBAAsB,EACxB,CACF,CACF,EAEA,OAAO,OAAOA,EAAkB","x_google_ignoreList":[9,10,12]} \ No newline at end of file +{"version":3,"file":"index.cjs","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/mutex.ts","../src/mutex-map.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { Mutex as AsyncMutex } from 'async-mutex';\n\n// Extending Mutex from async-mutex so we can add JSDoc\n\n/**\n * Class that allows calling asynchronous functions multiple times at once while only running one at\n * a time.\n *\n * @example\n *\n * ```typescript\n * const mutex = new Mutex();\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n * ```\n *\n * See [`async-mutex`](https://www.npmjs.com/package/async-mutex) for more information.\n */\nclass Mutex extends AsyncMutex {}\n\nexport default Mutex;\n","import Mutex from './mutex';\n\n/** Map of {@link Mutex}es that automatically (lazily) generates a new {@link Mutex} for any new key */\nclass MutexMap {\n private mutexesByID = new Map();\n\n get(mutexID: string): Mutex {\n let retVal = this.mutexesByID.get(mutexID);\n if (retVal) return retVal;\n\n retVal = new Mutex();\n this.mutexesByID.set(mutexID, retVal);\n return retVal;\n }\n}\n\nexport default MutexMap;\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * This function mirrors the `at` function from the JavaScript Standard String object. It handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * Finds the Unicode code point at the given index.\n *\n * @param string String to index\n * @param index Position of the character to be returned in range of -length(string) to\n * length(string)\n * @returns New string consisting of the Unicode code point located at the specified offset,\n * undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > stringLength(string) || index < -stringLength(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * This function mirrors the `charAt` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a new string consisting of the single unicode code point at the given index.\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns New string consisting of the Unicode code point located at the specified offset, empty\n * string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > stringLength(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * This function mirrors the `codePointAt` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index.\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns Non-negative integer representing the code point value of the character at the given\n * index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > stringLength(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * This function mirrors the `endsWith` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Determines whether a string ends with the characters of this string.\n *\n * @param string String to search through\n * @param searchString Characters to search for at the end of the string\n * @param endPosition End position where searchString is expected to be found. Default is\n * `length(string)`\n * @returns True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = stringLength(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + stringLength(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * This function mirrors the `includes` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Performs a case-sensitive search to determine if searchString is found in string.\n *\n * @param string String to search through\n * @param searchString String to search for\n * @param position Position within the string to start searching for searchString. Default is `0`\n * @returns True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * This function mirrors the `indexOf` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns the index of the first occurrence of a given string.\n *\n * @param string String to search through\n * @param searchString The string to search for\n * @param position Start of searching. Default is `0`\n * @returns Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * This function mirrors the `lastIndexOf` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Searches this string and returns the index of the last occurrence of the specified substring.\n *\n * @param string String to search through\n * @param searchString Substring to search for\n * @param position The index at which to begin searching. If omitted, the search begins at the end\n * of the string. Default is `undefined`\n * @returns Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(string: string, searchString: string, position?: number): number {\n let validatedPosition = position === undefined ? stringLength(string) : position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= stringLength(string)) {\n validatedPosition = stringLength(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, stringLength(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * This function mirrors the `length` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns the length of a string.\n *\n * @param string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function stringLength(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * This function mirrors the `normalize` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns the Unicode Normalization Form of this string.\n *\n * @param string The starting string\n * @param form Form specifying the Unicode Normalization Form. Default is `'NFC'`\n * @returns A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * This function mirrors the `padEnd` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string.\n *\n * @param string String to add padding too\n * @param targetLength The length of the resulting string once the starting string has been padded.\n * If value is less than or equal to length(string), then string is returned as is.\n * @param padString The string to pad the current string with. If padString is too long to stay\n * within targetLength, it will be truncated. Default is `\" \"`\n * @returns String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= stringLength(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * This function mirrors the `padStart` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string.\n *\n * @param string String to add padding too\n * @param targetLength The length of the resulting string once the starting string has been padded.\n * If value is less than or equal to length(string), then string is returned as is.\n * @param padString The string to pad the current string with. If padString is too long to stay\n * within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= stringLength(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\n// This is a helper function that performs a correction on the slice index to make sure it\n// cannot go out of bounds\nfunction correctSliceIndex(length: number, index: number) {\n if (index > length) return length;\n if (index < -length) return 0;\n if (index < 0) return index + length;\n return index;\n}\n\n/**\n * This function mirrors the `slice` function from the JavaScript Standard String object. It handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string.\n *\n * @param string The starting string\n * @param indexStart The index of the first character to include in the returned substring.\n * @param indexEnd The index of the first character to exclude from the returned substring.\n * @returns A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const length: number = stringLength(string);\n if (\n indexStart > length ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(indexStart > 0 && indexStart < length && indexEnd < 0 && indexEnd > -length)) ||\n indexEnd < -length ||\n (indexStart < 0 && indexStart > -length && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(length, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(length, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * This function mirrors the `split` function from the JavaScript Standard String object. It handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array.\n *\n * @param string The string to split\n * @param separator The pattern describing where each split should occur\n * @param splitLimit Limit on the number of substrings to be included in the array. Splits the\n * string at each occurrence of specified separator, but stops when limit entries have been placed\n * in the array.\n * @returns An array of strings, split at each point where separator occurs in the starting string.\n * Returns undefined if separator is not found in string.\n */\nexport function split(string: string, separator: string | RegExp, splitLimit?: number): string[] {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !includes(separator.flags, 'g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return [string];\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = stringLength(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * This function mirrors the `startsWith` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate.\n *\n * @param string String to search through\n * @param searchString The characters to be searched for at the start of this string.\n * @param position The start position at which searchString is expected to be found (the index of\n * searchString's first character). Default is `0`\n * @returns True if the given characters are found at the beginning of the string, including when\n * searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * This function mirrors the `substr` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a substring by providing start and length. This function is not exported because it is\n * considered deprecated, however it is still useful as a local helper function.\n *\n * @param string String to be divided\n * @param begin Start position. Default is `Start of string`\n * @param len Length of result. Default is `String length minus start parameter`. Default is `String\n * length minus start parameter`\n * @returns Substring from starting string\n */\nfunction substr(\n string: string,\n begin: number = 0,\n len: number = stringLength(string) - begin,\n): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * This function mirrors the `substring` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a substring by providing start and end position.\n *\n * @param string String to be divided\n * @param begin Start position\n * @param end End position. Default is `End of string`\n * @returns Substring from starting string\n */\nexport function substring(\n string: string,\n begin: number,\n end: number = stringLength(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * This function mirrors the `toArray` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Converts a string to an array of string characters.\n *\n * @param string String to convert to array\n * @returns An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","Mutex","AsyncMutex","MutexMap","mutexID","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","stringLength","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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CAAC,OAAO,EAClB,qBAAsB,EACxB,EACA,CACE,WAAY,CACV,SAAU,CACR,YAAa,8DACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,yGACF,KAAM,QACR,EACA,aAAc,CACZ,YACE,iFACF,KAAM,SACR,CACF,EACA,SAAU,CAAC,WAAY,OAAO,EAC9B,qBAAsB,EACxB,CACF,CACF,CACF,EACA,qBAAsB,EACxB,EACA,SAAU,CACR,YACE,mGACF,KAAM,SACN,MAAO,CACL,CACE,WAAY,CACV,GAAI,CACF,YAAa,6CACb,KAAM,wBACR,CACF,EACA,SAAU,CAAC,IAAI,CACjB,EACA,CACE,WAAY,CACV,QAAS,CACP,YAAa,mEACb,KAAM,wBACR,EACA,eAAgB,CACd,YAAa,mDACb,KAAM,QACR,EACA,cAAe,CACb,YAAa,kDACb,KAAM,QACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,WAAY,CACV,MAAO,CACL,YAAa,4DACb,KAAM,qBACR,EACA,QAAS,CACP,YACE,uFACF,KAAM,qBACR,EACA,YAAa,CACX,YACE,6GACF,KAAM,qBACR,EACA,cAAe,CACb,YACE,wFACF,KAAM,QACR,EACA,MAAO,CACL,YAAa,wCACb,KAAM,wBACR,EACA,MAAO,CACL,YACE,qGACF,KAAM,QACR,CACF,EACA,SAAU,CAAC,QAAS,QAAS,OAAO,EACpC,sBAAuB,EACzB,EACA,eAAgB,CACd,YAAa,2BACb,KAAM,SACN,WAAY,CACV,OAAQ,CACN,YAAa,kCACb,KAAM,oBACR,EACA,MAAO,CACL,YAAa,8CACb,KAAM,QACN,MAAO,CAAE,KAAM,kBAAmB,EAClC,YAAa,EACf,CACF,EACA,SAAU,CAAC,SAAU,OAAO,CAC9B,EACA,iBAAkB,CAChB,YAAa,+CACb,KAAM,SACN,MAAO,CAAC,CAAE,KAAM,yBAA0B,EAC1C,sBAAuB,EACzB,EACA,gBAAiB,CACf,YAAa,sDACb,KAAM,SACN,MAAO,CACL,CAAE,KAAM,wBAAyB,EACjC,CACE,WAAY,CACV,QAAS,CACP,YAAa,mCACb,KAAM,4BACR,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,sBAAuB,EACzB,EACA,mBAAoB,CAClB,YAAa,qDACb,KAAM,SACN,WAAY,CACV,gBAAiB,CACf,YACE,mFACF,KAAM,SACR,EACA,QAAS,CACP,YAAa,iEACb,KAAM,yBACR,EACA,YAAa,CACX,YAAa,sEACb,KAAM,0BACR,CACF,EACA,qBAAsB,EACxB,CACF,CACF,EAEA,OAAO,OAAOA,EAAkB","x_google_ignoreList":[9,10,12]} \ No newline at end of file diff --git a/lib/platform-bible-utils/dist/index.d.ts b/lib/platform-bible-utils/dist/index.d.ts index 798be2391f..87a7eefcc5 100644 --- a/lib/platform-bible-utils/dist/index.d.ts +++ b/lib/platform-bible-utils/dist/index.d.ts @@ -404,63 +404,75 @@ export declare function getAllObjectFunctionNames(obj: { */ export declare function createSyncProxyForAsyncObject(getObject: (args?: unknown[]) => Promise, objectToProxy?: Partial): T; /** - * Finds the Unicode code point at the given index. This function handles Unicode code points - * instead of UTF-16 character codes. + * This function mirrors the `at` function from the JavaScript Standard String object. It handles + * Unicode code points instead of UTF-16 character codes. + * + * Finds the Unicode code point at the given index. * * @param string String to index * @param index Position of the character to be returned in range of -length(string) to - * length(string) - * @returns New string consisting of the Unicode code point located at the specified - * offset, undefined if index is out of bounds + * length(string) + * @returns New string consisting of the Unicode code point located at the specified offset, + * undefined if index is out of bounds */ export declare function at(string: string, index: number): string | undefined; /** - * Returns a new string consisting of the single UTF-16 code unit at the given index. - * This function handles Unicode code points instead of UTF-16 character codes. + * This function mirrors the `charAt` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. + * + * Returns a new string consisting of the single unicode code point at the given index. * * @param string String to index * @param index Position of the string character to be returned, in the range of 0 to * length(string)-1 - * @returns New string consisting of the Unicode code point located at the specified - * offset, empty string if index is out of bounds + * @returns New string consisting of the Unicode code point located at the specified offset, empty + * string if index is out of bounds */ export declare function charAt(string: string, index: number): string; /** + * This function mirrors the `codePointAt` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. + * * Returns a non-negative integer that is the Unicode code point value of the character starting at - * the given index. This function handles Unicode code points instead of UTF-16 character codes. + * the given index. * * @param string String to index * @param index Position of the string character to be returned, in the range of 0 to * length(string)-1 - * @returns Non-negative integer representing the code point value of the - * character at the given index, or undefined if there is no element at that position + * @returns Non-negative integer representing the code point value of the character at the given + * index, or undefined if there is no element at that position */ export declare function codePointAt(string: string, index: number): number | undefined; /** - * Determines whether a string ends with the characters of this string. This function handles - * Unicode code points instead of UTF-16 character codes. + * This function mirrors the `endsWith` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. + * + * Determines whether a string ends with the characters of this string. * * @param string String to search through * @param searchString Characters to search for at the end of the string - * @param endPosition End position where searchString is expected to be - * found. Default is `length(string)` + * @param endPosition End position where searchString is expected to be found. Default is + * `length(string)` * @returns True if it ends with searchString, false if it does not */ export declare function endsWith(string: string, searchString: string, endPosition?: number): boolean; /** - * Performs a case-sensitive search to determine if searchString is found in string. This function + * This function mirrors the `includes` function from the JavaScript Standard String object. It * handles Unicode code points instead of UTF-16 character codes. * + * Performs a case-sensitive search to determine if searchString is found in string. + * * @param string String to search through * @param searchString String to search for - * @param position Position within the string to start searching for searchString. - * Default is `0` + * @param position Position within the string to start searching for searchString. Default is `0` * @returns True if search string is found, false if it is not */ export declare function includes(string: string, searchString: string, position?: number): boolean; /** - * Returns the index of the first occurrence of a given string. This function handles Unicode code - * points instead of UTF-16 character codes. + * This function mirrors the `indexOf` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. + * + * Returns the index of the first occurrence of a given string. * * @param string String to search through * @param searchString The string to search for @@ -469,18 +481,32 @@ export declare function includes(string: string, searchString: string, position? */ export declare function indexOf(string: string, searchString: string, position?: number | undefined): number; /** + * This function mirrors the `lastIndexOf` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. + * * Searches this string and returns the index of the last occurrence of the specified substring. - * This function handles Unicode code points instead of UTF-16 character codes. * * @param string String to search through * @param searchString Substring to search for * @param position The index at which to begin searching. If omitted, the search begins at the end - * of the string. Default is `undefined` + * of the string. Default is `undefined` * @returns Index of the last occurrence of searchString found, or -1 if not found. */ export declare function lastIndexOf(string: string, searchString: string, position?: number): number; -declare function length$1(string: string): number; /** + * This function mirrors the `length` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. + * + * Returns the length of a string. + * + * @param string String to return the length for + * @returns Number that is length of the starting string + */ +export declare function stringLength(string: string): number; +/** + * This function mirrors the `normalize` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. + * * Returns the Unicode Normalization Form of this string. * * @param string The starting string @@ -489,34 +515,41 @@ declare function length$1(string: string): number; */ export declare function normalize(string: string, form: "NFC" | "NFD" | "NFKC" | "NFKD" | "none"): string; /** - * Pads this string with another string (multiple times, if needed) until the resulting string - * reaches the given length. The padding is applied from the end of this string. This function + * This function mirrors the `padEnd` function from the JavaScript Standard String object. It * handles Unicode code points instead of UTF-16 character codes. * + * Pads this string with another string (multiple times, if needed) until the resulting string + * reaches the given length. The padding is applied from the end of this string. + * * @param string String to add padding too - * @param targetLength The length of the resulting string once the starting string has been - * padded. If value is less than or equal to length(string), then string is returned as is. - * @param padString The string to pad the current string with. If padString is too - * long to stay within targetLength, it will be truncated. Default is `" "` + * @param targetLength The length of the resulting string once the starting string has been padded. + * If value is less than or equal to length(string), then string is returned as is. + * @param padString The string to pad the current string with. If padString is too long to stay + * within targetLength, it will be truncated. Default is `" "` * @returns String with appropriate padding at the end */ export declare function padEnd(string: string, targetLength: number, padString?: string): string; /** - * Pads this string with another string (multiple times, if needed) until the resulting string - * reaches the given length. The padding is applied from the start of this string. This function + * This function mirrors the `padStart` function from the JavaScript Standard String object. It * handles Unicode code points instead of UTF-16 character codes. * + * Pads this string with another string (multiple times, if needed) until the resulting string + * reaches the given length. The padding is applied from the start of this string. + * * @param string String to add padding too - * @param targetLength The length of the resulting string once the starting string has been - * padded. If value is less than or equal to length(string), then string is returned as is. - * @param padString The string to pad the current string with. If padString is too - * long to stay within the targetLength, it will be truncated from the end. Default is `" "` + * @param targetLength The length of the resulting string once the starting string has been padded. + * If value is less than or equal to length(string), then string is returned as is. + * @param padString The string to pad the current string with. If padString is too long to stay + * within the targetLength, it will be truncated from the end. Default is `" "` * @returns String with of specified targetLength with padString applied from the start */ export declare function padStart(string: string, targetLength: number, padString?: string): string; /** + * This function mirrors the `slice` function from the JavaScript Standard String object. It handles + * Unicode code points instead of UTF-16 character codes. + * * Extracts a section of this string and returns it as a new string, without modifying the original - * string. This function handles Unicode code points instead of UTF-16 character codes. + * string. * * @param string The starting string * @param indexStart The index of the first character to include in the returned substring. @@ -525,35 +558,41 @@ export declare function padStart(string: string, targetLength: number, padString */ export declare function slice(string: string, indexStart: number, indexEnd?: number): string; /** - * Takes a pattern and divides the string into an ordered list of substrings by searching for the - * pattern, puts these substrings into an array, and returns the array. This function handles + * This function mirrors the `split` function from the JavaScript Standard String object. It handles * Unicode code points instead of UTF-16 character codes. * + * Takes a pattern and divides the string into an ordered list of substrings by searching for the + * pattern, puts these substrings into an array, and returns the array. + * * @param string The string to split * @param separator The pattern describing where each split should occur - * @param splitLimit Limit on the number of substrings to be included in the array. Splits - * the string at each occurrence of specified separator, but stops when limit entries have been - * placed in the array. - * @returns An array of strings, split at each point where separator occurs - * in the starting string. Returns undefined if separator is not found in string. + * @param splitLimit Limit on the number of substrings to be included in the array. Splits the + * string at each occurrence of specified separator, but stops when limit entries have been placed + * in the array. + * @returns An array of strings, split at each point where separator occurs in the starting string. + * Returns undefined if separator is not found in string. */ export declare function split(string: string, separator: string | RegExp, splitLimit?: number): string[]; /** + * This function mirrors the `startsWith` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. + * * Determines whether the string begins with the characters of a specified string, returning true or - * false as appropriate. This function handles Unicode code points instead of UTF-16 character - * codes. + * false as appropriate. * * @param string String to search through * @param searchString The characters to be searched for at the start of this string. - * @param position The start position at which searchString is expected to be found - * (the index of searchString's first character). Default is `0` - * @returns True if the given characters are found at the beginning of the string, - * including when searchString is an empty string; otherwise, false. + * @param position The start position at which searchString is expected to be found (the index of + * searchString's first character). Default is `0` + * @returns True if the given characters are found at the beginning of the string, including when + * searchString is an empty string; otherwise, false. */ export declare function startsWith(string: string, searchString: string, position?: number): boolean; /** - * Returns a substring by providing start and end position. This function handles Unicode code - * points instead of UTF-16 character codes. + * This function mirrors the `substring` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. + * + * Returns a substring by providing start and end position. * * @param string String to be divided * @param begin Start position @@ -562,8 +601,10 @@ export declare function startsWith(string: string, searchString: string, positio */ export declare function substring(string: string, begin: number, end?: number): string; /** - * Converts a string to an array of string characters. This function handles Unicode code points - * instead of UTF-16 character codes. + * This function mirrors the `toArray` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. + * + * Converts a string to an array of string characters. * * @param string String to convert to array * @returns An array of characters from the starting string @@ -1016,8 +1057,4 @@ export declare const menuDocumentSchema: { }; }; -export { - length$1 as length, -}; - export {}; diff --git a/lib/platform-bible-utils/dist/index.js b/lib/platform-bible-utils/dist/index.js index 955a1b03a0..b4d1351d52 100644 --- a/lib/platform-bible-utils/dist/index.js +++ b/lib/platform-bible-utils/dist/index.js @@ -571,7 +571,7 @@ function C(t, e, r = 0) { return Ae(t, e, r); } function je(t, e, r) { - let s = r || m(t); + let s = r === void 0 ? m(t) : r; s < 0 ? s = 0 : s >= m(t) && (s = m(t) - 1); for (let n = s; n >= 0; n--) if (q(t, n, m(e)) === e) @@ -1159,7 +1159,6 @@ export { Tt as isSerializable, ne as isString, je as lastIndexOf, - m as length, tt as menuDocumentSchema, at as newGuid, qt as normalize, @@ -1172,6 +1171,7 @@ export { St as slice, Ct as split, Pt as startsWith, + m as stringLength, $ as substring, Me as toArray, ie as wait, diff --git a/lib/platform-bible-utils/dist/index.js.map b/lib/platform-bible-utils/dist/index.js.map index d12e38b4be..adc1f8e3ae 100644 --- a/lib/platform-bible-utils/dist/index.js.map +++ b/lib/platform-bible-utils/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/mutex.ts","../src/mutex-map.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { Mutex as AsyncMutex } from 'async-mutex';\n\n// Extending Mutex from async-mutex so we can add JSDoc\n\n/**\n * Class that allows calling asynchronous functions multiple times at once while only running one at\n * a time.\n *\n * @example\n *\n * ```typescript\n * const mutex = new Mutex();\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n * ```\n *\n * See [`async-mutex`](https://www.npmjs.com/package/async-mutex) for more information.\n */\nclass Mutex extends AsyncMutex {}\n\nexport default Mutex;\n","import Mutex from './mutex';\n\n/** Map of {@link Mutex}es that automatically (lazily) generates a new {@link Mutex} for any new key */\nclass MutexMap {\n private mutexesByID = new Map();\n\n get(mutexID: string): Mutex {\n let retVal = this.mutexesByID.get(mutexID);\n if (retVal) return retVal;\n\n retVal = new Mutex();\n this.mutexesByID.set(mutexID, retVal);\n return retVal;\n }\n}\n\nexport default MutexMap;\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * Finds the Unicode code point at the given index. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param string String to index\n * @param index Position of the character to be returned in range of -length(string) to\n * length(string)\n * @returns New string consisting of the Unicode code point located at the specified\n * offset, undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > length(string) || index < -length(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * Returns a new string consisting of the single UTF-16 code unit at the given index.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns New string consisting of the Unicode code point located at the specified\n * offset, empty string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > length(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns Non-negative integer representing the code point value of the\n * character at the given index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > length(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * Determines whether a string ends with the characters of this string. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to search through\n * @param searchString Characters to search for at the end of the string\n * @param endPosition End position where searchString is expected to be\n * found. Default is `length(string)`\n * @returns True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = length(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + length(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * Performs a case-sensitive search to determine if searchString is found in string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to search through\n * @param searchString String to search for\n * @param position Position within the string to start searching for searchString.\n * Default is `0`\n * @returns True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * Returns the index of the first occurrence of a given string. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param string String to search through\n * @param searchString The string to search for\n * @param position Start of searching. Default is `0`\n * @returns Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * Searches this string and returns the index of the last occurrence of the specified substring.\n * This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to search through\n * @param searchString Substring to search for\n * @param position The index at which to begin searching. If omitted, the search begins at the end\n * of the string. Default is `undefined`\n * @returns Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(\n string: string,\n searchString: string,\n position?: number,\n): number {\n let validatedPosition = position ? position : length(string);\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= length(string)) {\n validatedPosition = length(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, length(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * Returns the length of a string. This function handles Unicode code points instead of UTF-16\n * character codes.\n *\n * @param string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function length(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * Returns the Unicode Normalization Form of this string.\n *\n * @param string The starting string\n * @param form Form specifying the Unicode Normalization Form. Default is `'NFC'`\n * @returns A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to add padding too\n * @param targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param padString The string to pad the current string with. If padString is too\n * long to stay within targetLength, it will be truncated. Default is `\" \"`\n * @returns String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string. This function\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string String to add padding too\n * @param targetLength The length of the resulting string once the starting string has been\n * padded. If value is less than or equal to length(string), then string is returned as is.\n * @param padString The string to pad the current string with. If padString is too\n * long to stay within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= length(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\nfunction correctSliceIndex(stringLength: number, index: number) {\n if (index > stringLength) return stringLength;\n if (index < -stringLength) return 0;\n if (index < 0) return index + stringLength;\n return index;\n}\n\n/**\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string. This function handles Unicode code points instead of UTF-16 character codes.\n *\n * @param string The starting string\n * @param indexStart The index of the first character to include in the returned substring.\n * @param indexEnd The index of the first character to exclude from the returned substring.\n * @returns A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const stringLength: number = length(string);\n if (\n indexStart > stringLength ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(\n indexStart > 0 &&\n indexStart < stringLength &&\n indexEnd < 0 &&\n indexEnd > -stringLength\n )) ||\n indexEnd < -stringLength ||\n (indexStart < 0 && indexStart > -stringLength && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(stringLength, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array. This function handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * @param string The string to split\n * @param separator The pattern describing where each split should occur\n * @param splitLimit Limit on the number of substrings to be included in the array. Splits\n * the string at each occurrence of specified separator, but stops when limit entries have been\n * placed in the array.\n * @returns An array of strings, split at each point where separator occurs\n * in the starting string. Returns undefined if separator is not found in string.\n */\nexport function split(string: string, separator: string | RegExp, splitLimit?: number): string[] {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !includes(separator.flags, 'g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return [string];\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = length(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate. This function handles Unicode code points instead of UTF-16 character\n * codes.\n *\n * @param string String to search through\n * @param searchString The characters to be searched for at the start of this string.\n * @param position The start position at which searchString is expected to be found\n * (the index of searchString's first character). Default is `0`\n * @returns True if the given characters are found at the beginning of the string,\n * including when searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * Returns a substring by providing start and length. This function handles Unicode code points\n * instead of UTF-16 character codes. This function is not exported because it is considered\n * deprecated, however it is still useful as a local helper function.\n *\n * @param string String to be divided\n * @param begin Start position. Default is `Start of string`\n * @param len Length of result. Default is `String\n * length minus start parameter`. Default is `String length minus start parameter`\n * @returns Substring from starting string\n */\nfunction substr(string: string, begin: number = 0, len: number = length(string) - begin): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * Returns a substring by providing start and end position. This function handles Unicode code\n * points instead of UTF-16 character codes.\n *\n * @param string String to be divided\n * @param begin Start position\n * @param end End position. Default is `End of string`\n * @returns Substring from starting string\n */\nexport function substring(\n string: string,\n begin: number,\n end: number = length(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * Converts a string to an array of string characters. This function handles Unicode code points\n * instead of UTF-16 character codes.\n *\n * @param string String to convert to array\n * @returns An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","Mutex","AsyncMutex","MutexMap","mutexID","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","stringLength","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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","x_google_ignoreList":[9,10,12]} \ No newline at end of file +{"version":3,"file":"index.js","sources":["../src/async-variable.ts","../src/util.ts","../src/document-combiner-engine.ts","../src/unsubscriber-async-list.ts","../src/platform-event-emitter.model.ts","../src/mutex.ts","../src/mutex-map.ts","../src/scripture-util.ts","../src/unsubscriber.ts","../node_modules/char-regex/index.js","../node_modules/stringz/dist/index.js","../src/string-util.ts","../../../node_modules/fast-equals/dist/esm/index.mjs","../src/equality-checking.ts","../src/serialization.ts","../src/menus.model.ts"],"sourcesContent":["/** This class provides a convenient way for one task to wait on a variable that another task sets. */\nexport default class AsyncVariable {\n private readonly variableName: string;\n private readonly promiseToValue: Promise;\n private resolver: ((value: T) => void) | undefined;\n private rejecter: ((reason: string | undefined) => void) | undefined;\n\n /**\n * Creates an instance of the class\n *\n * @param variableName Name to use when logging about this variable\n * @param rejectIfNotSettledWithinMS Milliseconds to wait before verifying if the promise was\n * settled (resolved or rejected); will reject if it has not settled by that time. Use -1 if you\n * do not want a timeout at all.\n */\n constructor(variableName: string, rejectIfNotSettledWithinMS: number = 10000) {\n this.variableName = variableName;\n this.promiseToValue = new Promise((resolve, reject) => {\n this.resolver = resolve;\n this.rejecter = reject;\n });\n if (rejectIfNotSettledWithinMS > 0) {\n setTimeout(() => {\n if (this.rejecter) {\n this.rejecter(`Timeout reached when waiting for ${this.variableName} to settle`);\n this.complete();\n }\n }, rejectIfNotSettledWithinMS);\n }\n Object.seal(this);\n }\n\n /**\n * Get this variable's promise to a value. This always returns the same promise even after the\n * value has been resolved or rejected.\n *\n * @returns The promise for the value to be set\n */\n get promise(): Promise {\n return this.promiseToValue;\n }\n\n /**\n * A simple way to see if this variable's promise was resolved or rejected already\n *\n * @returns Whether the variable was already resolved or rejected\n */\n get hasSettled(): boolean {\n return Object.isFrozen(this);\n }\n\n /**\n * Resolve this variable's promise to the given value\n *\n * @param value This variable's promise will resolve to this value\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n resolveToValue(value: T, throwIfAlreadySettled: boolean = false): void {\n if (this.resolver) {\n console.debug(`${this.variableName} is being resolved now`);\n this.resolver(value);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent resolution of ${this.variableName}`);\n }\n }\n\n /**\n * Reject this variable's promise for the value with the given reason\n *\n * @param reason This variable's promise will be rejected with this reason\n * @param throwIfAlreadySettled Determines whether to throw if the variable was already resolved\n * or rejected\n */\n rejectWithReason(reason: string, throwIfAlreadySettled: boolean = false): void {\n if (this.rejecter) {\n console.debug(`${this.variableName} is being rejected now`);\n this.rejecter(reason);\n this.complete();\n } else {\n if (throwIfAlreadySettled) throw Error(`${this.variableName} was already settled`);\n console.debug(`Ignoring subsequent rejection of ${this.variableName}`);\n }\n }\n\n /** Prevent any further updates to this variable */\n private complete(): void {\n this.resolver = undefined;\n this.rejecter = undefined;\n Object.freeze(this);\n }\n}\n","/** Collection of functions, objects, and types that are used as helpers in other services. */\n\n// Thanks to blubberdiblub at https://stackoverflow.com/a/68141099/217579\nexport function newGuid(): string {\n return '00-0-4-1-000'.replace(/[^-]/g, (s) =>\n // @ts-expect-error ts(2363) this works fine\n // eslint-disable-next-line no-bitwise\n (((Math.random() + ~~s) * 0x10000) >> s).toString(16).padStart(4, '0'),\n );\n}\n\n// thanks to DRAX at https://stackoverflow.com/a/9436948\n/**\n * Determine whether the object is a string\n *\n * @param o Object to determine if it is a string\n * @returns True if the object is a string; false otherwise\n */\nexport function isString(o: unknown): o is string {\n return typeof o === 'string' || o instanceof String;\n}\n\n/**\n * If deepClone isn't used when copying properties between objects, you may be left with dangling\n * references between the source and target of property copying operations.\n *\n * @param obj Object to clone\n * @returns Duplicate copy of `obj` without any references back to the original one\n */\nexport function deepClone(obj: T): T {\n // Assert the return type matches what is expected\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\n/**\n * Get a function that reduces calls to the function passed in\n *\n * @param fn The function to debounce\n * @param delay How much delay in milliseconds after the most recent call to the debounced function\n * to call the function\n * @returns Function that, when called, only calls the function passed in at maximum every delay ms\n */\n// We don't know the parameter types since this function can be anything\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function debounce void>(fn: T, delay = 300): T {\n if (isString(fn)) throw new Error('Tried to debounce a string! Could be XSS');\n let timeout: ReturnType;\n // Ensure the right return type.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return ((...args) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => fn(...args), delay);\n }) as T;\n}\n\n/**\n * Groups each item in the array of items into a map according to the keySelector\n *\n * @param items Array of items to group by\n * @param keySelector Function to run on each item to get the key for the group to which it belongs\n * @param valueSelector Function to run on each item to get the value it should have in the group\n * (like map function). If not provided, uses the item itself\n * @returns Map of keys to groups of values corresponding to each item\n */\nexport function groupBy(items: T[], keySelector: (item: T) => K): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector: (item: T, key: K) => V,\n): Map>;\nexport function groupBy(\n items: T[],\n keySelector: (item: T) => K,\n valueSelector?: (item: T, key: K) => V,\n): Map> {\n const map = new Map>();\n items.forEach((item) => {\n const key = keySelector(item);\n const group = map.get(key);\n const value = valueSelector ? valueSelector(item, key) : item;\n if (group) group.push(value);\n else map.set(key, [value]);\n });\n return map;\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\ntype ErrorWithMessage = {\n message: string;\n};\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\nfunction isErrorWithMessage(error: unknown): error is ErrorWithMessage {\n return (\n typeof error === 'object' &&\n // We're potentially dealing with objects we didn't create, so they might contain `null`\n // eslint-disable-next-line no-null/no-null\n error !== null &&\n 'message' in error &&\n // Type assert `error` to check it's `message`.\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n typeof (error as Record).message === 'string'\n );\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error from the object (useful for getting an error in a catch block)\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nfunction toErrorWithMessage(maybeError: unknown): ErrorWithMessage {\n if (isErrorWithMessage(maybeError)) return maybeError;\n\n try {\n return new Error(JSON.stringify(maybeError));\n } catch {\n // fallback in case there's an error stringifying the maybeError\n // like with circular references for example.\n return new Error(String(maybeError));\n }\n}\n\n// From https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript\n/**\n * Function to get an error message from the object (useful for getting error message in a catch\n * block)\n *\n * @example `try {...} catch (e) { logger.info(getErrorMessage(e)) }`\n *\n * @param error Error object whose message to get\n * @returns Message of the error - if object has message, returns message. Otherwise tries to\n * stringify\n */\nexport function getErrorMessage(error: unknown) {\n return toErrorWithMessage(error).message;\n}\n\n/** Asynchronously waits for the specified number of milliseconds. (wraps setTimeout in a promise) */\nexport function wait(ms: number) {\n // eslint-disable-next-line no-promise-executor-return\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Runs the specified function and will timeout if it takes longer than the specified wait time\n *\n * @param fn The function to run\n * @param maxWaitTimeInMS The maximum amount of time to wait for the function to resolve\n * @returns Promise that resolves to the resolved value of the function or undefined if it ran\n * longer than the specified wait time\n */\nexport function waitForDuration(fn: () => Promise, maxWaitTimeInMS: number) {\n const timeout = wait(maxWaitTimeInMS).then(() => undefined);\n return Promise.any([timeout, fn()]);\n}\n\n/**\n * Get all functions on an object and its prototype chain (so we don't miss any class methods or any\n * object methods). Note that the functions on the final item in the prototype chain (i.e., Object)\n * are skipped to avoid including functions like `__defineGetter__`, `__defineSetter__`, `toString`,\n * etc.\n *\n * @param obj Object whose functions to get\n * @param objId Optional ID of the object to use for debug logging\n * @returns Array of all function names on an object\n */\n// Note: lodash has something that MIGHT do the same thing as this. Investigate for https://github.com/paranext/paranext-core/issues/134\nexport function getAllObjectFunctionNames(\n obj: { [property: string]: unknown },\n objId: string = 'obj',\n): Set {\n const objectFunctionNames = new Set();\n\n // Get all function properties directly defined on the object\n Object.getOwnPropertyNames(obj).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId} due to error: ${error}`);\n }\n });\n\n // Walk up the prototype chain and get additional function properties, skipping the functions\n // provided by the final (Object) prototype\n let objectPrototype = Object.getPrototypeOf(obj);\n while (objectPrototype && Object.getPrototypeOf(objectPrototype)) {\n Object.getOwnPropertyNames(objectPrototype).forEach((property) => {\n try {\n if (typeof obj[property] === 'function') objectFunctionNames.add(property);\n } catch (error) {\n console.debug(`Skipping ${property} on ${objId}'s prototype due to error: ${error}`);\n }\n });\n objectPrototype = Object.getPrototypeOf(objectPrototype);\n }\n\n return objectFunctionNames;\n}\n\n/**\n * Creates a synchronous proxy for an asynchronous object. The proxy allows calling methods on an\n * object that is asynchronously fetched using a provided asynchronous function.\n *\n * @param getObject - A function that returns a promise resolving to the object whose asynchronous\n * methods to call.\n * @param objectToProxy - An optional object that is the object that is proxied. If a property is\n * accessed that does exist on this object, it will be returned. If a property is accessed that\n * does not exist on this object, it will be considered to be an asynchronous method called on the\n * object returned from getObject.\n * @returns A synchronous proxy for the asynchronous object.\n */\nexport function createSyncProxyForAsyncObject(\n getObject: (args?: unknown[]) => Promise,\n objectToProxy: Partial = {},\n): T {\n // objectToProxy will have only the synchronously accessed properties of T on it, and this proxy\n // makes the async methods that do not exist yet available synchronously so we have all of T\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n return new Proxy(objectToProxy as T, {\n get(target, prop) {\n // We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // @ts-expect-error 7053\n if (prop in target) return target[prop];\n return async (...args: unknown[]) => {\n // 7053: We don't have any type information for T, so we assume methodName exists on it and will let JavaScript throw if it doesn't exist\n // 2556: The args here are the parameters for the method specified\n // @ts-expect-error 7053 2556\n return (await getObject())[prop](...args);\n };\n },\n });\n}\n","import { deepClone } from './util';\n\nexport type JsonDocumentLike = { [key: string]: unknown };\n\n/**\n * Options for DocumentCombinerEngine objects\n *\n * - `copyDocuments`: If true, this instance will perform a deep copy of all provided documents before\n * composing the output. If false, then changes made to provided documents after they are\n * contributed will be reflected in the next time output is composed.\n * - `ignoreDuplicateProperties`: If true, then duplicate properties are skipped if they are seen in\n * contributed documents. If false, then throw when duplicate properties are seen in contributed\n * documents.\n */\nexport type DocumentCombinerOptions = {\n copyDocuments: boolean;\n ignoreDuplicateProperties: boolean;\n};\n\n/**\n * Base class for any code that wants to compose JSON documents (in the form of JS objects) together\n * into a single output document.\n */\nexport default abstract class DocumentCombinerEngine {\n protected baseDocument: JsonDocumentLike;\n protected readonly contributions = new Map();\n protected latestOutput: JsonDocumentLike | undefined;\n protected readonly options: DocumentCombinerOptions;\n\n /**\n * Create a DocumentCombinerEngine instance\n *\n * @param baseDocument This is the first document that will be used when composing the output\n * @param options Options used by this object when combining documents\n */\n protected constructor(baseDocument: JsonDocumentLike, options: DocumentCombinerOptions) {\n // Setting baseDocument redundantly because TS doesn't understand that updateBaseDocument does it\n this.baseDocument = baseDocument;\n this.options = options;\n this.updateBaseDocument(baseDocument);\n }\n\n /**\n * Update the starting document for composition process\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n * @returns Recalculated output document given the new starting state and existing other documents\n */\n updateBaseDocument(baseDocument: JsonDocumentLike): JsonDocumentLike | undefined {\n this.validateStartingDocument(baseDocument);\n this.baseDocument = this.options.copyDocuments ? deepClone(baseDocument) : baseDocument;\n return this.rebuild();\n }\n\n /**\n * Add or update one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n * @returns Recalculated output document given the new or updated contribution and existing other\n * documents\n */\n addOrUpdateContribution(\n documentName: string,\n document: JsonDocumentLike,\n ): JsonDocumentLike | undefined {\n this.validateContribution(documentName, document);\n const previousDocumentVersion = this.contributions.get(documentName);\n const documentToSet = this.options.copyDocuments && !!document ? deepClone(document) : document;\n this.contributions.set(documentName, documentToSet);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after adding/updating the contribution, put it back how it was\n if (previousDocumentVersion) this.contributions.set(documentName, previousDocumentVersion);\n else this.contributions.delete(documentName);\n throw new Error(`Error when setting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Delete one of the contribution documents for the composition process\n *\n * @param documentName Name of the contributed document to delete\n * @returns Recalculated output document given the remaining other documents\n */\n deleteContribution(documentName: string): object | undefined {\n const document = this.contributions.get(documentName);\n if (!document) throw new Error(`{documentKey} does not exist`);\n this.contributions.delete(documentName);\n try {\n return this.rebuild();\n } catch (error) {\n // If the output isn't valid after deleting the contribution, put it back and rethrow\n this.contributions.set(documentName, document);\n throw new Error(`Error when deleting the document named ${documentName}: ${error}`);\n }\n }\n\n /**\n * Run the document composition process given the starting document and all contributions. Throws\n * if the output document fails to validate properly.\n *\n * @returns Recalculated output document given the starting and contributed documents\n */\n rebuild(): JsonDocumentLike | undefined {\n // The starting document is the output if there are no other contributions\n if (this.contributions.size === 0) {\n let potentialOutput = deepClone(this.baseDocument);\n potentialOutput = this.transformFinalOutput(potentialOutput);\n this.validateOutput(potentialOutput);\n this.latestOutput = potentialOutput;\n return this.latestOutput;\n }\n\n // Compose the output by validating each document one at a time to pinpoint errors better\n let outputIteration = this.baseDocument;\n this.contributions.forEach((contribution: JsonDocumentLike) => {\n outputIteration = mergeObjects(\n outputIteration,\n contribution,\n this.options.ignoreDuplicateProperties,\n );\n this.validateOutput(outputIteration);\n });\n outputIteration = this.transformFinalOutput(outputIteration);\n this.validateOutput(outputIteration);\n this.latestOutput = outputIteration;\n return this.latestOutput;\n }\n\n /**\n * Throw an error if the provided document is not a valid starting document.\n *\n * @param baseDocument Base JSON document/JS object that all other documents are added to\n */\n protected abstract validateStartingDocument(baseDocument: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided document is not a valid contribution document.\n *\n * @param documentName Name of the contributed document to combine\n * @param document Content of the contributed document to combine\n */\n protected abstract validateContribution(documentName: string, document: JsonDocumentLike): void;\n\n /**\n * Throw an error if the provided output is not valid.\n *\n * @param output Output document that could potentially be returned to callers\n */\n protected abstract validateOutput(output: JsonDocumentLike): void;\n\n /**\n * Transform the document that is the composition of the base document and all contribution\n * documents. This is the last step that will be run prior to validation before\n * `this.latestOutput` is updated to the new output.\n *\n * @param finalOutput Final output document that could potentially be returned to callers. \"Final\"\n * means no further contribution documents will be merged.\n */\n protected abstract transformFinalOutput(finalOutput: JsonDocumentLike): JsonDocumentLike;\n}\n\n// #region Helper functions\n\n/**\n * Determines if the input values are objects but not arrays\n *\n * @param values Objects to check\n * @returns True if all the values are objects but not arrays\n */\nfunction areNonArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Determines if the input values are arrays\n *\n * @param value Objects to check\n * @returns True if the values are arrays\n */\nfunction areArrayObjects(...values: unknown[]): boolean {\n let allMatch = true;\n values.forEach((value: unknown) => {\n if (!value || typeof value !== 'object' || !Array.isArray(value)) allMatch = false;\n });\n return allMatch;\n}\n\n/**\n * Recursively merge the properties of one object (copyFrom) into another (startingPoint). Throws if\n * copyFrom would overwrite values already existing in startingPoint.\n *\n * @param startingPoint Object that is the starting point for the return value\n * @param copyFrom Object whose values are copied into the return value\n * @returns Object that is the combination of the two documents\n */\nfunction mergeObjects(\n startingPoint: JsonDocumentLike,\n copyFrom: JsonDocumentLike,\n ignoreDuplicateProperties: boolean,\n): JsonDocumentLike {\n const retVal = deepClone(startingPoint);\n if (!copyFrom) return retVal;\n\n Object.keys(copyFrom).forEach((key: string | number) => {\n if (Object.hasOwn(startingPoint, key)) {\n if (areNonArrayObjects(startingPoint[key], copyFrom[key])) {\n retVal[key] = mergeObjects(\n // We know these are objects from the `if` check\n /* eslint-disable no-type-assertion/no-type-assertion */\n startingPoint[key] as JsonDocumentLike,\n copyFrom[key] as JsonDocumentLike,\n ignoreDuplicateProperties,\n /* eslint-enable no-type-assertion/no-type-assertion */\n );\n } else if (areArrayObjects(startingPoint[key], copyFrom[key])) {\n // We know these are arrays because of the `else if` check\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n retVal[key] = (retVal[key] as Array).concat(copyFrom[key] as Array);\n } else if (!ignoreDuplicateProperties)\n throw new Error(`Cannot merge objects: key \"${key}\" already exists in the target object`);\n } else {\n retVal[key] = copyFrom[key];\n }\n });\n\n return retVal;\n}\n\n// #endregion\n","import { Dispose } from './disposal.model';\nimport { Unsubscriber, UnsubscriberAsync } from './unsubscriber';\n\n/** Simple collection for UnsubscriberAsync objects that also provides an easy way to run them. */\nexport default class UnsubscriberAsyncList {\n readonly unsubscribers = new Set();\n\n constructor(private name = 'Anonymous') {}\n\n /**\n * Add unsubscribers to the list. Note that duplicates are not added twice.\n *\n * @param unsubscribers - Objects that were returned from a registration process.\n */\n add(...unsubscribers: (UnsubscriberAsync | Unsubscriber | Dispose)[]) {\n unsubscribers.forEach((unsubscriber) => {\n if ('dispose' in unsubscriber) this.unsubscribers.add(unsubscriber.dispose);\n else this.unsubscribers.add(unsubscriber);\n });\n }\n\n /**\n * Run all unsubscribers added to this list and then clear the list.\n *\n * @returns `true` if all unsubscribers succeeded, `false` otherwise.\n */\n async runAllUnsubscribers(): Promise {\n const unsubs = [...this.unsubscribers].map((unsubscriber) => unsubscriber());\n const results = await Promise.all(unsubs);\n this.unsubscribers.clear();\n return results.every((unsubscriberSucceeded, index) => {\n if (!unsubscriberSucceeded)\n console.error(`UnsubscriberAsyncList ${this.name}: Unsubscriber at index ${index} failed!`);\n\n return unsubscriberSucceeded;\n });\n }\n}\n","/** Interfaces, classes, and functions related to events and event emitters */\n\nimport { Dispose } from './disposal.model';\nimport { PlatformEvent, PlatformEventHandler } from './platform-event';\n\n/**\n * Event manager - accepts subscriptions to an event and runs the subscription callbacks when the\n * event is emitted Use eventEmitter.event(callback) to subscribe to the event. Use\n * eventEmitter.emit(event) to run the subscriptions. Generally, this EventEmitter should be\n * private, and its event should be public. That way, the emitter is not publicized, but anyone can\n * subscribe to the event.\n */\nexport default class PlatformEventEmitter implements Dispose {\n /**\n * Subscribes a function to run when this event is emitted.\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n * @alias event\n */\n subscribe = this.event;\n\n /** All callback functions that will run when this event is emitted. Lazy loaded */\n private subscriptions?: PlatformEventHandler[];\n /** Event for listeners to subscribe to. Lazy loaded */\n private lazyEvent?: PlatformEvent;\n /** Whether this emitter has been disposed */\n private isDisposed = false;\n\n /**\n * Event for listeners to subscribe to. Subscribes a function to run when this event is emitted.\n * Use like `const unsubscriber = event(callback)`\n *\n * @param callback Function to run with the event when it is emitted\n * @returns Unsubscriber function to run to stop calling the passed-in function when the event is\n * emitted\n */\n get event(): PlatformEvent {\n this.assertNotDisposed();\n\n if (!this.lazyEvent) {\n this.lazyEvent = (callback) => {\n if (!callback || typeof callback !== 'function')\n throw new Error(`Event handler callback must be a function!`);\n\n // Initialize this.subscriptions if it does not exist\n if (!this.subscriptions) this.subscriptions = [];\n\n this.subscriptions.push(callback);\n\n return () => {\n if (!this.subscriptions) return false; // Did not find any subscribed callbacks\n\n const callbackIndex = this.subscriptions.indexOf(callback);\n\n if (callbackIndex < 0) return false; // Did not find this callback in the subscriptions\n\n // Remove the callback\n this.subscriptions.splice(callbackIndex, 1);\n\n return true;\n };\n };\n }\n return this.lazyEvent;\n }\n\n /** Disposes of this event, preparing it to release from memory */\n dispose = () => {\n return this.disposeFn();\n };\n\n /**\n * Runs the subscriptions for the event\n *\n * @param event Event data to provide to subscribed callbacks\n */\n emit = (event: T) => {\n // Do not do anything other than emitFn here. This emit is just binding `this` to emitFn\n this.emitFn(event);\n };\n\n /**\n * Function that runs the subscriptions for the event. Added here so children can override emit\n * and still call the base functionality. See NetworkEventEmitter.emit for example\n */\n protected emitFn(event: T) {\n this.assertNotDisposed();\n\n this.subscriptions?.forEach((callback) => callback(event));\n }\n\n /** Check to make sure this emitter is not disposed. Throw if it is */\n protected assertNotDisposed() {\n if (this.isDisposed) throw new Error('Emitter is disposed');\n }\n\n /**\n * Disposes of this event, preparing it to release from memory. Added here so children can\n * override emit and still call the base functionality.\n */\n protected disposeFn() {\n this.assertNotDisposed();\n\n this.isDisposed = true;\n this.subscriptions = undefined;\n this.lazyEvent = undefined;\n return Promise.resolve(true);\n }\n}\n","import { Mutex as AsyncMutex } from 'async-mutex';\n\n// Extending Mutex from async-mutex so we can add JSDoc\n\n/**\n * Class that allows calling asynchronous functions multiple times at once while only running one at\n * a time.\n *\n * @example\n *\n * ```typescript\n * const mutex = new Mutex();\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n *\n * mutex.runExclusive(async () => {\n * // Do some asynchronous stuff\n * console.log('These run one-at-a-time');\n * });\n * ```\n *\n * See [`async-mutex`](https://www.npmjs.com/package/async-mutex) for more information.\n */\nclass Mutex extends AsyncMutex {}\n\nexport default Mutex;\n","import Mutex from './mutex';\n\n/** Map of {@link Mutex}es that automatically (lazily) generates a new {@link Mutex} for any new key */\nclass MutexMap {\n private mutexesByID = new Map();\n\n get(mutexID: string): Mutex {\n let retVal = this.mutexesByID.get(mutexID);\n if (retVal) return retVal;\n\n retVal = new Mutex();\n this.mutexesByID.set(mutexID, retVal);\n return retVal;\n }\n}\n\nexport default MutexMap;\n","import { BookInfo, ScriptureReference } from './scripture.model';\n\nconst scrBookData: BookInfo[] = [\n { shortName: 'ERR', fullNames: ['ERROR'], chapters: -1 },\n { shortName: 'GEN', fullNames: ['Genesis'], chapters: 50 },\n { shortName: 'EXO', fullNames: ['Exodus'], chapters: 40 },\n { shortName: 'LEV', fullNames: ['Leviticus'], chapters: 27 },\n { shortName: 'NUM', fullNames: ['Numbers'], chapters: 36 },\n { shortName: 'DEU', fullNames: ['Deuteronomy'], chapters: 34 },\n { shortName: 'JOS', fullNames: ['Joshua'], chapters: 24 },\n { shortName: 'JDG', fullNames: ['Judges'], chapters: 21 },\n { shortName: 'RUT', fullNames: ['Ruth'], chapters: 4 },\n { shortName: '1SA', fullNames: ['1 Samuel'], chapters: 31 },\n { shortName: '2SA', fullNames: ['2 Samuel'], chapters: 24 },\n { shortName: '1KI', fullNames: ['1 Kings'], chapters: 22 },\n { shortName: '2KI', fullNames: ['2 Kings'], chapters: 25 },\n { shortName: '1CH', fullNames: ['1 Chronicles'], chapters: 29 },\n { shortName: '2CH', fullNames: ['2 Chronicles'], chapters: 36 },\n { shortName: 'EZR', fullNames: ['Ezra'], chapters: 10 },\n { shortName: 'NEH', fullNames: ['Nehemiah'], chapters: 13 },\n { shortName: 'EST', fullNames: ['Esther'], chapters: 10 },\n { shortName: 'JOB', fullNames: ['Job'], chapters: 42 },\n { shortName: 'PSA', fullNames: ['Psalm', 'Psalms'], chapters: 150 },\n { shortName: 'PRO', fullNames: ['Proverbs'], chapters: 31 },\n { shortName: 'ECC', fullNames: ['Ecclesiastes'], chapters: 12 },\n { shortName: 'SNG', fullNames: ['Song of Solomon', 'Song of Songs'], chapters: 8 },\n { shortName: 'ISA', fullNames: ['Isaiah'], chapters: 66 },\n { shortName: 'JER', fullNames: ['Jeremiah'], chapters: 52 },\n { shortName: 'LAM', fullNames: ['Lamentations'], chapters: 5 },\n { shortName: 'EZK', fullNames: ['Ezekiel'], chapters: 48 },\n { shortName: 'DAN', fullNames: ['Daniel'], chapters: 12 },\n { shortName: 'HOS', fullNames: ['Hosea'], chapters: 14 },\n { shortName: 'JOL', fullNames: ['Joel'], chapters: 3 },\n { shortName: 'AMO', fullNames: ['Amos'], chapters: 9 },\n { shortName: 'OBA', fullNames: ['Obadiah'], chapters: 1 },\n { shortName: 'JON', fullNames: ['Jonah'], chapters: 4 },\n { shortName: 'MIC', fullNames: ['Micah'], chapters: 7 },\n { shortName: 'NAM', fullNames: ['Nahum'], chapters: 3 },\n { shortName: 'HAB', fullNames: ['Habakkuk'], chapters: 3 },\n { shortName: 'ZEP', fullNames: ['Zephaniah'], chapters: 3 },\n { shortName: 'HAG', fullNames: ['Haggai'], chapters: 2 },\n { shortName: 'ZEC', fullNames: ['Zechariah'], chapters: 14 },\n { shortName: 'MAL', fullNames: ['Malachi'], chapters: 4 },\n { shortName: 'MAT', fullNames: ['Matthew'], chapters: 28 },\n { shortName: 'MRK', fullNames: ['Mark'], chapters: 16 },\n { shortName: 'LUK', fullNames: ['Luke'], chapters: 24 },\n { shortName: 'JHN', fullNames: ['John'], chapters: 21 },\n { shortName: 'ACT', fullNames: ['Acts'], chapters: 28 },\n { shortName: 'ROM', fullNames: ['Romans'], chapters: 16 },\n { shortName: '1CO', fullNames: ['1 Corinthians'], chapters: 16 },\n { shortName: '2CO', fullNames: ['2 Corinthians'], chapters: 13 },\n { shortName: 'GAL', fullNames: ['Galatians'], chapters: 6 },\n { shortName: 'EPH', fullNames: ['Ephesians'], chapters: 6 },\n { shortName: 'PHP', fullNames: ['Philippians'], chapters: 4 },\n { shortName: 'COL', fullNames: ['Colossians'], chapters: 4 },\n { shortName: '1TH', fullNames: ['1 Thessalonians'], chapters: 5 },\n { shortName: '2TH', fullNames: ['2 Thessalonians'], chapters: 3 },\n { shortName: '1TI', fullNames: ['1 Timothy'], chapters: 6 },\n { shortName: '2TI', fullNames: ['2 Timothy'], chapters: 4 },\n { shortName: 'TIT', fullNames: ['Titus'], chapters: 3 },\n { shortName: 'PHM', fullNames: ['Philemon'], chapters: 1 },\n { shortName: 'HEB', fullNames: ['Hebrews'], chapters: 13 },\n { shortName: 'JAS', fullNames: ['James'], chapters: 5 },\n { shortName: '1PE', fullNames: ['1 Peter'], chapters: 5 },\n { shortName: '2PE', fullNames: ['2 Peter'], chapters: 3 },\n { shortName: '1JN', fullNames: ['1 John'], chapters: 5 },\n { shortName: '2JN', fullNames: ['2 John'], chapters: 1 },\n { shortName: '3JN', fullNames: ['3 John'], chapters: 1 },\n { shortName: 'JUD', fullNames: ['Jude'], chapters: 1 },\n { shortName: 'REV', fullNames: ['Revelation'], chapters: 22 },\n];\n\nexport const FIRST_SCR_BOOK_NUM = 1;\nexport const LAST_SCR_BOOK_NUM = scrBookData.length - 1;\nexport const FIRST_SCR_CHAPTER_NUM = 1;\nexport const FIRST_SCR_VERSE_NUM = 1;\n\nexport const getChaptersForBook = (bookNum: number): number => {\n return scrBookData[bookNum]?.chapters ?? -1;\n};\n\nexport const offsetBook = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n bookNum: Math.max(FIRST_SCR_BOOK_NUM, Math.min(scrRef.bookNum + offset, LAST_SCR_BOOK_NUM)),\n chapterNum: 1,\n verseNum: 1,\n});\n\nexport const offsetChapter = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n chapterNum: Math.min(\n Math.max(FIRST_SCR_CHAPTER_NUM, scrRef.chapterNum + offset),\n getChaptersForBook(scrRef.bookNum),\n ),\n verseNum: 1,\n});\n\nexport const offsetVerse = (scrRef: ScriptureReference, offset: number): ScriptureReference => ({\n ...scrRef,\n verseNum: Math.max(FIRST_SCR_VERSE_NUM, scrRef.verseNum + offset),\n});\n","/** Function to run to dispose of something. Returns true if successfully unsubscribed */\nexport type Unsubscriber = () => boolean;\n\n/**\n * Returns an Unsubscriber function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers All unsubscribers to aggregate into one unsubscriber\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscribers = (unsubscribers: Unsubscriber[]): Unsubscriber => {\n return (...args) => {\n // Run the unsubscriber for each handler\n const unsubs = unsubscribers.map((unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return unsubs.every((success) => success);\n };\n};\n\n/**\n * Function to run to dispose of something that runs asynchronously. The promise resolves to true if\n * successfully unsubscribed\n */\nexport type UnsubscriberAsync = () => Promise;\n\n/**\n * Returns an UnsubscriberAsync function that combines all the unsubscribers passed in.\n *\n * @param unsubscribers - All unsubscribers to aggregate into one unsubscriber.\n * @returns Function that unsubscribes from all passed in unsubscribers when run\n */\nexport const aggregateUnsubscriberAsyncs = (\n unsubscribers: (UnsubscriberAsync | Unsubscriber)[],\n): UnsubscriberAsync => {\n return async (...args) => {\n // Run the unsubscriber for each handler\n const unsubPromises = unsubscribers.map(async (unsubscriber) => unsubscriber(...args));\n\n // If all the unsubscribers resolve to truthiness, we succeed\n return (await Promise.all(unsubPromises)).every((success) => success);\n };\n};\n","\"use strict\"\r\n\r\n// Based on: https://github.com/lodash/lodash/blob/6018350ac10d5ce6a5b7db625140b82aeab804df/.internal/unicodeSize.js\r\n\r\nmodule.exports = () => {\r\n\t// Used to compose unicode character classes.\r\n\tconst astralRange = \"\\\\ud800-\\\\udfff\"\r\n\tconst comboMarksRange = \"\\\\u0300-\\\\u036f\"\r\n\tconst comboHalfMarksRange = \"\\\\ufe20-\\\\ufe2f\"\r\n\tconst comboSymbolsRange = \"\\\\u20d0-\\\\u20ff\"\r\n\tconst comboMarksExtendedRange = \"\\\\u1ab0-\\\\u1aff\"\r\n\tconst comboMarksSupplementRange = \"\\\\u1dc0-\\\\u1dff\"\r\n\tconst comboRange = comboMarksRange + comboHalfMarksRange + comboSymbolsRange + comboMarksExtendedRange + comboMarksSupplementRange\r\n\tconst varRange = \"\\\\ufe0e\\\\ufe0f\"\r\n\tconst familyRange = \"\\\\uD83D\\\\uDC69\\\\uD83C\\\\uDFFB\\\\u200D\\\\uD83C\\\\uDF93\"\r\n\r\n\t// Used to compose unicode capture groups.\r\n\tconst astral = `[${astralRange}]`\r\n\tconst combo = `[${comboRange}]`\r\n\tconst fitz = \"\\\\ud83c[\\\\udffb-\\\\udfff]\"\r\n\tconst modifier = `(?:${combo}|${fitz})`\r\n\tconst nonAstral = `[^${astralRange}]`\r\n\tconst regional = \"(?:\\\\uD83C[\\\\uDDE6-\\\\uDDFF]){2}\"\r\n\tconst surrogatePair = \"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\"\r\n\tconst zwj = \"\\\\u200d\"\r\n\tconst blackFlag = \"(?:\\\\ud83c\\\\udff4\\\\udb40\\\\udc67\\\\udb40\\\\udc62\\\\udb40(?:\\\\udc65|\\\\udc73|\\\\udc77)\\\\udb40(?:\\\\udc6e|\\\\udc63|\\\\udc6c)\\\\udb40(?:\\\\udc67|\\\\udc74|\\\\udc73)\\\\udb40\\\\udc7f)\"\r\n\tconst family = `[${familyRange}]`\r\n\r\n\t// Used to compose unicode regexes.\r\n\tconst optModifier = `${modifier}?`\r\n\tconst optVar = `[${varRange}]?`\r\n\tconst optJoin = `(?:${zwj}(?:${[nonAstral, regional, surrogatePair].join(\"|\")})${optVar + optModifier})*`\r\n\tconst seq = optVar + optModifier + optJoin\r\n\tconst nonAstralCombo = `${nonAstral}${combo}?`\r\n\tconst symbol = `(?:${[nonAstralCombo, combo, regional, surrogatePair, astral, family].join(\"|\")})`\r\n\r\n\t// Used to match [String symbols](https://mathiasbynens.be/notes/javascript-unicode).\r\n\treturn new RegExp(`${blackFlag}|${fitz}(?=${fitz})|${symbol + seq}`, \"g\")\r\n}\r\n","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// @ts-ignore\nvar char_regex_1 = __importDefault(require(\"char-regex\"));\n/**\n * Converts a string to an array of string chars\n * @param {string} str The string to turn into array\n * @returns {string[]}\n */\nfunction toArray(str) {\n if (typeof str !== 'string') {\n throw new Error('A string is expected as input');\n }\n return str.match(char_regex_1.default()) || [];\n}\nexports.toArray = toArray;\n/**\n * Returns the length of a string\n *\n * @export\n * @param {string} str\n * @returns {number}\n */\nfunction length(str) {\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var match = str.match(char_regex_1.default());\n return match === null ? 0 : match.length;\n}\nexports.length = length;\n/**\n * Returns a substring by providing start and end position\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} end End position\n * @returns {string}\n */\nfunction substring(str, begin, end) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n // Even though negative numbers work here, theyre not in the spec\n if (typeof begin !== 'number' || begin < 0) {\n begin = 0;\n }\n if (typeof end === 'number' && end < 0) {\n end = 0;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substring = substring;\n/**\n * Returns a substring by providing start position and length\n *\n * @export\n * @param {string} str\n * @param {number} [begin=0] Starting position\n * @param {number} len Desired length\n * @returns {string}\n */\nfunction substr(str, begin, len) {\n if (begin === void 0) { begin = 0; }\n // Check for input\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n var strLength = length(str);\n // Fix type\n if (typeof begin !== 'number') {\n begin = parseInt(begin, 10);\n }\n // Return zero-length string if got oversize number.\n if (begin >= strLength) {\n return '';\n }\n // Calculating postive version of negative value.\n if (begin < 0) {\n begin += strLength;\n }\n var end;\n if (typeof len === 'undefined') {\n end = strLength;\n }\n else {\n // Fix type\n if (typeof len !== 'number') {\n len = parseInt(len, 10);\n }\n end = len >= 0 ? len + begin : begin;\n }\n var match = str.match(char_regex_1.default());\n if (!match)\n return '';\n return match.slice(begin, end).join('');\n}\nexports.substr = substr;\n/**\n * Enforces a string to be a certain length by\n * adding or removing characters\n *\n * @export\n * @param {string} str\n * @param {number} [limit=16] Limit\n * @param {string} [padString='#'] The Pad String\n * @param {string} [padPosition='right'] The Pad Position\n * @returns {string}\n */\nfunction limit(str, limit, padString, padPosition) {\n if (limit === void 0) { limit = 16; }\n if (padString === void 0) { padString = '#'; }\n if (padPosition === void 0) { padPosition = 'right'; }\n // Input should be a string, limit should be a number\n if (typeof str !== 'string' || typeof limit !== 'number') {\n throw new Error('Invalid arguments specified');\n }\n // Pad position should be either left or right\n if (['left', 'right'].indexOf(padPosition) === -1) {\n throw new Error('Pad position should be either left or right');\n }\n // Pad string can be anything, we convert it to string\n if (typeof padString !== 'string') {\n padString = String(padString);\n }\n // Calculate string length considering astral code points\n var strLength = length(str);\n if (strLength > limit) {\n return substring(str, 0, limit);\n }\n else if (strLength < limit) {\n var padRepeats = padString.repeat(limit - strLength);\n return padPosition === 'left' ? padRepeats + str : str + padRepeats;\n }\n return str;\n}\nexports.limit = limit;\n/**\n * Returns the index of the first occurrence of a given string\n *\n * @export\n * @param {string} str\n * @param {string} [searchStr] the string to search\n * @param {number} [pos] starting position\n * @returns {number}\n */\nfunction indexOf(str, searchStr, pos) {\n if (pos === void 0) { pos = 0; }\n if (typeof str !== 'string') {\n throw new Error('Input must be a string');\n }\n if (str === '') {\n if (searchStr === '') {\n return 0;\n }\n return -1;\n }\n // fix type\n pos = Number(pos);\n pos = isNaN(pos) ? 0 : pos;\n searchStr = String(searchStr);\n var strArr = toArray(str);\n if (pos >= strArr.length) {\n if (searchStr === '') {\n return strArr.length;\n }\n return -1;\n }\n if (searchStr === '') {\n return pos;\n }\n var searchArr = toArray(searchStr);\n var finded = false;\n var index;\n for (index = pos; index < strArr.length; index += 1) {\n var searchIndex = 0;\n while (searchIndex < searchArr.length &&\n searchArr[searchIndex] === strArr[index + searchIndex]) {\n searchIndex += 1;\n }\n if (searchIndex === searchArr.length &&\n searchArr[searchIndex - 1] === strArr[index + searchIndex - 1]) {\n finded = true;\n break;\n }\n }\n return finded ? index : -1;\n}\nexports.indexOf = indexOf;\n","import {\n indexOf as stringzIndexOf,\n substring as stringzSubstring,\n length as stringzLength,\n toArray as stringzToArray,\n limit as stringzLimit,\n substr as stringzSubstr,\n} from 'stringz';\n\n/**\n * This function mirrors the `at` function from the JavaScript Standard String object. It handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * Finds the Unicode code point at the given index.\n *\n * @param string String to index\n * @param index Position of the character to be returned in range of -length(string) to\n * length(string)\n * @returns New string consisting of the Unicode code point located at the specified offset,\n * undefined if index is out of bounds\n */\nexport function at(string: string, index: number): string | undefined {\n if (index > stringLength(string) || index < -stringLength(string)) return undefined;\n return substr(string, index, 1);\n}\n\n/**\n * This function mirrors the `charAt` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a new string consisting of the single unicode code point at the given index.\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns New string consisting of the Unicode code point located at the specified offset, empty\n * string if index is out of bounds\n */\nexport function charAt(string: string, index: number): string {\n if (index < 0 || index > stringLength(string) - 1) return '';\n return substr(string, index, 1);\n}\n\n/**\n * This function mirrors the `codePointAt` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a non-negative integer that is the Unicode code point value of the character starting at\n * the given index.\n *\n * @param string String to index\n * @param index Position of the string character to be returned, in the range of 0 to\n * length(string)-1\n * @returns Non-negative integer representing the code point value of the character at the given\n * index, or undefined if there is no element at that position\n */\nexport function codePointAt(string: string, index: number): number | undefined {\n if (index < 0 || index > stringLength(string) - 1) return undefined;\n return substr(string, index, 1).codePointAt(0);\n}\n\n/**\n * This function mirrors the `endsWith` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Determines whether a string ends with the characters of this string.\n *\n * @param string String to search through\n * @param searchString Characters to search for at the end of the string\n * @param endPosition End position where searchString is expected to be found. Default is\n * `length(string)`\n * @returns True if it ends with searchString, false if it does not\n */\nexport function endsWith(\n string: string,\n searchString: string,\n endPosition: number = stringLength(string),\n): boolean {\n const lastIndexOfSearchString = lastIndexOf(string, searchString);\n if (lastIndexOfSearchString === -1) return false;\n if (lastIndexOfSearchString + stringLength(searchString) !== endPosition) return false;\n return true;\n}\n\n/**\n * This function mirrors the `includes` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Performs a case-sensitive search to determine if searchString is found in string.\n *\n * @param string String to search through\n * @param searchString String to search for\n * @param position Position within the string to start searching for searchString. Default is `0`\n * @returns True if search string is found, false if it is not\n */\nexport function includes(string: string, searchString: string, position: number = 0): boolean {\n const partialString = substring(string, position);\n const indexOfSearchString = indexOf(partialString, searchString);\n if (indexOfSearchString === -1) return false;\n return true;\n}\n\n/**\n * This function mirrors the `indexOf` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns the index of the first occurrence of a given string.\n *\n * @param string String to search through\n * @param searchString The string to search for\n * @param position Start of searching. Default is `0`\n * @returns Index of the first occurrence of a given string\n */\nexport function indexOf(\n string: string,\n searchString: string,\n position: number | undefined = 0,\n): number {\n return stringzIndexOf(string, searchString, position);\n}\n\n/**\n * This function mirrors the `lastIndexOf` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Searches this string and returns the index of the last occurrence of the specified substring.\n *\n * @param string String to search through\n * @param searchString Substring to search for\n * @param position The index at which to begin searching. If omitted, the search begins at the end\n * of the string. Default is `undefined`\n * @returns Index of the last occurrence of searchString found, or -1 if not found.\n */\nexport function lastIndexOf(string: string, searchString: string, position?: number): number {\n let validatedPosition = position === undefined ? stringLength(string) : position;\n\n if (validatedPosition < 0) {\n validatedPosition = 0;\n } else if (validatedPosition >= stringLength(string)) {\n validatedPosition = stringLength(string) - 1;\n }\n\n for (let index = validatedPosition; index >= 0; index--) {\n if (substr(string, index, stringLength(searchString)) === searchString) {\n return index;\n }\n }\n\n return -1;\n}\n\n/**\n * This function mirrors the `length` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns the length of a string.\n *\n * @param string String to return the length for\n * @returns Number that is length of the starting string\n */\nexport function stringLength(string: string): number {\n return stringzLength(string);\n}\n\n/**\n * This function mirrors the `normalize` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns the Unicode Normalization Form of this string.\n *\n * @param string The starting string\n * @param form Form specifying the Unicode Normalization Form. Default is `'NFC'`\n * @returns A string containing the Unicode Normalization Form of the given string.\n */\nexport function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' | 'none'): string {\n const upperCaseForm = form.toUpperCase();\n if (upperCaseForm === 'NONE') {\n return string;\n }\n return string.normalize(upperCaseForm);\n}\n\n/**\n * This function mirrors the `padEnd` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the end of this string.\n *\n * @param string String to add padding too\n * @param targetLength The length of the resulting string once the starting string has been padded.\n * If value is less than or equal to length(string), then string is returned as is.\n * @param padString The string to pad the current string with. If padString is too long to stay\n * within targetLength, it will be truncated. Default is `\" \"`\n * @returns String with appropriate padding at the end\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padEnd(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= stringLength(string)) return string;\n return stringzLimit(string, targetLength, padString, 'right');\n}\n\n/**\n * This function mirrors the `padStart` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Pads this string with another string (multiple times, if needed) until the resulting string\n * reaches the given length. The padding is applied from the start of this string.\n *\n * @param string String to add padding too\n * @param targetLength The length of the resulting string once the starting string has been padded.\n * If value is less than or equal to length(string), then string is returned as is.\n * @param padString The string to pad the current string with. If padString is too long to stay\n * within the targetLength, it will be truncated from the end. Default is `\" \"`\n * @returns String with of specified targetLength with padString applied from the start\n */\n// Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59\nexport function padStart(string: string, targetLength: number, padString: string = ' '): string {\n if (targetLength <= stringLength(string)) return string;\n return stringzLimit(string, targetLength, padString, 'left');\n}\n\n// This is a helper function that performs a correction on the slice index to make sure it\n// cannot go out of bounds\nfunction correctSliceIndex(length: number, index: number) {\n if (index > length) return length;\n if (index < -length) return 0;\n if (index < 0) return index + length;\n return index;\n}\n\n/**\n * This function mirrors the `slice` function from the JavaScript Standard String object. It handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * Extracts a section of this string and returns it as a new string, without modifying the original\n * string.\n *\n * @param string The starting string\n * @param indexStart The index of the first character to include in the returned substring.\n * @param indexEnd The index of the first character to exclude from the returned substring.\n * @returns A new string containing the extracted section of the string.\n */\nexport function slice(string: string, indexStart: number, indexEnd?: number): string {\n const length: number = stringLength(string);\n if (\n indexStart > length ||\n (indexEnd &&\n ((indexStart > indexEnd &&\n !(indexStart > 0 && indexStart < length && indexEnd < 0 && indexEnd > -length)) ||\n indexEnd < -length ||\n (indexStart < 0 && indexStart > -length && indexEnd > 0)))\n )\n return '';\n\n const newStart = correctSliceIndex(length, indexStart);\n const newEnd = indexEnd ? correctSliceIndex(length, indexEnd) : undefined;\n\n return substring(string, newStart, newEnd);\n}\n\n/**\n * This function mirrors the `split` function from the JavaScript Standard String object. It handles\n * Unicode code points instead of UTF-16 character codes.\n *\n * Takes a pattern and divides the string into an ordered list of substrings by searching for the\n * pattern, puts these substrings into an array, and returns the array.\n *\n * @param string The string to split\n * @param separator The pattern describing where each split should occur\n * @param splitLimit Limit on the number of substrings to be included in the array. Splits the\n * string at each occurrence of specified separator, but stops when limit entries have been placed\n * in the array.\n * @returns An array of strings, split at each point where separator occurs in the starting string.\n * Returns undefined if separator is not found in string.\n */\nexport function split(string: string, separator: string | RegExp, splitLimit?: number): string[] {\n const result: string[] = [];\n\n if (splitLimit !== undefined && splitLimit <= 0) {\n return [string];\n }\n\n if (separator === '') return toArray(string).slice(0, splitLimit);\n\n let regexSeparator = separator;\n if (\n typeof separator === 'string' ||\n (separator instanceof RegExp && !includes(separator.flags, 'g'))\n ) {\n regexSeparator = new RegExp(separator, 'g');\n }\n\n const matches: RegExpMatchArray | null = string.match(regexSeparator);\n\n let currentIndex = 0;\n\n if (!matches) return [string];\n\n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) {\n const matchIndex = indexOf(string, matches[index], currentIndex);\n const matchLength = stringLength(matches[index]);\n\n result.push(substring(string, currentIndex, matchIndex));\n currentIndex = matchIndex + matchLength;\n\n if (splitLimit !== undefined && result.length === splitLimit) {\n break;\n }\n }\n\n result.push(substring(string, currentIndex));\n\n return result;\n}\n\n/**\n * This function mirrors the `startsWith` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Determines whether the string begins with the characters of a specified string, returning true or\n * false as appropriate.\n *\n * @param string String to search through\n * @param searchString The characters to be searched for at the start of this string.\n * @param position The start position at which searchString is expected to be found (the index of\n * searchString's first character). Default is `0`\n * @returns True if the given characters are found at the beginning of the string, including when\n * searchString is an empty string; otherwise, false.\n */\nexport function startsWith(string: string, searchString: string, position: number = 0): boolean {\n const indexOfSearchString = indexOf(string, searchString, position);\n if (indexOfSearchString !== position) return false;\n return true;\n}\n\n/**\n * This function mirrors the `substr` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a substring by providing start and length. This function is not exported because it is\n * considered deprecated, however it is still useful as a local helper function.\n *\n * @param string String to be divided\n * @param begin Start position. Default is `Start of string`\n * @param len Length of result. Default is `String length minus start parameter`. Default is `String\n * length minus start parameter`\n * @returns Substring from starting string\n */\nfunction substr(\n string: string,\n begin: number = 0,\n len: number = stringLength(string) - begin,\n): string {\n return stringzSubstr(string, begin, len);\n}\n\n/**\n * This function mirrors the `substring` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Returns a substring by providing start and end position.\n *\n * @param string String to be divided\n * @param begin Start position\n * @param end End position. Default is `End of string`\n * @returns Substring from starting string\n */\nexport function substring(\n string: string,\n begin: number,\n end: number = stringLength(string),\n): string {\n return stringzSubstring(string, begin, end);\n}\n\n/**\n * This function mirrors the `toArray` function from the JavaScript Standard String object. It\n * handles Unicode code points instead of UTF-16 character codes.\n *\n * Converts a string to an array of string characters.\n *\n * @param string String to convert to array\n * @returns An array of characters from the starting string\n */\nexport function toArray(string: string): string[] {\n return stringzToArray(string);\n}\n","var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n var cache = state.cache;\n var cachedA = cache.get(a);\n var cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n var result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nvar hasOwn = Object.hasOwn ||\n (function (object, property) {\n return hasOwnProperty.call(object, property);\n });\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nfunction sameValueZeroEqual(a, b) {\n return a || b ? a === b : a === b || (a !== a && b !== b);\n}\n\nvar OWNER = '_owner';\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueZeroEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.entries();\n var index = 0;\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.entries();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n var _a = aResult.value, aKey = _a[0], aValue = _a[1];\n var _b = bResult.value, bKey = _b[0], bValue = _b[1];\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch =\n state.equals(aKey, bKey, index, matchIndex, a, b, state) &&\n state.equals(aValue, bValue, aKey, bKey, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n var properties = keys(a);\n var index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n var property;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property) ||\n !state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n var properties = getStrictProperties(a);\n var index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n var property;\n var descriptorA;\n var descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (property === OWNER &&\n (a.$$typeof || b.$$typeof) &&\n a.$$typeof !== b.$$typeof) {\n return false;\n }\n if (!hasOwn(b, property)) {\n return false;\n }\n if (!state.equals(a[property], b[property], property, property, a, b, state)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB) &&\n (!descriptorA ||\n !descriptorB ||\n descriptorA.configurable !== descriptorB.configurable ||\n descriptorA.enumerable !== descriptorB.enumerable ||\n descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n if (a.size !== b.size) {\n return false;\n }\n var matchedIndices = {};\n var aIterable = a.values();\n var aResult;\n var bResult;\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n var bIterable = b.values();\n var hasMatch = false;\n var matchIndex = 0;\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state))) {\n matchedIndices[matchIndex] = true;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n var index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n\nvar ARGUMENTS_TAG = '[object Arguments]';\nvar BOOLEAN_TAG = '[object Boolean]';\nvar DATE_TAG = '[object Date]';\nvar MAP_TAG = '[object Map]';\nvar NUMBER_TAG = '[object Number]';\nvar OBJECT_TAG = '[object Object]';\nvar REG_EXP_TAG = '[object RegExp]';\nvar SET_TAG = '[object Set]';\nvar STRING_TAG = '[object String]';\nvar isArray = Array.isArray;\nvar isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView\n ? ArrayBuffer.isView\n : null;\nvar assign = Object.assign;\nvar getTag = Object.prototype.toString.call.bind(Object.prototype.toString);\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(_a) {\n var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (a == null ||\n b == null ||\n typeof a !== 'object' ||\n typeof b !== 'object') {\n return a !== a && b !== b;\n }\n var constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid capturing the string tag.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` check.\n if (isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // `isTypedArray()` works on all possible TypedArray classes, so we can avoid\n // capturing the string tag or comparing against all possible constructors.\n if (isTypedArray != null && isTypedArray(a)) {\n return areTypedArraysEqual(a, b, state);\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is subclassing a native class, it will be handled\n // with the string tag comparison.\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determing its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n var tag = getTag(a);\n if (tag === DATE_TAG) {\n return areDatesEqual(a, b, state);\n }\n if (tag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, state);\n }\n if (tag === MAP_TAG) {\n return areMapsEqual(a, b, state);\n }\n if (tag === SET_TAG) {\n return areSetsEqual(a, b, state);\n }\n if (tag === OBJECT_TAG) {\n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n return (typeof a.then !== 'function' &&\n typeof b.then !== 'function' &&\n areObjectsEqual(a, b, state));\n }\n // If an arguments tag, it should be treated as a standard object.\n if (tag === ARGUMENTS_TAG) {\n return areObjectsEqual(a, b, state);\n }\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {\n return arePrimitiveWrappersEqual(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases (may be included in a future release, if requested enough).\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig(_a) {\n var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;\n var config = {\n areArraysEqual: strict\n ? areObjectsEqualStrict\n : areArraysEqual,\n areDatesEqual: areDatesEqual,\n areMapsEqual: strict\n ? combineComparators(areMapsEqual, areObjectsEqualStrict)\n : areMapsEqual,\n areObjectsEqual: strict\n ? areObjectsEqualStrict\n : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict\n ? combineComparators(areSetsEqual, areObjectsEqualStrict)\n : areSetsEqual,\n areTypedArraysEqual: strict\n ? areObjectsEqualStrict\n : areTypedArraysEqual,\n };\n if (createCustomConfig) {\n config = assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n var areArraysEqual$1 = createIsCircular(config.areArraysEqual);\n var areMapsEqual$1 = createIsCircular(config.areMapsEqual);\n var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);\n var areSetsEqual$1 = createIsCircular(config.areSetsEqual);\n config = assign({}, config, {\n areArraysEqual: areArraysEqual$1,\n areMapsEqual: areMapsEqual$1,\n areObjectsEqual: areObjectsEqual$1,\n areSetsEqual: areSetsEqual$1,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual(_a) {\n var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;\n if (createState) {\n return function isEqual(a, b) {\n var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;\n return comparator(a, b, {\n cache: cache,\n equals: equals,\n meta: meta,\n strict: strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals: equals,\n meta: undefined,\n strict: strict,\n });\n };\n }\n var state = {\n cache: undefined,\n equals: equals,\n meta: undefined,\n strict: strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nvar deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nvar strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nvar circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nvar shallowEqual = createCustomEqual({\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nvar strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nvar circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nvar strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: function () { return sameValueZeroEqual; },\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options) {\n if (options === void 0) { options = {}; }\n var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;\n var config = createEqualityComparatorConfig(options);\n var comparator = createEqualityComparator(config);\n var equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };\n//# sourceMappingURL=index.mjs.map\n","// There is a circular version https://www.npmjs.com/package/fast-equals#circulardeepequal that I\n// think allows comparing React refs (which have circular references in particular places that this\n// library would ignore). Maybe we can change to that version sometime if needed.\nimport { deepEqual as isEqualDeep } from 'fast-equals';\n\n/**\n * Check that two objects are deeply equal, comparing members of each object and such\n *\n * @param a The first object to compare\n * @param b The second object to compare\n *\n * WARNING: Objects like arrays from different iframes have different constructor function\n * references even if they do the same thing, so this deep equality comparison fails objects that\n * look the same but have different constructors because different constructors could produce\n * false positives in [a few specific\n * situations](https://github.com/planttheidea/fast-equals/blob/a41afc0a240ad5a472e47b53791e9be017f52281/src/comparator.ts#L96).\n * This means that two objects like arrays from different iframes that look the same will fail\n * this check. Please use some other means to check deep equality in those situations.\n *\n * Note: This deep equality check considers `undefined` values on keys of objects NOT to be equal to\n * not specifying the key at all. For example, `{ stuff: 3, things: undefined }` and `{ stuff: 3\n * }` are not considered equal in this case\n *\n * - For more information and examples, see [this\n * CodeSandbox](https://codesandbox.io/s/deepequallibrarycomparison-4g4kk4?file=/src/index.mjs).\n *\n * @returns True if a and b are deeply equal; false otherwise\n */\nexport default function deepEqual(a: unknown, b: unknown) {\n return isEqualDeep(a, b);\n}\n","/**\n * Converts a JavaScript value to a JSON string, changing `undefined` properties in the JavaScript\n * object to `null` properties in the JSON string.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A JavaScript value, usually an object or array, to be converted.\n * @param replacer A function that transforms the results. Note that all `undefined` values returned\n * by the replacer will be further transformed into `null` in the JSON string.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON\n * text to make it easier to read. See the `space` parameter of `JSON.stringify` for more\n * details.\n */\nexport function serialize(\n value: unknown,\n replacer?: (this: unknown, key: string, value: unknown) => unknown,\n space?: string | number,\n): string {\n const undefinedReplacer = (replacerKey: string, replacerValue: unknown) => {\n let newValue = replacerValue;\n if (replacer) newValue = replacer(replacerKey, newValue);\n // All `undefined` values become `null` on the way from JS objects into JSON strings\n // eslint-disable-next-line no-null/no-null\n if (newValue === undefined) newValue = null;\n return newValue;\n };\n return JSON.stringify(value, undefinedReplacer, space);\n}\n\n/**\n * Converts a JSON string into a value, converting all `null` properties from JSON into `undefined`\n * in the returned JavaScript value/object.\n *\n * WARNING: `null` values will become `undefined` values after passing through {@link serialize} then\n * {@link deserialize}. For example, `{ a: 1, b: undefined, c: null }` will become `{ a: 1, b:\n * undefined, c: undefined }`. If you are passing around user data that needs to retain `null`\n * values, you should wrap them yourself in a string before using this function. Alternatively, you\n * can write your own replacer that will preserve `null` in a way that you can recover later.\n *\n * @param value A valid JSON string.\n * @param reviver A function that transforms the results. This function is called for each member of\n * the object. If a member contains nested objects, the nested objects are transformed before the\n * parent object is. Note that `null` values are converted into `undefined` values after the\n * reviver has run.\n */\nexport function deserialize(\n value: string,\n reviver?: (this: unknown, key: string, value: unknown) => unknown,\n // Need to use `any` instead of `unknown` here to match the signature of JSON.parse\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n // Helper function to replace `null` with `undefined` on a per property basis. This can't be done\n // with our own reviver because `JSON.parse` removes `undefined` properties from the return value.\n function replaceNull(obj: Record): Record {\n Object.keys(obj).forEach((key: string | number) => {\n // We only want to replace `null`, not other falsy values\n // eslint-disable-next-line no-null/no-null\n if (obj[key] === null) obj[key] = undefined;\n // If the property is an object, recursively call the helper function on it\n else if (typeof obj[key] === 'object')\n // Since the object came from a string, we know the keys will not be symbols\n // eslint-disable-next-line no-type-assertion/no-type-assertion\n obj[key] = replaceNull(obj[key] as Record);\n });\n return obj;\n }\n\n const parsedObject = JSON.parse(value, reviver);\n // Explicitly convert the value 'null' that isn't stored as a property on an object to 'undefined'\n // eslint-disable-next-line no-null/no-null\n if (parsedObject === null) return undefined;\n if (typeof parsedObject === 'object') return replaceNull(parsedObject);\n return parsedObject;\n}\n\n/**\n * Check to see if the value is serializable without losing information\n *\n * @param value Value to test\n * @returns True if serializable; false otherwise\n *\n * Note: the values `undefined` and `null` are serializable (on their own or in an array), but\n * `null` values get transformed into `undefined` when serializing/deserializing.\n *\n * WARNING: This is inefficient right now as it stringifies, parses, stringifies, and === the value.\n * Please only use this if you need to\n *\n * DISCLAIMER: this does not successfully detect that values are not serializable in some cases:\n *\n * - Losses of removed properties like functions and `Map`s\n * - Class instances (not deserializable into class instances without special code)\n *\n * We intend to improve this in the future if it becomes important to do so. See [`JSON.stringify`\n * documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description)\n * for more information.\n */\nexport function isSerializable(value: unknown): boolean {\n try {\n const serializedValue = serialize(value);\n return serializedValue === serialize(deserialize(serializedValue));\n } catch (e) {\n return false;\n }\n}\n\n/**\n * HTML Encodes the provided string. Thanks to ChatGPT\n *\n * @param str String to HTML encode\n * @returns HTML-encoded string\n */\nexport const htmlEncode = (str: string): string =>\n str\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\n","//----------------------------------------------------------------------------------------------\n// NOTE: If you change any of the types, make sure the JSON schema at the end of this file gets\n// changed so they align.\n//----------------------------------------------------------------------------------------------\n\n/** Identifier for a string that will be localized in a menu based on the user's UI language */\nexport type LocalizeKey = `%${string}%`;\n\n/** Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command) */\nexport type ReferencedItem = `${string}.${string}`;\n\nexport type OrderedItem = {\n /** Relative order of this item compared to other items in the same parent/scope (sorted ascending) */\n order: number;\n};\n\nexport type OrderedExtensibleContainer = OrderedItem & {\n /** Determines whether other items can be added to this after it has been defined */\n isExtensible?: boolean;\n};\n\n/** Group of menu items that belongs in a column */\nexport type MenuGroupDetailsInColumn = OrderedExtensibleContainer & {\n /** ID of column in which this group resides */\n column: ReferencedItem;\n};\n\n/** Group of menu items that belongs in a submenu */\nexport type MenuGroupDetailsInSubMenu = OrderedExtensibleContainer & {\n /** ID of menu item hosting the submenu in which this group resides */\n menuItem: ReferencedItem;\n};\n\n/** Column that includes header text in a menu */\nexport type MenuColumnWithHeader = OrderedExtensibleContainer & {\n /** Key that represents the text of the header text of the column */\n label: LocalizeKey;\n};\n\nexport type MenuItemBase = OrderedItem & {\n /** Menu group to which this menu item belongs */\n group: ReferencedItem;\n /** Key that represents the text of this menu item to display */\n label: LocalizeKey;\n /** Key that represents words the platform should reference when users are searching for menu items */\n searchTerms?: LocalizeKey;\n /** Key that represents the text to display if a mouse pointer hovers over the menu item */\n tooltip?: LocalizeKey;\n /** Additional information provided by developers to help people who perform localization */\n localizeNotes: string;\n};\n\n/** Menu item that hosts a submenu */\nexport type MenuItemContainingSubmenu = MenuItemBase & {\n /** ID for this menu item that holds a submenu */\n id: ReferencedItem;\n};\n\n/** Menu item that runs a command */\nexport type MenuItemContainingCommand = MenuItemBase & {\n /** Name of the PAPI command to run when this menu item is selected. */\n command: ReferencedItem;\n /** Path to the icon to display after the menu text */\n iconPathAfter?: string;\n /** Path to the icon to display before the menu text */\n iconPathBefore?: string;\n};\n\n/**\n * Group of menu items that can be combined with other groups to form a single menu/submenu. Groups\n * are separated using a line within the menu/submenu.\n */\nexport type Groups = {\n /** Named menu group */\n [property: ReferencedItem]: MenuGroupDetailsInColumn | MenuGroupDetailsInSubMenu;\n};\n\n/** Group of columns that can be combined with other columns to form a multi-column menu */\nexport type ColumnsWithHeaders = {\n /** Named column of a menu */\n [property: ReferencedItem]: MenuColumnWithHeader;\n /** Defines whether columns can be added to this multi-column menu */\n isExtensible?: boolean;\n};\n\n/** Menu that contains a column without a header */\nexport type SingleColumnMenu = {\n /** Groups that belong in this menu */\n groups: Groups;\n /** List of menu items that belong in this menu */\n items: (MenuItemContainingCommand | MenuItemContainingSubmenu)[];\n};\n\n/** Menu that contains multiple columns with headers */\nexport type MultiColumnMenu = SingleColumnMenu & {\n /** Columns that belong in this menu */\n columns: ColumnsWithHeaders;\n};\n\n/** Menus for one single web view */\nexport type WebViewMenu = {\n /** Indicates whether the platform default menus should be included for this webview */\n includeDefaults: boolean | undefined;\n /** Menu that opens when you click on the top left corner of a tab */\n topMenu: MultiColumnMenu | undefined;\n /** Menu that opens when you right click on the main body/area of a tab */\n contextMenu: SingleColumnMenu | undefined;\n};\n\n/** Menus for all web views */\nexport type WebViewMenus = {\n /** Named web view */\n [property: ReferencedItem]: WebViewMenu;\n};\n\n/** Platform.Bible menus */\nexport type PlatformMenus = {\n /** Top level menu for the application */\n mainMenu: MultiColumnMenu;\n /** Menus that apply per web view in the application */\n webViewMenus: WebViewMenus;\n /** Default context menu for web views that don't specify their own */\n defaultWebViewContextMenu: SingleColumnMenu;\n /** Default top menu for web views that don't specify their own */\n defaultWebViewTopMenu: MultiColumnMenu;\n};\n\n//----------------------------------------------------------------------------------------------\n// NOTE: If you change the schema below, make sure the TS types above get changed so they align.\n//----------------------------------------------------------------------------------------------\n/** JSON schema object that aligns with the PlatformMenus type */\nexport const menuDocumentSchema = {\n title: 'Platform.Bible menus',\n type: 'object',\n properties: {\n mainMenu: {\n description: 'Top level menu for the application',\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewTopMenu: {\n description: \"Default top menu for web views that don't specify their own\",\n $ref: '#/$defs/multiColumnMenu',\n },\n defaultWebViewContextMenu: {\n description: \"Default context menu for web views that don't specify their own\",\n $ref: '#/$defs/singleColumnMenu',\n },\n webViewMenus: {\n description: 'Menus that apply per web view in the application',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n $ref: '#/$defs/menusForOneWebView',\n },\n },\n additionalProperties: false,\n },\n },\n required: ['mainMenu', 'defaultWebViewTopMenu', 'defaultWebViewContextMenu', 'webViewMenus'],\n additionalProperties: false,\n $defs: {\n localizeKey: {\n description:\n \"Identifier for a string that will be localized in a menu based on the user's UI language\",\n type: 'string',\n pattern: '^%[\\\\w\\\\-\\\\.]+%$',\n },\n referencedItem: {\n description:\n 'Name of some UI element (i.e., tab, column, group, menu item) or some PAPI object (i.e., command)',\n type: 'string',\n pattern: '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$',\n },\n columnsWithHeaders: {\n description:\n 'Group of columns that can be combined with other columns to form a multi-column menu',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single column with a header string',\n type: 'object',\n properties: {\n label: {\n description: 'Header text for this this column in the UI',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n order: {\n description:\n 'Relative order of this column compared to other columns (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu groups to this column',\n type: 'boolean',\n },\n },\n required: ['label', 'order'],\n additionalProperties: false,\n },\n },\n properties: {\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add columns to this multi-column menu',\n type: 'boolean',\n },\n },\n },\n menuGroups: {\n description:\n 'Group of menu items that can be combined with other groups to form a single menu/submenu. Groups are separated using a line within the menu/submenu.',\n type: 'object',\n patternProperties: {\n '^[\\\\w\\\\-]+\\\\.[\\\\w\\\\-]+$': {\n description: 'Single group that contains menu items',\n type: 'object',\n oneOf: [\n {\n properties: {\n column: {\n description:\n 'Column where this group belongs, not required for single column menus',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['order'],\n additionalProperties: false,\n },\n {\n properties: {\n menuItem: {\n description: 'Menu item that anchors the submenu where this group belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this group compared to other groups in the same column or submenu (sorted ascending)',\n type: 'number',\n },\n isExtensible: {\n description:\n 'Defines whether contributions are allowed to add menu items to this menu group',\n type: 'boolean',\n },\n },\n required: ['menuItem', 'order'],\n additionalProperties: false,\n },\n ],\n },\n },\n additionalProperties: false,\n },\n menuItem: {\n description:\n 'Single item in a menu that can be clicked on to take an action or can be the parent of a submenu',\n type: 'object',\n oneOf: [\n {\n properties: {\n id: {\n description: 'ID for this menu item that holds a submenu',\n $ref: '#/$defs/referencedItem',\n },\n },\n required: ['id'],\n },\n {\n properties: {\n command: {\n description: 'Name of the PAPI command to run when this menu item is selected.',\n $ref: '#/$defs/referencedItem',\n },\n iconPathBefore: {\n description: 'Path to the icon to display before the menu text',\n type: 'string',\n },\n iconPathAfter: {\n description: 'Path to the icon to display after the menu text',\n type: 'string',\n },\n },\n required: ['command'],\n },\n ],\n properties: {\n label: {\n description: 'Key that represents the text of this menu item to display',\n $ref: '#/$defs/localizeKey',\n },\n tooltip: {\n description:\n 'Key that represents the text to display if a mouse pointer hovers over the menu item',\n $ref: '#/$defs/localizeKey',\n },\n searchTerms: {\n description:\n 'Key that represents additional words the platform should reference when users are searching for menu items',\n $ref: '#/$defs/localizeKey',\n },\n localizeNotes: {\n description:\n 'Additional information provided by developers to help people who perform localization',\n type: 'string',\n },\n group: {\n description: 'Group to which this menu item belongs',\n $ref: '#/$defs/referencedItem',\n },\n order: {\n description:\n 'Relative order of this menu item compared to other menu items in the same group (sorted ascending)',\n type: 'number',\n },\n },\n required: ['label', 'group', 'order'],\n unevaluatedProperties: false,\n },\n groupsAndItems: {\n description: 'Core schema for a column',\n type: 'object',\n properties: {\n groups: {\n description: 'Groups that belong in this menu',\n $ref: '#/$defs/menuGroups',\n },\n items: {\n description: 'List of menu items that belong in this menu',\n type: 'array',\n items: { $ref: '#/$defs/menuItem' },\n uniqueItems: true,\n },\n },\n required: ['groups', 'items'],\n },\n singleColumnMenu: {\n description: 'Menu that contains a column without a header',\n type: 'object',\n allOf: [{ $ref: '#/$defs/groupsAndItems' }],\n unevaluatedProperties: false,\n },\n multiColumnMenu: {\n description: 'Menu that can contain multiple columns with headers',\n type: 'object',\n allOf: [\n { $ref: '#/$defs/groupsAndItems' },\n {\n properties: {\n columns: {\n description: 'Columns that belong in this menu',\n $ref: '#/$defs/columnsWithHeaders',\n },\n },\n required: ['columns'],\n },\n ],\n unevaluatedProperties: false,\n },\n menusForOneWebView: {\n description: 'Set of menus that are associated with a single tab',\n type: 'object',\n properties: {\n includeDefaults: {\n description:\n 'Indicates whether the platform default menus should be included for this webview',\n type: 'boolean',\n },\n topMenu: {\n description: 'Menu that opens when you click on the top left corner of a tab',\n $ref: '#/$defs/multiColumnMenu',\n },\n contextMenu: {\n description: 'Menu that opens when you right click on the main body/area of a tab',\n $ref: '#/$defs/singleColumnMenu',\n },\n },\n additionalProperties: false,\n },\n },\n};\n\nObject.freeze(menuDocumentSchema);\n"],"names":["AsyncVariable","variableName","rejectIfNotSettledWithinMS","__publicField","resolve","reject","value","throwIfAlreadySettled","reason","newGuid","s","isString","o","deepClone","obj","debounce","fn","delay","timeout","args","groupBy","items","keySelector","valueSelector","map","item","key","group","isErrorWithMessage","error","toErrorWithMessage","maybeError","getErrorMessage","wait","ms","waitForDuration","maxWaitTimeInMS","getAllObjectFunctionNames","objId","objectFunctionNames","property","objectPrototype","createSyncProxyForAsyncObject","getObject","objectToProxy","target","prop","DocumentCombinerEngine","baseDocument","options","documentName","document","previousDocumentVersion","documentToSet","potentialOutput","outputIteration","contribution","mergeObjects","areNonArrayObjects","values","allMatch","areArrayObjects","startingPoint","copyFrom","ignoreDuplicateProperties","retVal","UnsubscriberAsyncList","name","unsubscribers","unsubscriber","unsubs","results","unsubscriberSucceeded","index","PlatformEventEmitter","event","callback","callbackIndex","_a","Mutex","AsyncMutex","MutexMap","mutexID","scrBookData","FIRST_SCR_BOOK_NUM","LAST_SCR_BOOK_NUM","FIRST_SCR_CHAPTER_NUM","FIRST_SCR_VERSE_NUM","getChaptersForBook","bookNum","offsetBook","scrRef","offset","offsetChapter","offsetVerse","aggregateUnsubscribers","success","aggregateUnsubscriberAsyncs","unsubPromises","charRegex","astralRange","comboMarksRange","comboHalfMarksRange","comboSymbolsRange","comboMarksExtendedRange","comboMarksSupplementRange","comboRange","varRange","familyRange","astral","combo","fitz","modifier","nonAstral","regional","surrogatePair","zwj","blackFlag","family","optModifier","optVar","optJoin","seq","symbol","__importDefault","this","mod","dist","char_regex_1","require$$0","toArray","str","toArray_1","length","match","length_1","substring","begin","end","substring_1","substr","len","strLength","substr_1","limit","padString","padPosition","padRepeats","limit_1","indexOf","searchStr","pos","strArr","searchArr","finded","searchIndex","indexOf_1","at","string","stringLength","charAt","codePointAt","endsWith","searchString","endPosition","lastIndexOfSearchString","lastIndexOf","includes","position","partialString","stringzIndexOf","validatedPosition","stringzLength","normalize","form","upperCaseForm","padEnd","targetLength","stringzLimit","padStart","correctSliceIndex","slice","indexStart","indexEnd","newStart","newEnd","split","separator","splitLimit","result","regexSeparator","matches","currentIndex","matchIndex","matchLength","startsWith","stringzSubstr","stringzSubstring","stringzToArray","getOwnPropertyNames","getOwnPropertySymbols","hasOwnProperty","combineComparators","comparatorA","comparatorB","a","b","state","createIsCircular","areItemsEqual","cache","cachedA","cachedB","getStrictProperties","object","hasOwn","sameValueZeroEqual","OWNER","getOwnPropertyDescriptor","keys","areArraysEqual","areDatesEqual","areMapsEqual","matchedIndices","aIterable","aResult","bResult","bIterable","hasMatch","aKey","aValue","_b","bKey","bValue","areObjectsEqual","properties","areObjectsEqualStrict","descriptorA","descriptorB","arePrimitiveWrappersEqual","areRegExpsEqual","areSetsEqual","areTypedArraysEqual","ARGUMENTS_TAG","BOOLEAN_TAG","DATE_TAG","MAP_TAG","NUMBER_TAG","OBJECT_TAG","REG_EXP_TAG","SET_TAG","STRING_TAG","isArray","isTypedArray","assign","getTag","createEqualityComparator","constructor","tag","createEqualityComparatorConfig","circular","createCustomConfig","strict","config","areArraysEqual$1","areMapsEqual$1","areObjectsEqual$1","areSetsEqual$1","createInternalEqualityComparator","compare","_indexOrKeyA","_indexOrKeyB","_parentA","_parentB","createIsEqual","comparator","createState","equals","meta","deepEqual","createCustomEqual","createCustomInternalComparator","isEqualDeep","serialize","replacer","space","replacerKey","replacerValue","newValue","deserialize","reviver","replaceNull","parsedObject","isSerializable","serializedValue","htmlEncode","menuDocumentSchema"],"mappings":"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","x_google_ignoreList":[9,10,12]} \ No newline at end of file diff --git a/lib/platform-bible-utils/src/index.ts b/lib/platform-bible-utils/src/index.ts index 20c3d0fed4..5c071a31da 100644 --- a/lib/platform-bible-utils/src/index.ts +++ b/lib/platform-bible-utils/src/index.ts @@ -40,7 +40,7 @@ export { includes, indexOf, lastIndexOf, - length, + stringLength, normalize, padEnd, padStart, diff --git a/lib/platform-bible-utils/src/string-util.test.ts b/lib/platform-bible-utils/src/string-util.test.ts index 4a74c7a43e..34656d56b6 100644 --- a/lib/platform-bible-utils/src/string-util.test.ts +++ b/lib/platform-bible-utils/src/string-util.test.ts @@ -6,7 +6,7 @@ import { includes, indexOf, lastIndexOf, - length, + stringLength, normalize, padEnd, padStart, @@ -47,12 +47,12 @@ describe('at', () => { }); test('at with index greater than length returns undefined', () => { - const result = at(LONG_SURROGATE_PAIRS_STRING, length(LONG_SURROGATE_PAIRS_STRING) + 10); + const result = at(LONG_SURROGATE_PAIRS_STRING, stringLength(LONG_SURROGATE_PAIRS_STRING) + 10); expect(result).toEqual(undefined); }); test('at with index smaller than -length returns undefined', () => { - const result = at(LONG_SURROGATE_PAIRS_STRING, -length(LONG_SURROGATE_PAIRS_STRING) - 10); + const result = at(LONG_SURROGATE_PAIRS_STRING, -stringLength(LONG_SURROGATE_PAIRS_STRING) - 10); expect(result).toEqual(undefined); }); }); @@ -151,7 +151,7 @@ describe('lastIndexOf', () => { describe('length', () => { test('length is correct', () => { - const result = length(LONG_SURROGATE_PAIRS_STRING); + const result = stringLength(LONG_SURROGATE_PAIRS_STRING); expect(result).toEqual(SURROGATE_PAIRS_STRING_LENGTH); }); }); diff --git a/lib/platform-bible-utils/src/string-util.ts b/lib/platform-bible-utils/src/string-util.ts index 5f87a8fb8c..eea006fe72 100644 --- a/lib/platform-bible-utils/src/string-util.ts +++ b/lib/platform-bible-utils/src/string-util.ts @@ -8,8 +8,8 @@ import { } from 'stringz'; /** - * This function mirrors the `at` function from the JavaScript Standard String object. - * It handles Unicode code points instead of UTF-16 character codes. + * This function mirrors the `at` function from the JavaScript Standard String object. It handles + * Unicode code points instead of UTF-16 character codes. * * Finds the Unicode code point at the given index. * @@ -20,13 +20,13 @@ import { * undefined if index is out of bounds */ export function at(string: string, index: number): string | undefined { - if (index > length(string) || index < -length(string)) return undefined; + if (index > stringLength(string) || index < -stringLength(string)) return undefined; return substr(string, index, 1); } /** - * This function mirrors the `charAt` function from the JavaScript Standard String object. - * It handles Unicode code points instead of UTF-16 character codes. + * This function mirrors the `charAt` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. * * Returns a new string consisting of the single unicode code point at the given index. * @@ -37,13 +37,13 @@ export function at(string: string, index: number): string | undefined { * string if index is out of bounds */ export function charAt(string: string, index: number): string { - if (index < 0 || index > length(string) - 1) return ''; + if (index < 0 || index > stringLength(string) - 1) return ''; return substr(string, index, 1); } /** - * This function mirrors the `codePointAt` function from the JavaScript Standard String object. - * It handles Unicode code points instead of UTF-16 character codes. + * This function mirrors the `codePointAt` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. * * Returns a non-negative integer that is the Unicode code point value of the character starting at * the given index. @@ -55,13 +55,13 @@ export function charAt(string: string, index: number): string { * index, or undefined if there is no element at that position */ export function codePointAt(string: string, index: number): number | undefined { - if (index < 0 || index > length(string) - 1) return undefined; + if (index < 0 || index > stringLength(string) - 1) return undefined; return substr(string, index, 1).codePointAt(0); } /** - * This function mirrors the `endsWith` function from the JavaScript Standard String object. - * It handles Unicode code points instead of UTF-16 character codes. + * This function mirrors the `endsWith` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. * * Determines whether a string ends with the characters of this string. * @@ -74,17 +74,17 @@ export function codePointAt(string: string, index: number): number | undefined { export function endsWith( string: string, searchString: string, - endPosition: number = length(string), + endPosition: number = stringLength(string), ): boolean { const lastIndexOfSearchString = lastIndexOf(string, searchString); if (lastIndexOfSearchString === -1) return false; - if (lastIndexOfSearchString + length(searchString) !== endPosition) return false; + if (lastIndexOfSearchString + stringLength(searchString) !== endPosition) return false; return true; } /** - * This function mirrors the `includes` function from the JavaScript Standard String object. - * It handles Unicode code points instead of UTF-16 character codes. + * This function mirrors the `includes` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. * * Performs a case-sensitive search to determine if searchString is found in string. * @@ -101,8 +101,8 @@ export function includes(string: string, searchString: string, position: number } /** - * This function mirrors the `indexOf` function from the JavaScript Standard String object. - * It handles Unicode code points instead of UTF-16 character codes. + * This function mirrors the `indexOf` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. * * Returns the index of the first occurrence of a given string. * @@ -120,8 +120,8 @@ export function indexOf( } /** - * This function mirrors the `lastIndexOf` function from the JavaScript Standard String object. - * It handles Unicode code points instead of UTF-16 character codes. + * This function mirrors the `lastIndexOf` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. * * Searches this string and returns the index of the last occurrence of the specified substring. * @@ -132,16 +132,16 @@ export function indexOf( * @returns Index of the last occurrence of searchString found, or -1 if not found. */ export function lastIndexOf(string: string, searchString: string, position?: number): number { - let validatedPosition = position === undefined ? length(string) : position; + let validatedPosition = position === undefined ? stringLength(string) : position; if (validatedPosition < 0) { validatedPosition = 0; - } else if (validatedPosition >= length(string)) { - validatedPosition = length(string) - 1; + } else if (validatedPosition >= stringLength(string)) { + validatedPosition = stringLength(string) - 1; } for (let index = validatedPosition; index >= 0; index--) { - if (substr(string, index, length(searchString)) === searchString) { + if (substr(string, index, stringLength(searchString)) === searchString) { return index; } } @@ -150,21 +150,22 @@ export function lastIndexOf(string: string, searchString: string, position?: num } /** - * This function mirrors the `length` function from the JavaScript Standard String object. - * It handles Unicode code points instead of UTF-16 character codes. + * This function mirrors the `length` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. Since `length` appears to be a + * reserved keyword, the function was renamed to `stringLength` * * Returns the length of a string. * * @param string String to return the length for * @returns Number that is length of the starting string */ -export function length(string: string): number { +export function stringLength(string: string): number { return stringzLength(string); } /** - * This function mirrors the `normalize` function from the JavaScript Standard String object. - * It handles Unicode code points instead of UTF-16 character codes. + * This function mirrors the `normalize` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. * * Returns the Unicode Normalization Form of this string. * @@ -181,8 +182,8 @@ export function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' } /** - * This function mirrors the `padEnd` function from the JavaScript Standard String object. - * It handles Unicode code points instead of UTF-16 character codes. + * This function mirrors the `padEnd` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. * * Pads this string with another string (multiple times, if needed) until the resulting string * reaches the given length. The padding is applied from the end of this string. @@ -196,13 +197,13 @@ export function normalize(string: string, form: 'NFC' | 'NFD' | 'NFKC' | 'NFKD' */ // Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59 export function padEnd(string: string, targetLength: number, padString: string = ' '): string { - if (targetLength <= length(string)) return string; + if (targetLength <= stringLength(string)) return string; return stringzLimit(string, targetLength, padString, 'right'); } /** - * This function mirrors the `padStart` function from the JavaScript Standard String object. - * It handles Unicode code points instead of UTF-16 character codes. + * This function mirrors the `padStart` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. * * Pads this string with another string (multiple times, if needed) until the resulting string * reaches the given length. The padding is applied from the start of this string. @@ -216,22 +217,22 @@ export function padEnd(string: string, targetLength: number, padString: string = */ // Note: Limit with padString only works when length(padString) = 1, will be fixed with https://github.com/sallar/stringz/pull/59 export function padStart(string: string, targetLength: number, padString: string = ' '): string { - if (targetLength <= length(string)) return string; + if (targetLength <= stringLength(string)) return string; return stringzLimit(string, targetLength, padString, 'left'); } // This is a helper function that performs a correction on the slice index to make sure it // cannot go out of bounds -function correctSliceIndex(stringLength: number, index: number) { - if (index > stringLength) return stringLength; - if (index < -stringLength) return 0; - if (index < 0) return index + stringLength; +function correctSliceIndex(length: number, index: number) { + if (index > length) return length; + if (index < -length) return 0; + if (index < 0) return index + length; return index; } /** - * This function mirrors the `slice` function from the JavaScript Standard String object. - * It handles Unicode code points instead of UTF-16 character codes. + * This function mirrors the `slice` function from the JavaScript Standard String object. It handles + * Unicode code points instead of UTF-16 character codes. * * Extracts a section of this string and returns it as a new string, without modifying the original * string. @@ -242,31 +243,26 @@ function correctSliceIndex(stringLength: number, index: number) { * @returns A new string containing the extracted section of the string. */ export function slice(string: string, indexStart: number, indexEnd?: number): string { - const stringLength: number = length(string); + const length: number = stringLength(string); if ( - indexStart > stringLength || + indexStart > length || (indexEnd && ((indexStart > indexEnd && - !( - indexStart > 0 && - indexStart < stringLength && - indexEnd < 0 && - indexEnd > -stringLength - )) || - indexEnd < -stringLength || - (indexStart < 0 && indexStart > -stringLength && indexEnd > 0))) + !(indexStart > 0 && indexStart < length && indexEnd < 0 && indexEnd > -length)) || + indexEnd < -length || + (indexStart < 0 && indexStart > -length && indexEnd > 0))) ) return ''; - const newStart = correctSliceIndex(stringLength, indexStart); - const newEnd = indexEnd ? correctSliceIndex(stringLength, indexEnd) : undefined; + const newStart = correctSliceIndex(length, indexStart); + const newEnd = indexEnd ? correctSliceIndex(length, indexEnd) : undefined; return substring(string, newStart, newEnd); } /** - * This function mirrors the `split` function from the JavaScript Standard String object. - * It handles Unicode code points instead of UTF-16 character codes. + * This function mirrors the `split` function from the JavaScript Standard String object. It handles + * Unicode code points instead of UTF-16 character codes. * * Takes a pattern and divides the string into an ordered list of substrings by searching for the * pattern, puts these substrings into an array, and returns the array. @@ -304,7 +300,7 @@ export function split(string: string, separator: string | RegExp, splitLimit?: n for (let index = 0; index < (splitLimit ? splitLimit - 1 : matches.length); index++) { const matchIndex = indexOf(string, matches[index], currentIndex); - const matchLength = length(matches[index]); + const matchLength = stringLength(matches[index]); result.push(substring(string, currentIndex, matchIndex)); currentIndex = matchIndex + matchLength; @@ -320,8 +316,8 @@ export function split(string: string, separator: string | RegExp, splitLimit?: n } /** - * This function mirrors the `startsWith` function from the JavaScript Standard String object. - * It handles Unicode code points instead of UTF-16 character codes. + * This function mirrors the `startsWith` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. * * Determines whether the string begins with the characters of a specified string, returning true or * false as appropriate. @@ -340,8 +336,8 @@ export function startsWith(string: string, searchString: string, position: numbe } /** - * This function mirrors the `substr` function from the JavaScript Standard String object. - * It handles Unicode code points instead of UTF-16 character codes. + * This function mirrors the `substr` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. * * Returns a substring by providing start and length. This function is not exported because it is * considered deprecated, however it is still useful as a local helper function. @@ -352,13 +348,17 @@ export function startsWith(string: string, searchString: string, position: numbe * length minus start parameter` * @returns Substring from starting string */ -function substr(string: string, begin: number = 0, len: number = length(string) - begin): string { +function substr( + string: string, + begin: number = 0, + len: number = stringLength(string) - begin, +): string { return stringzSubstr(string, begin, len); } /** - * This function mirrors the `substring` function from the JavaScript Standard String object. - * It handles Unicode code points instead of UTF-16 character codes. + * This function mirrors the `substring` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. * * Returns a substring by providing start and end position. * @@ -367,13 +367,17 @@ function substr(string: string, begin: number = 0, len: number = length(string) * @param end End position. Default is `End of string` * @returns Substring from starting string */ -export function substring(string: string, begin: number, end: number = length(string)): string { +export function substring( + string: string, + begin: number, + end: number = stringLength(string), +): string { return stringzSubstring(string, begin, end); } /** - * This function mirrors the `toArray` function from the JavaScript Standard String object. - * It handles Unicode code points instead of UTF-16 character codes. + * This function mirrors the `toArray` function from the JavaScript Standard String object. It + * handles Unicode code points instead of UTF-16 character codes. * * Converts a string to an array of string characters. * diff --git a/src/extension-host/services/extension-storage.service.ts b/src/extension-host/services/extension-storage.service.ts index 707856dc48..d9c1e41d85 100644 --- a/src/extension-host/services/extension-storage.service.ts +++ b/src/extension-host/services/extension-storage.service.ts @@ -8,7 +8,7 @@ import { import { ExecutionToken } from '@node/models/execution-token.model'; import executionTokenService from '@node/services/execution-token.service'; import { Buffer } from 'buffer'; -import { length, includes } from 'platform-bible-utils'; +import { stringLength, includes } from 'platform-bible-utils'; // #region Functions that need to be called by other services to initialize this service @@ -67,7 +67,7 @@ export function buildExtensionPathFromName(extensionName: string, fileName: stri function buildUserDataPath(token: ExecutionToken, key: string): string { if (!executionTokenService.tokenIsValid(token)) throw new Error('Invalid token'); const subDir: string = sanitizeDirectoryName(token.name); - if (!subDir || length(subDir) === 0) throw new Error('Bad extension name'); + if (!subDir || stringLength(subDir) === 0) throw new Error('Bad extension name'); // From https://base64.guru/standards/base64url, the purpose of "base64url" encoding is // "the ability to use the encoding result as filename or URL address" diff --git a/src/extension-host/services/extension.service.ts b/src/extension-host/services/extension.service.ts index 6c78984ded..03ff253fef 100644 --- a/src/extension-host/services/extension.service.ts +++ b/src/extension-host/services/extension.service.ts @@ -23,7 +23,7 @@ import { deserialize, endsWith, includes, - length, + stringLength, startsWith, slice, } from 'platform-bible-utils'; @@ -491,7 +491,7 @@ async function cacheExtensionTypeDeclarations(extensionInfos: ExtensionInfo[]) { userExtensionTypesCacheUri, // Folder name must match module name which we are assuming is the same as the name of the // .d.ts file, so get the .d.ts file's name and use it as the folder name - slice(extensionDtsBaseDestination, 0, -length('.d.ts')), + slice(extensionDtsBaseDestination, 0, -stringLength('.d.ts')), 'index.d.ts', ); diff --git a/src/main/services/extension-asset-protocol.service.ts b/src/main/services/extension-asset-protocol.service.ts index cf017faf7e..e92608e621 100644 --- a/src/main/services/extension-asset-protocol.service.ts +++ b/src/main/services/extension-asset-protocol.service.ts @@ -1,7 +1,7 @@ import { protocol } from 'electron'; import { StatusCodes } from 'http-status-codes'; import extensionAssetService from '@shared/services/extension-asset.service'; -import { includes, indexOf, lastIndexOf, length, substring } from 'platform-bible-utils'; +import { includes, indexOf, lastIndexOf, stringLength, substring } from 'platform-bible-utils'; /** Here some of the most common MIME types that we expect to handle */ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types @@ -68,7 +68,7 @@ const initialize = () => { // 2) Use request headers to pass along the extension name so extension code doesn't have to embed its name in URLs. // Remove "papi-extension://" from the front of the URL - const uri: string = substring(request.url, length(`${protocolName}://`)); + const uri: string = substring(request.url, stringLength(`${protocolName}://`)); // There have to be at least 2 parts to the URI divided by a slash if (!includes(uri, '/')) { @@ -86,7 +86,7 @@ const initialize = () => { // allowed in URLs. So let's decode both of them before passing them to the extension host. extension = decodeURIComponent(extension); asset = decodeURIComponent(asset); - if (length(extension) > 100 || length(asset) > 100) { + if (stringLength(extension) > 100 || stringLength(asset) > 100) { return errorResponse(request.url, StatusCodes.BAD_REQUEST); } diff --git a/src/node/models/execution-token.model.ts b/src/node/models/execution-token.model.ts index 9914bbb9dc..8e1ba10aef 100644 --- a/src/node/models/execution-token.model.ts +++ b/src/node/models/execution-token.model.ts @@ -1,6 +1,6 @@ import crypto from 'crypto'; import { createNonce } from '@node/utils/crypto-util'; -import { length } from 'platform-bible-utils'; +import { stringLength } from 'platform-bible-utils'; /** For now this is just for extensions, but maybe we will want to expand this in the future */ export type ExecutionTokenType = 'extension'; @@ -13,7 +13,7 @@ export class ExecutionToken { constructor(tokenType: ExecutionTokenType, name: string) { if (!tokenType) throw new Error('token type must be defined'); - if (!name || length(name) < 1) throw new Error('name must be a string of length > 0'); + if (!name || stringLength(name) < 1) throw new Error('name must be a string of length > 0'); this.type = tokenType; this.name = name; diff --git a/src/node/services/execution-token.service.ts b/src/node/services/execution-token.service.ts index cae94fb62d..623c190698 100644 --- a/src/node/services/execution-token.service.ts +++ b/src/node/services/execution-token.service.ts @@ -1,11 +1,11 @@ import { ExecutionToken, ExecutionTokenType } from '@node/models/execution-token.model'; -import { length } from 'platform-bible-utils'; +import { stringLength } from 'platform-bible-utils'; const tokenMap = new Map(); function getMapKey(name: string, tokenType: ExecutionTokenType = 'extension'): string { - if (!name || length(name) < 1) throw new Error('name must be defined'); - if (!tokenType || length(tokenType) < 1) throw new Error('type must be defined'); + if (!name || stringLength(name) < 1) throw new Error('name must be defined'); + if (!tokenType || stringLength(tokenType) < 1) throw new Error('type must be defined'); return `${tokenType}:${name}`; } diff --git a/src/shared/models/data-provider.model.ts b/src/shared/models/data-provider.model.ts index 5693936d8f..b2be660036 100644 --- a/src/shared/models/data-provider.model.ts +++ b/src/shared/models/data-provider.model.ts @@ -1,5 +1,5 @@ import { - length, + stringLength, UnsubscriberAsync, PlatformEventHandler, substring, @@ -241,7 +241,7 @@ export function getDataProviderDataTypeFromFunctionName< // Assert the expected return type. // eslint-disable-next-line no-type-assertion/no-type-assertion - return substring(fnName, length(fnPrefix)) as DataTypeNames; + return substring(fnName, stringLength(fnPrefix)) as DataTypeNames; } export default DataProviderInternal; diff --git a/src/shared/services/network.service.ts b/src/shared/services/network.service.ts index e02b0b6b28..08a71f318b 100644 --- a/src/shared/services/network.service.ts +++ b/src/shared/services/network.service.ts @@ -15,7 +15,7 @@ import { } from '@shared/data/internal-connection.model'; import { aggregateUnsubscriberAsyncs, - length, + stringLength, UnsubscriberAsync, getErrorMessage, wait, @@ -149,7 +149,7 @@ function validateCommandFormatting(commandName: string) { throw new Error( `Invalid command name ${commandName}: must have non-empty string before a period`, ); - if (periodIndex >= length(commandName) - 1) + if (periodIndex >= stringLength(commandName) - 1) throw new Error( `Invalid command name ${commandName}: must have a non-empty string after a period`, ); diff --git a/src/shared/utils/util.ts b/src/shared/utils/util.ts index 933e9b1a56..18ea621cf2 100644 --- a/src/shared/utils/util.ts +++ b/src/shared/utils/util.ts @@ -4,12 +4,12 @@ import { charAt, indexOf, isString, - length, + stringLength, substring, } from 'platform-bible-utils'; const NONCE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; -const NONCE_CHARS_LENGTH = length(NONCE_CHARS); +const NONCE_CHARS_LENGTH = stringLength(NONCE_CHARS); /** * Create a nonce that is at least 128 bits long and should be (is not currently) cryptographically * random. See nonce spec at https://w3c.github.io/webappsec-csp/#security-nonces @@ -182,7 +182,7 @@ export function deserializeRequestType(requestType: SerializedRequestType): Requ if (!requestType) throw new Error('deserializeRequestType: must be a non-empty string'); const colonIndex = indexOf(requestType, REQUEST_TYPE_SEPARATOR); - if (colonIndex <= 0 || colonIndex >= length(requestType) - 1) + if (colonIndex <= 0 || colonIndex >= stringLength(requestType) - 1) throw new Error( `deserializeRequestType: Must have two parts divided by a ${REQUEST_TYPE_SEPARATOR} (${requestType})`, );