diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/action-popup.html | 2 | ||||
-rw-r--r-- | ext/display-templates.html | 46 | ||||
-rw-r--r-- | ext/js/app/popup-factory.js | 1 | ||||
-rw-r--r-- | ext/js/background/backend.js | 105 | ||||
-rw-r--r-- | ext/js/comm/api.js | 4 | ||||
-rw-r--r-- | ext/js/comm/cross-frame-api.js | 31 | ||||
-rw-r--r-- | ext/js/core.js | 4 | ||||
-rw-r--r-- | ext/js/dom/dom-text-scanner.js | 4 | ||||
-rw-r--r-- | ext/js/dom/sandbox/css-style-applier.js | 4 | ||||
-rw-r--r-- | ext/js/language/translator.js | 6 | ||||
-rw-r--r-- | ext/js/yomichan.js | 28 | ||||
-rw-r--r-- | ext/lib/dexie-export-import.js | 3457 | ||||
-rw-r--r-- | ext/lib/dexie-export-import.js.map (renamed from ext/lib/dexie-export-import.min.js.map) | 0 | ||||
-rw-r--r-- | ext/lib/dexie-export-import.min.js | 271 | ||||
-rw-r--r-- | ext/permissions.html | 14 | ||||
-rw-r--r-- | ext/popup.html | 8 | ||||
-rw-r--r-- | ext/search.html | 4 | ||||
-rw-r--r-- | ext/settings.html | 349 | ||||
-rw-r--r-- | ext/welcome.html | 44 |
19 files changed, 3778 insertions, 604 deletions
diff --git a/ext/action-popup.html b/ext/action-popup.html index d153f6eb..bf1fe166 100644 --- a/ext/action-popup.html +++ b/ext/action-popup.html @@ -25,7 +25,7 @@ </div> </label> <div class="nav-button-container"> - <button class="nav-button action-select-profile" title="Change primary profile" hidden> + <button type="button" class="nav-button action-select-profile" title="Change primary profile" hidden> <span class="icon" data-icon="profile"></span> <span class="profile-select-container"><select class="profile-select" id="profile-select"> <optgroup label="Primary Profile" id="profile-select-option-group"></optgroup> diff --git a/ext/display-templates.html b/ext/display-templates.html index 979415c7..ed0037bb 100644 --- a/ext/display-templates.html +++ b/ext/display-templates.html @@ -5,27 +5,27 @@ <div class="entry-current-indicator" title="Current entry"><span class="entry-current-indicator-inner"></span></div> <div class="entry-header"> <div class="actions"> - <button class="action-button action-button-collapsible" data-action="view-tags" hidden disabled> + <button type="button" class="action-button action-button-collapsible" data-action="view-tags" hidden disabled> <span class="action-icon icon" data-icon="tag"></span> </button> - <button class="action-button" data-action="view-note" hidden disabled title="View added note" data-hotkey='["viewNote","title","View added note ({0})"]' data-menu-position="left below h-cover v-cover"> + <button type="button" class="action-button" data-action="view-note" hidden disabled title="View added note" data-hotkey='["viewNote","title","View added note ({0})"]' data-menu-position="left below h-cover v-cover"> <span class="action-icon icon color-icon" data-icon="view-note"></span> <span class="action-button-badge icon" hidden></span> </button> - <button class="action-button" data-action="add-note" hidden disabled data-mode="term-kanji" title="Add expression" data-hotkey='["addNoteTermKanji","title","Add expression ({0})"]'> + <button type="button" class="action-button" data-action="add-note" hidden disabled data-mode="term-kanji" title="Add expression" data-hotkey='["addNoteTermKanji","title","Add expression ({0})"]'> <span class="action-icon icon color-icon" data-icon="add-term-kanji"></span> </button> - <button class="action-button" data-action="add-note" hidden disabled data-mode="term-kana" title="Add reading" data-hotkey='["addNoteTermKana","title","Add reading ({0})"]'> + <button type="button" class="action-button" data-action="add-note" hidden disabled data-mode="term-kana" title="Add reading" data-hotkey='["addNoteTermKana","title","Add reading ({0})"]'> <span class="action-icon icon color-icon" data-icon="add-term-kana"></span> </button> - <button class="action-button" data-action="play-audio" title="Play audio" data-title-default="Play audio" data-hotkey='["playAudio",["title","data-title-default"],"Play audio ({0})"]' data-menu-position="left below h-cover v-cover"> + <button type="button" class="action-button" data-action="play-audio" title="Play audio" data-title-default="Play audio" data-hotkey='["playAudio",["title","data-title-default"],"Play audio ({0})"]' data-menu-position="left below h-cover v-cover"> <span class="action-icon icon color-icon" data-icon="play-audio"></span> <span class="action-button-badge icon" hidden></span> </button> <span class="entry-current-indicator-icon" title="Current entry"> <span class="icon color-icon" data-icon="entry-current"></span> </span> - <button class="action-button action-button-collapsible" data-action="menu" data-menu-position="left below h-cover v-cover"> + <button type="button" class="action-button action-button-collapsible" data-action="menu" data-menu-position="left below h-cover v-cover"> <span class="action-icon icon" data-icon="kebab-menu"></span> </button> </div> @@ -58,7 +58,7 @@ </span> </div> <div class="headword-details"> - <button class="action-button" data-action="play-audio" title="Play audio" data-title-default="Play audio" data-hotkey='["playAudio",["title","data-title-default"],"Play audio ({0})"]' data-menu-position="right below h-cover v-cover"> + <button type="button" class="action-button" data-action="play-audio" title="Play audio" data-title-default="Play audio" data-hotkey='["playAudio",["title","data-title-default"],"Play audio ({0})"]' data-menu-position="right below h-cover v-cover"> <span class="action-icon icon color-icon" data-icon="play-audio"></span> <span class="action-button-badge icon" hidden></span> </button> @@ -66,7 +66,7 @@ </div></template> <template id="definition-item-template" data-remove-whitespace-text="true"><li class="definition-item"> <div class="definition-item-inner"> - <button class="definition-item-expansion-button"><div class="definition-item-expansion-button-icon icon" data-icon="double-down-chevron"></div></button> + <button type="button" class="definition-item-expansion-button"><div class="definition-item-expansion-button-icon icon" data-icon="double-down-chevron"></div></button> <div class="definition-item-content"> <div class="definition-tag-list tag-list"></div> <div class="definition-disambiguation-list"></div> @@ -110,16 +110,16 @@ <div class="entry-current-indicator" title="Current entry"><span class="entry-current-indicator-inner"></span></div> <div class="entry-header"> <div class="actions"> - <button class="action-button" data-action="view-note" hidden disabled title="View added note" data-hotkey='["viewNote","title","View added note ({0})"]'> + <button type="button" class="action-button" data-action="view-note" hidden disabled title="View added note" data-hotkey='["viewNote","title","View added note ({0})"]'> <span class="action-icon icon color-icon" data-icon="view-note"></span> </button> - <button class="action-button" data-action="add-note" hidden disabled data-mode="kanji" title="Add kanji" data-hotkey='["addNoteKanji","title","Add kanji ({0})"]'> + <button type="button" class="action-button" data-action="add-note" hidden disabled data-mode="kanji" title="Add kanji" data-hotkey='["addNoteKanji","title","Add kanji ({0})"]'> <span class="action-icon icon color-icon" data-icon="add-term-kanji"></span> </button> <span class="entry-current-indicator-icon" title="Current entry"> <span class="icon color-icon" data-icon="entry-current"></span> </span> - <button class="action-button action-button-collapsible" data-action="menu" data-menu-position="left below h-cover v-cover"> + <button type="button" class="action-button action-button-collapsible" data-action="menu" data-menu-position="left below h-cover v-cover"> <span class="action-icon icon" data-icon="kebab-menu"></span> </button> </div> @@ -136,25 +136,25 @@ </div> <table class="kanji-glyph-data"><tbody> <tr> - <th>Meaning</th> - <th>Readings</th> - <th>Statistics</th> + <th scope="col">Meaning</th> + <th scope="col">Readings</th> + <th scope="col">Statistics</th> </tr> <tr> <td class="kanji-gloss-container"><ol class="kanji-gloss-list"></ol></td> <td class="kanji-readings"><dl class="kanji-readings-chinese"></dl><dl class="kanji-readings-japanese"></dl></td> <td class="kanji-statistics"></td> </tr> - <tr><th colspan="3">Classifications</th></tr> + <tr><th scope="col" colspan="3">Classifications</th></tr> <tr><td colspan="3" class="kanji-classifications"></td></tr> - <tr><th colspan="3">Codepoints</th></tr> + <tr><th scope="col" colspan="3">Codepoints</th></tr> <tr><td colspan="3" class="kanji-codepoints"></td></tr> - <tr><th colspan="3">Dictionary Indices</th></tr> + <tr><th scope="col" colspan="3">Dictionary Indices</th></tr> <tr><td colspan="3" class="kanji-dictionary-indices"></td></tr> </tbody></table> </div></template> <template id="kanji-info-table-template"><table class="kanji-info-table"><tbody class="kanji-info-table-body"></tbody></table></template> -<template id="kanji-info-table-item-template"><tr class="kanji-info-table-item"><th class="kanji-info-table-item-header"></th><td class="kanji-info-table-item-value"></td></tr></template> +<template id="kanji-info-table-item-template"><tr class="kanji-info-table-item"><th scope="col" class="kanji-info-table-item-header"></th><td class="kanji-info-table-item-value"></td></tr></template> <template id="kanji-info-table-empty-template"><tr class="kanji-info-table-item kanji-info-table-item-empty"><td class="kanji-info-table-item-value-empty">No data found</td></tr></template> <template id="kanji-gloss-item-template"><li class="kanji-gloss-item"><span class="kanji-gloss-content"></span></li></template> <!-- [html-validate-disable element-required-ancestor] --> @@ -169,7 +169,7 @@ <template id="footer-notification-template"><div class="footer-notification scrollbar-inverse"> <div class="footer-notification-body"></div> <div class="footer-notification-close-button-container"> - <button class="footer-notification-close-button"><span class="footer-notification-close-button-icon icon" data-icon="cross"></span></button> + <button type="button" class="footer-notification-close-button"><span class="footer-notification-close-button-icon icon" data-icon="cross"></span></button> </div> </div></template> <template id="footer-notification-tag-details-template" data-remove-whitespace-text="true"> @@ -193,12 +193,12 @@ <!-- Popup menu --> <template id="audio-button-popup-menu-template"><div class="popup-menu-container scan-disable audio-button-popup-menu" tabindex="-1" role="dialog"><div class="popup-menu popup-menu-auto-size"><div class="popup-menu-body"></div></div></div></template> <template id="audio-button-popup-menu-item-template"><div class="popup-menu-item-group"> - <button class="popup-menu-item popup-menu-item-audio-button" data-menu-action="playAudioFromSource"><div class="popup-menu-item-icon icon" data-icon="none"></div><span class="popup-menu-item-label"></span></button> - <button class="popup-menu-item popup-menu-item-set-primary-audio-button" data-menu-action="setPrimaryAudio" title="Use as audio for Anki card"><div class="popup-menu-item-icon icon" data-icon="note-card"></div></button> + <button type="button" class="popup-menu-item popup-menu-item-audio-button" data-menu-action="playAudioFromSource"><div class="popup-menu-item-icon icon" data-icon="none"></div><span class="popup-menu-item-label"></span></button> + <button type="button" class="popup-menu-item popup-menu-item-set-primary-audio-button" data-menu-action="setPrimaryAudio" title="Use as audio for Anki card"><div class="popup-menu-item-icon icon" data-icon="note-card"></div></button> </div></template> <template id="view-note-button-popup-menu-template"><div class="popup-menu-container scan-disable view-note-button-popup-menu" tabindex="-1" role="dialog"><div class="popup-menu popup-menu-auto-size"><div class="popup-menu-body"></div></div></div></template> -<template id="view-note-button-popup-menu-item-template"><button class="popup-menu-item"><span class="popup-menu-item-label"></span></button></template> +<template id="view-note-button-popup-menu-item-template"><button type="button" class="popup-menu-item"><span class="popup-menu-item-label"></span></button></template> <template id="dictionary-entry-popup-menu-template"><div class="popup-menu-container scan-disable dictionary-entry-popup-menu" tabindex="-1" role="dialog"><div class="popup-menu popup-menu-auto-size"><div class="popup-menu-body"></div></div></div></template> -<template id="dictionary-entry-popup-menu-item-template"><button class="popup-menu-item"><span class="popup-menu-item-label"></span></button></template> +<template id="dictionary-entry-popup-menu-item-template"><button type="button" class="popup-menu-item"><span class="popup-menu-item-label"></span></button></template> </body></html> diff --git a/ext/js/app/popup-factory.js b/ext/js/app/popup-factory.js index eeb31a1b..c3c98162 100644 --- a/ext/js/app/popup-factory.js +++ b/ext/js/app/popup-factory.js @@ -71,6 +71,7 @@ class PopupFactory { * @param {?number} [details.depth] A specific depth value to assign to the popup. * @param {boolean} [details.popupWindow] Whether or not a separate popup window should be used, rather than an iframe. * @param {boolean} [details.childrenSupported] Whether or not the popup is able to show child popups. + * @returns {Popup|PopupWindow|PopupProxy} The new or existing popup. */ async getOrCreatePopup({ frameId=null, diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js index dd233abb..565f4abf 100644 --- a/ext/js/background/backend.js +++ b/ext/js/background/backend.js @@ -139,7 +139,8 @@ class Backend { ['textHasJapaneseCharacters', {async: false, contentScript: true, handler: this._onApiTextHasJapaneseCharacters.bind(this)}], ['getTermFrequencies', {async: true, contentScript: true, handler: this._onApiGetTermFrequencies.bind(this)}], ['findAnkiNotes', {async: true, contentScript: true, handler: this._onApiFindAnkiNotes.bind(this)}], - ['loadExtensionScripts', {async: true, contentScript: true, handler: this._onApiLoadExtensionScripts.bind(this)}] + ['loadExtensionScripts', {async: true, contentScript: true, handler: this._onApiLoadExtensionScripts.bind(this)}], + ['openCrossFramePort', {async: false, contentScript: true, handler: this._onApiOpenCrossFramePort.bind(this)}] ]); this._messageHandlersWithProgress = new Map([ ]); @@ -189,9 +190,6 @@ class Backend { chrome.tabs.onZoomChange.addListener(onZoomChange); } - const onConnect = this._onWebExtensionEventWrapper(this._onConnect.bind(this)); - chrome.runtime.onConnect.addListener(onConnect); - const onMessage = this._onMessageWrapper.bind(this); chrome.runtime.onMessage.addListener(onMessage); @@ -228,8 +226,8 @@ class Backend { log.error(e); } - const deinflectionReasions = await this._fetchAsset('/data/deinflect.json', true); - this._translator.prepare(deinflectionReasions); + const deinflectionReasons = await this._fetchAsset('/data/deinflect.json', true); + this._translator.prepare(deinflectionReasons); await this._optionsUtil.prepare(); this._defaultAnkiFieldTemplates = (await this._fetchAsset('/data/templates/default-anki-field-templates.handlebars')).trim(); @@ -331,58 +329,6 @@ class Backend { return invokeMessageHandler(messageHandler, params, callback, sender); } - _onConnect(port) { - try { - let details; - try { - details = JSON.parse(port.name); - } catch (e) { - return; - } - if (details.name !== 'background-cross-frame-communication-port') { return; } - - const senderTabId = (port.sender && port.sender.tab ? port.sender.tab.id : null); - if (typeof senderTabId !== 'number') { - throw new Error('Port does not have an associated tab ID'); - } - const senderFrameId = port.sender.frameId; - if (typeof senderFrameId !== 'number') { - throw new Error('Port does not have an associated frame ID'); - } - let {targetTabId, targetFrameId} = details; - if (typeof targetTabId !== 'number') { - targetTabId = senderTabId; - } - - const details2 = { - name: 'cross-frame-communication-port', - sourceTabId: senderTabId, - sourceFrameId: senderFrameId - }; - let forwardPort = chrome.tabs.connect(targetTabId, {frameId: targetFrameId, name: JSON.stringify(details2)}); - - const cleanup = () => { - this._checkLastError(chrome.runtime.lastError); - if (forwardPort !== null) { - forwardPort.disconnect(); - forwardPort = null; - } - if (port !== null) { - port.disconnect(); - port = null; - } - }; - - port.onMessage.addListener((message) => { forwardPort.postMessage(message); }); - forwardPort.onMessage.addListener((message) => { port.postMessage(message); }); - port.onDisconnect.addListener(cleanup); - forwardPort.onDisconnect.addListener(cleanup); - } catch (e) { - port.disconnect(); - log.error(e); - } - } - _onZoomChange({tabId, oldZoomFactor, newZoomFactor}) { this._sendMessageTabIgnoreResponse(tabId, {action: 'Yomichan.zoomChanged', params: {oldZoomFactor, newZoomFactor}}); } @@ -2273,4 +2219,47 @@ class Backend { } return results; } + + _onApiOpenCrossFramePort({targetTabId, targetFrameId}, sender) { + const sourceTabId = (sender && sender.tab ? sender.tab.id : null); + if (typeof sourceTabId !== 'number') { + throw new Error('Port does not have an associated tab ID'); + } + const sourceFrameId = sender.frameId; + if (typeof sourceFrameId !== 'number') { + throw new Error('Port does not have an associated frame ID'); + } + + const sourceDetails = { + name: 'cross-frame-communication-port', + otherTabId: targetTabId, + otherFrameId: targetFrameId + }; + const targetDetails = { + name: 'cross-frame-communication-port', + otherTabId: sourceTabId, + otherFrameId: sourceFrameId + }; + let sourcePort = chrome.tabs.connect(sourceTabId, {frameId: sourceFrameId, name: JSON.stringify(sourceDetails)}); + let targetPort = chrome.tabs.connect(targetTabId, {frameId: targetFrameId, name: JSON.stringify(targetDetails)}); + + const cleanup = () => { + this._checkLastError(chrome.runtime.lastError); + if (targetPort !== null) { + targetPort.disconnect(); + targetPort = null; + } + if (sourcePort !== null) { + sourcePort.disconnect(); + sourcePort = null; + } + }; + + sourcePort.onMessage.addListener((message) => { targetPort.postMessage(message); }); + targetPort.onMessage.addListener((message) => { sourcePort.postMessage(message); }); + sourcePort.onDisconnect.addListener(cleanup); + targetPort.onDisconnect.addListener(cleanup); + + return {targetTabId, targetFrameId}; + } } diff --git a/ext/js/comm/api.js b/ext/js/comm/api.js index de12bb6c..72d2ba07 100644 --- a/ext/js/comm/api.js +++ b/ext/js/comm/api.js @@ -181,6 +181,10 @@ class API { return this._invoke('loadExtensionScripts', {files}); } + openCrossFramePort(targetTabId, targetFrameId) { + return this._invoke('openCrossFramePort', {targetTabId, targetFrameId}); + } + // Utilities _createActionPort(timeout=5000) { diff --git a/ext/js/comm/cross-frame-api.js b/ext/js/comm/cross-frame-api.js index 7892eb4c..fb2a1718 100644 --- a/ext/js/comm/cross-frame-api.js +++ b/ext/js/comm/cross-frame-api.js @@ -224,10 +224,13 @@ class CrossFrameAPI { this._commPorts = new Map(); this._messageHandlers = new Map(); this._onDisconnectBind = this._onDisconnect.bind(this); + this._tabId = null; + this._frameId = null; } - prepare() { + async prepare() { chrome.runtime.onConnect.addListener(this._onConnect.bind(this)); + ({tabId: this._tabId, frameId: this._frameId} = await yomichan.api.frameInformationGet()); } invoke(targetFrameId, action, params={}) { @@ -235,8 +238,8 @@ class CrossFrameAPI { } async invokeTab(targetTabId, targetFrameId, action, params={}) { - if (typeof targetTabId !== 'number') { targetTabId = null; } - const commPort = this._getOrCreateCommPort(targetTabId, targetFrameId); + if (typeof targetTabId !== 'number') { targetTabId = this._tabId; } + const commPort = await this._getOrCreateCommPort(targetTabId, targetFrameId); return await commPort.invoke(action, params, this._ackTimeout, this._responseTimeout); } @@ -265,8 +268,8 @@ class CrossFrameAPI { } if (details.name !== 'cross-frame-communication-port') { return; } - const otherTabId = details.sourceTabId; - const otherFrameId = details.sourceFrameId; + const otherTabId = details.otherTabId; + const otherFrameId = details.otherFrameId; this._setupCommPort(otherTabId, otherFrameId, port); } catch (e) { port.disconnect(); @@ -297,14 +300,16 @@ class CrossFrameAPI { return this._createCommPort(otherTabId, otherFrameId); } - _createCommPort(otherTabId, otherFrameId) { - const details = { - name: 'background-cross-frame-communication-port', - targetTabId: otherTabId, - targetFrameId: otherFrameId - }; - const port = yomichan.connect(null, {name: JSON.stringify(details)}); - return this._setupCommPort(otherTabId, otherFrameId, port); + async _createCommPort(otherTabId, otherFrameId) { + await yomichan.api.openCrossFramePort(otherTabId, otherFrameId); + + const tabPorts = this._commPorts.get(otherTabId); + if (typeof tabPorts !== 'undefined') { + const commPort = tabPorts.get(otherFrameId); + if (typeof commPort !== 'undefined') { + return commPort; + } + } } _setupCommPort(otherTabId, otherFrameId, port) { diff --git a/ext/js/core.js b/ext/js/core.js index 5b064a36..1e749c7d 100644 --- a/ext/js/core.js +++ b/ext/js/core.js @@ -309,7 +309,7 @@ function promiseTimeout(delay, resolveValue) { * Creates a promise that will resolve after the next animation frame, using `requestAnimationFrame`. * @param {number} [timeout] A maximum duration (in milliseconds) to wait until the promise resolves. If null or omitted, no timeout is used. * @returns {Promise<{time: number, timeout: number}>} A promise that is resolved with `{time, timeout}`, where `time` is the timestamp from `requestAnimationFrame`, - * and `timeout` is a boolean indicating whether the cause was a timeout or not. + * and `timeout` is a boolean indicating whether the cause was a timeout or not. * @throws The promise throws an error if animation is not supported in this context, such as in a service worker. */ function promiseAnimationFrame(timeout=null) { @@ -609,7 +609,7 @@ class DynamicProperty extends EventDispatcher { * @param {*} value The override value to assign. * @param {number} [priority] The priority value to use, as a number. * @returns {string} A string token which can be passed to the clearOverride function - * to remove the override. + * to remove the override. */ setOverride(value, priority=0) { const overridesCount = this._overrides.length; diff --git a/ext/js/dom/dom-text-scanner.js b/ext/js/dom/dom-text-scanner.js index dc5bd96a..ec4c7bd6 100644 --- a/ext/js/dom/dom-text-scanner.js +++ b/ext/js/dom/dom-text-scanner.js @@ -405,8 +405,8 @@ class DOMTextScanner { * @returns {{enterable: boolean, newlines: number}} The seek information. * The `enterable` value indicates whether the content of this node should be entered. * The `newlines` value corresponds to the number of newline characters that should be added. - * 1 newline corresponds to a simple new line in the layout. - * 2 newlines corresponds to a significant visual distinction since the previous content. + * - 1 newline corresponds to a simple new line in the layout. + * - 2 newlines corresponds to a significant visual distinction since the previous content. */ static getElementSeekInfo(element) { let enterable = true; diff --git a/ext/js/dom/sandbox/css-style-applier.js b/ext/js/dom/sandbox/css-style-applier.js index 01936d26..a47ef6ef 100644 --- a/ext/js/dom/sandbox/css-style-applier.js +++ b/ext/js/dom/sandbox/css-style-applier.js @@ -35,9 +35,10 @@ class CssStyleApplier { * @property {string} value The property's value. */ + /* eslint-disable jsdoc/check-line-alignment */ /** * Creates a new instance of the class. - * @param {string} styleDataUrl The local URL to the JSON file continaing the style rules. + * @param {string} styleDataUrl The local URL to the JSON file containing the style rules. * The style rules should be of the format: * ``` * [ @@ -57,6 +58,7 @@ class CssStyleApplier { this._patternHtmlWhitespace = /[\t\r\n\f ]+/g; this._patternClassNameCharacter = /[0-9a-zA-Z-_]/; } + /* eslint-enable jsdoc/check-line-alignment */ /** * Loads the data file for use. diff --git a/ext/js/language/translator.js b/ext/js/language/translator.js index edb38bfb..3b47cc51 100644 --- a/ext/js/language/translator.js +++ b/ext/js/language/translator.js @@ -93,6 +93,12 @@ class Translator { } if (mode === 'simple') { + if (sortFrequencyDictionary !== null) { + const sortDictionaryMap = [sortFrequencyDictionary] + .filter((key) => enabledDictionaryMap.has(key)) + .reduce((subMap, key) => subMap.set(key, enabledDictionaryMap.get(key)), new Map()); + await this._addTermMeta(dictionaryEntries, sortDictionaryMap); + } this._clearTermTags(dictionaryEntries); } else { await this._addTermMeta(dictionaryEntries, enabledDictionaryMap); diff --git a/ext/js/yomichan.js b/ext/js/yomichan.js index 6eea952e..a4feaa23 100644 --- a/ext/js/yomichan.js +++ b/ext/js/yomichan.js @@ -129,12 +129,12 @@ class Yomichan extends EventDispatcher { if (!isBackground) { this._api = new API(this); - this._crossFrame = new CrossFrameAPI(); - this._crossFrame.prepare(); - this.sendMessage({action: 'requestBackendReadySignal'}); await this._isBackendReadyPromise; + this._crossFrame = new CrossFrameAPI(); + await this._crossFrame.prepare(); + log.on('log', this._onForwardLog.bind(this)); } } @@ -172,24 +172,6 @@ class Yomichan extends EventDispatcher { } } - /** - * Runs `chrome.runtime.connect()` with additional exception handling events. - * @param {...*} args The arguments to be passed to `chrome.runtime.connect()`. - * @returns {Port} The resulting port. - * @throws {Error} Errors thrown by `chrome.runtime.connect()` are re-thrown. - */ - connect(...args) { - try { - return chrome.runtime.connect(...args); - } catch (e) { - this.triggerExtensionUnloaded(); - throw e; - } - } - - /** - * Runs chrome.runtime.connect() with additional exception handling events. - */ triggerExtensionUnloaded() { this._isExtensionUnloaded = true; if (this._isTriggeringExtensionUnloaded) { return; } @@ -232,7 +214,9 @@ class Yomichan extends EventDispatcher { } _onMessageOptionsUpdated({source}) { - this.trigger('optionsUpdated', {source}); + if (source !== 'background') { + this.trigger('optionsUpdated', {source}); + } } _onMessageDatabaseUpdated({type, cause}) { diff --git a/ext/lib/dexie-export-import.js b/ext/lib/dexie-export-import.js new file mode 100644 index 00000000..f915d1c1 --- /dev/null +++ b/ext/lib/dexie-export-import.js @@ -0,0 +1,3457 @@ +/* ========================================================================== + * dexie-export-import.js + * ========================================================================== + * + * Dexie addon for exporting and importing databases to / from Blobs. + * + * By David Fahlander, david.fahlander@gmail.com, + * + * ========================================================================== + * + * Version 4.0.7, Wed Mar 29 2023 + * + * https://dexie.org + * + * Apache License Version 2.0, January 2004, http://www.apache.org/licenses/ + * + */ + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('dexie')) : + typeof define === 'function' && define.amd ? define(['exports', 'dexie'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.DexieExportImport = {}, global.Dexie)); +})(this, (function (exports, Dexie) { 'use strict'; + + function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } + + var Dexie__default = /*#__PURE__*/_interopDefaultLegacy(Dexie); + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + + function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + } + + function __generator(thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } + } + + function getSchemaString(table) { + var primKeyAndIndexes = [table.schema.primKey].concat(table.schema.indexes); + return primKeyAndIndexes.map(function (index) { return index.src; }).join(','); + } + function extractDbSchema(exportedDb) { + var schema = {}; + for (var _i = 0, _a = exportedDb.tables; _i < _a.length; _i++) { + var table = _a[_i]; + schema[table.name] = table.schema; + } + return schema; + } + function readBlobAsync(blob, type) { + return new Promise(function (resolve, reject) { + var reader = new FileReader(); + reader.onabort = function (ev) { return reject(new Error("file read aborted")); }; + reader.onerror = function (ev) { return reject(ev.target.error); }; + reader.onload = function (ev) { return resolve(ev.target.result); }; + if (type === 'binary') + reader.readAsArrayBuffer(blob); + else + reader.readAsText(blob); + }); + } + function readBlobSync(blob, type) { + if (typeof FileReaderSync === 'undefined') { + throw new Error('FileReaderSync missing. Reading blobs synchronously requires code to run from within a web worker. Use TSON.encapsulateAsync() to do it from the main thread.'); + } + var reader = new FileReaderSync(); // Requires worker environment + var data = type === 'binary' ? + reader.readAsArrayBuffer(blob) : + reader.readAsText(blob); + return data; + } + + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; + } + + var typeson = createCommonjsModule(function (module, exports) { + (function (global, factory) { + module.exports = factory() ; + }(commonjsGlobal, (function () { + function _typeof(obj) { + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function (obj) { + return typeof obj; + }; + } else { + _typeof = function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; + } + + return _typeof(obj); + } + + function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { + try { + var info = gen[key](arg); + var value = info.value; + } catch (error) { + reject(error); + return; + } + + if (info.done) { + resolve(value); + } else { + Promise.resolve(value).then(_next, _throw); + } + } + + function _asyncToGenerator(fn) { + return function () { + var self = this, + args = arguments; + return new Promise(function (resolve, reject) { + var gen = fn.apply(self, args); + + function _next(value) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); + } + + function _throw(err) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); + } + + _next(undefined); + }); + }; + } + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; + } + + function ownKeys(object, enumerableOnly) { + var keys = Object.keys(object); + + if (Object.getOwnPropertySymbols) { + var symbols = Object.getOwnPropertySymbols(object); + if (enumerableOnly) symbols = symbols.filter(function (sym) { + return Object.getOwnPropertyDescriptor(object, sym).enumerable; + }); + keys.push.apply(keys, symbols); + } + + return keys; + } + + function _objectSpread2(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i] != null ? arguments[i] : {}; + + if (i % 2) { + ownKeys(Object(source), true).forEach(function (key) { + _defineProperty(target, key, source[key]); + }); + } else if (Object.getOwnPropertyDescriptors) { + Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); + } else { + ownKeys(Object(source)).forEach(function (key) { + Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); + }); + } + } + + return target; + } + + function _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); + } + + function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); + } + + function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } + } + + function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; + } + + function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); + } + + function _iterableToArrayLimit(arr, i) { + if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { + return; + } + + var _arr = []; + var _n = true; + var _d = false; + var _e = undefined; + + try { + for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"] != null) _i["return"](); + } finally { + if (_d) throw _e; + } + } + + return _arr; + } + + function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); + } + + function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); + } + + /** + * We keep this function minimized so if using two instances of this + * library, where one is minimized and one is not, it will still work + * with `hasConstructorOf`. + * With ES6 classes, we may be able to simply use `class TypesonPromise + * extends Promise` and add a string tag for detection. + * @param {function} f + */ + // eslint-disable-next-line max-len + // eslint-disable-next-line block-spacing, space-before-function-paren, space-before-blocks, space-infix-ops, semi, promise/avoid-new + var TypesonPromise = function TypesonPromise(f) { + _classCallCheck(this, TypesonPromise); + + this.p = new Promise(f); + }; // eslint-disable-next-line max-len + // class TypesonPromise extends Promise {get[Symbol.toStringTag](){return 'TypesonPromise'};} // eslint-disable-line keyword-spacing, space-before-function-paren, space-before-blocks, block-spacing, semi + + + TypesonPromise.__typeson__type__ = 'TypesonPromise'; // Note: core-js-bundle provides a `Symbol` polyfill + + /* istanbul ignore else */ + + if (typeof Symbol !== 'undefined') { + // Ensure `isUserObject` will return `false` for `TypesonPromise` + TypesonPromise.prototype[Symbol.toStringTag] = 'TypesonPromise'; + } + /** + * + * @param {function} [onFulfilled] + * @param {function} [onRejected] + * @returns {TypesonPromise} + */ + + + TypesonPromise.prototype.then = function (onFulfilled, onRejected) { + var _this = this; + + return new TypesonPromise(function (typesonResolve, typesonReject) { + // eslint-disable-next-line promise/catch-or-return + _this.p.then(function (res) { + // eslint-disable-next-line promise/always-return + typesonResolve(onFulfilled ? onFulfilled(res) : res); + })["catch"](function (res) { + return onRejected ? onRejected(res) : Promise.reject(res); + }).then(typesonResolve, typesonReject); + }); + }; + /** + * + * @param {function} onRejected + * @returns {TypesonPromise} + */ + + + TypesonPromise.prototype["catch"] = function (onRejected) { + return this.then(null, onRejected); + }; + /** + * + * @param {Any} v + * @returns {TypesonPromise} + */ + + + TypesonPromise.resolve = function (v) { + return new TypesonPromise(function (typesonResolve) { + typesonResolve(v); + }); + }; + /** + * + * @param {Any} v + * @returns {TypesonPromise} + */ + + + TypesonPromise.reject = function (v) { + return new TypesonPromise(function (typesonResolve, typesonReject) { + typesonReject(v); + }); + }; + + ['all', 'race'].forEach(function (meth) { + /** + * + * @param {Promise[]} promArr + * @returns {TypesonPromise} + */ + TypesonPromise[meth] = function (promArr) { + return new TypesonPromise(function (typesonResolve, typesonReject) { + // eslint-disable-next-line promise/catch-or-return + Promise[meth](promArr.map(function (prom) { + return prom && prom.constructor && prom.constructor.__typeson__type__ === 'TypesonPromise' ? prom.p : prom; + })).then(typesonResolve, typesonReject); + }); + }; + }); + + var _ref = {}, + toStr = _ref.toString, + hasOwn = {}.hasOwnProperty, + getProto = Object.getPrototypeOf, + fnToString = hasOwn.toString; + /** + * Second argument not in use internally, but provided for utility. + * @param {Any} v + * @param {boolean} catchCheck + * @returns {boolean} + */ + + function isThenable(v, catchCheck) { + return isObject(v) && typeof v.then === 'function' && (!catchCheck || typeof v["catch"] === 'function'); + } + /** + * + * @param {Any} val + * @returns {string} + */ + + + function toStringTag(val) { + return toStr.call(val).slice(8, -1); + } + /** + * This function is dependent on both constructors + * being identical so any minimization is expected of both. + * @param {Any} a + * @param {function} b + * @returns {boolean} + */ + + + function hasConstructorOf(a, b) { + if (!a || _typeof(a) !== 'object') { + return false; + } + + var proto = getProto(a); + + if (!proto) { + return b === null; + } + + var Ctor = hasOwn.call(proto, 'constructor') && proto.constructor; + + if (typeof Ctor !== 'function') { + return b === null; + } + + if (b === Ctor) { + return true; + } + + if (b !== null && fnToString.call(Ctor) === fnToString.call(b)) { + return true; + } + + if (typeof b === 'function' && typeof Ctor.__typeson__type__ === 'string' && Ctor.__typeson__type__ === b.__typeson__type__) { + return true; + } + + return false; + } + /** + * + * @param {Any} val + * @returns {boolean} + */ + + + function isPlainObject(val) { + // Mirrors jQuery's + if (!val || toStringTag(val) !== 'Object') { + return false; + } + + var proto = getProto(val); + + if (!proto) { + // `Object.create(null)` + return true; + } + + return hasConstructorOf(val, Object); + } + /** + * + * @param {Any} val + * @returns {boolean} + */ + + + function isUserObject(val) { + if (!val || toStringTag(val) !== 'Object') { + return false; + } + + var proto = getProto(val); + + if (!proto) { + // `Object.create(null)` + return true; + } + + return hasConstructorOf(val, Object) || isUserObject(proto); + } + /** + * + * @param {Any} v + * @returns {boolean} + */ + + + function isObject(v) { + return v && _typeof(v) === 'object'; + } + /** + * + * @param {string} keyPathComponent + * @returns {string} + */ + + + function escapeKeyPathComponent(keyPathComponent) { + return keyPathComponent.replace(/~/g, '~0').replace(/\./g, '~1'); + } + /** + * + * @param {string} keyPathComponent + * @returns {string} + */ + + + function unescapeKeyPathComponent(keyPathComponent) { + return keyPathComponent.replace(/~1/g, '.').replace(/~0/g, '~'); + } + /** + * @param {PlainObject|GenericArray} obj + * @param {string} keyPath + * @returns {Any} + */ + + + function getByKeyPath(obj, keyPath) { + if (keyPath === '') { + return obj; + } + + var period = keyPath.indexOf('.'); + + if (period > -1) { + var innerObj = obj[unescapeKeyPathComponent(keyPath.slice(0, period))]; + return innerObj === undefined ? undefined : getByKeyPath(innerObj, keyPath.slice(period + 1)); + } + + return obj[unescapeKeyPathComponent(keyPath)]; + } + /** + * + * @param {PlainObject} obj + * @param {string} keyPath + * @param {Any} value + * @returns {Any} + */ + + + function setAtKeyPath(obj, keyPath, value) { + if (keyPath === '') { + return value; + } + + var period = keyPath.indexOf('.'); + + if (period > -1) { + var innerObj = obj[unescapeKeyPathComponent(keyPath.slice(0, period))]; + return setAtKeyPath(innerObj, keyPath.slice(period + 1), value); + } + + obj[unescapeKeyPathComponent(keyPath)] = value; + return obj; + } + /** + * + * @param {external:JSON} value + * @returns {"null"|"array"|"undefined"|"boolean"|"number"|"string"| + * "object"|"symbol"} + */ + + + function getJSONType(value) { + return value === null ? 'null' : Array.isArray(value) ? 'array' : _typeof(value); + } + + var keys = Object.keys, + isArray = Array.isArray, + hasOwn$1 = {}.hasOwnProperty, + internalStateObjPropsToIgnore = ['type', 'replaced', 'iterateIn', 'iterateUnsetNumeric']; + /** + * Handle plain object revivers first so reference setting can use + * revived type (e.g., array instead of object); assumes revived + * has same structure or will otherwise break subsequent references. + * @param {PlainObjectType} a + * @param {PlainObjectType} b + * @returns {1|-1|boolean} + */ + + function nestedPathsFirst(a, b) { + if (a.keypath === '') { + return -1; + } + + var as = a.keypath.match(/\./g) || 0; + var bs = b.keypath.match(/\./g) || 0; + + if (as) { + as = as.length; + } + + if (bs) { + bs = bs.length; + } + + return as > bs ? -1 : as < bs ? 1 : a.keypath < b.keypath ? -1 : a.keypath > b.keypath; + } + /** + * An instance of this class can be used to call `stringify()` and `parse()`. + * Typeson resolves cyclic references by default. Can also be extended to + * support custom types using the register() method. + * + * @class + * @param {{cyclic: boolean}} [options] - if cyclic (default true), + * cyclic references will be handled gracefully. + */ + + + var Typeson = + /*#__PURE__*/ + function () { + function Typeson(options) { + _classCallCheck(this, Typeson); + + this.options = options; // Replacers signature: replace (value). Returns falsy if not + // replacing. Otherwise ['Date', value.getTime()] + + this.plainObjectReplacers = []; + this.nonplainObjectReplacers = []; // Revivers: [{type => reviver}, {plain: boolean}]. + // Sample: [{'Date': value => new Date(value)}, {plain: false}] + + this.revivers = {}; + /** Types registered via `register()`. */ + + this.types = {}; + } + /** + * @typedef {null|boolean|number|string|GenericArray|PlainObject} JSON + */ + + /** + * @callback JSONReplacer + * @param {""|string} key + * @param {JSON} value + * @returns {number|string|boolean|null|PlainObject|undefined} + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#The%20replacer%20parameter + */ + + /** + * Serialize given object to Typeson. + * Initial arguments work identical to those of `JSON.stringify`. + * The `replacer` argument has nothing to do with our replacers. + * @param {Any} obj + * @param {JSONReplacer|string[]} replacer + * @param {number|string} space + * @param {object} opts + * @returns {string|Promise} Promise resolves to a string + */ + + + _createClass(Typeson, [{ + key: "stringify", + value: function stringify(obj, replacer, space, opts) { + opts = _objectSpread2({}, this.options, {}, opts, { + stringification: true + }); + var encapsulated = this.encapsulate(obj, null, opts); + + if (isArray(encapsulated)) { + return JSON.stringify(encapsulated[0], replacer, space); + } + + return encapsulated.then(function (res) { + return JSON.stringify(res, replacer, space); + }); + } + /** + * Also sync but throws on non-sync result. + * @param {Any} obj + * @param {JSONReplacer|string[]} replacer + * @param {number|string} space + * @param {object} opts + * @returns {string} + */ + + }, { + key: "stringifySync", + value: function stringifySync(obj, replacer, space, opts) { + return this.stringify(obj, replacer, space, _objectSpread2({ + throwOnBadSyncType: true + }, opts, { + sync: true + })); + } + /** + * + * @param {Any} obj + * @param {JSONReplacer|string[]} replacer + * @param {number|string} space + * @param {object} opts + * @returns {Promise<string>} + */ + + }, { + key: "stringifyAsync", + value: function stringifyAsync(obj, replacer, space, opts) { + return this.stringify(obj, replacer, space, _objectSpread2({ + throwOnBadSyncType: true + }, opts, { + sync: false + })); + } + /** + * Parse Typeson back into an obejct. + * Initial arguments works identical to those of `JSON.parse()`. + * @param {string} text + * @param {function} reviver This JSON reviver has nothing to do with + * our revivers. + * @param {object} opts + * @returns {external:JSON} + */ + + }, { + key: "parse", + value: function parse(text, reviver, opts) { + opts = _objectSpread2({}, this.options, {}, opts, { + parse: true + }); + return this.revive(JSON.parse(text, reviver), opts); + } + /** + * Also sync but throws on non-sync result. + * @param {string} text + * @param {function} reviver This JSON reviver has nothing to do with + * our revivers. + * @param {object} opts + * @returns {external:JSON} + */ + + }, { + key: "parseSync", + value: function parseSync(text, reviver, opts) { + return this.parse(text, reviver, _objectSpread2({ + throwOnBadSyncType: true + }, opts, { + sync: true + })); + } + /** + * @param {string} text + * @param {function} reviver This JSON reviver has nothing to do with + * our revivers. + * @param {object} opts + * @returns {Promise} Resolves to `external:JSON` + */ + + }, { + key: "parseAsync", + value: function parseAsync(text, reviver, opts) { + return this.parse(text, reviver, _objectSpread2({ + throwOnBadSyncType: true + }, opts, { + sync: false + })); + } + /** + * + * @param {Any} obj + * @param {object} stateObj + * @param {object} [opts={}] + * @returns {string[]|false} + */ + + }, { + key: "specialTypeNames", + value: function specialTypeNames(obj, stateObj) { + var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + opts.returnTypeNames = true; + return this.encapsulate(obj, stateObj, opts); + } + /** + * + * @param {Any} obj + * @param {PlainObject} stateObj + * @param {PlainObject} [opts={}] + * @returns {Promise|GenericArray|PlainObject|string|false} + */ + + }, { + key: "rootTypeName", + value: function rootTypeName(obj, stateObj) { + var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + opts.iterateNone = true; + return this.encapsulate(obj, stateObj, opts); + } + /** + * Encapsulate a complex object into a plain Object by replacing + * registered types with plain objects representing the types data. + * + * This method is used internally by `Typeson.stringify()`. + * @param {Any} obj - Object to encapsulate. + * @param {PlainObject} stateObj + * @param {PlainObject} opts + * @returns {Promise|GenericArray|PlainObject|string|false} + */ + + }, { + key: "encapsulate", + value: function encapsulate(obj, stateObj, opts) { + opts = _objectSpread2({ + sync: true + }, this.options, {}, opts); + var _opts = opts, + sync = _opts.sync; + var that = this, + types = {}, + refObjs = [], + // For checking cyclic references + refKeys = [], + // For checking cyclic references + promisesDataRoot = []; // Clone the object deeply while at the same time replacing any + // special types or cyclic reference: + + var cyclic = 'cyclic' in opts ? opts.cyclic : true; + var _opts2 = opts, + encapsulateObserver = _opts2.encapsulateObserver; + + var ret = _encapsulate('', obj, cyclic, stateObj || {}, promisesDataRoot); + /** + * + * @param {Any} ret + * @returns {GenericArray|PlainObject|string|false} + */ + + + function finish(ret) { + // Add `$types` to result only if we ever bumped into a + // special type (or special case where object has own `$types`) + var typeNames = Object.values(types); + + if (opts.iterateNone) { + if (typeNames.length) { + return typeNames[0]; + } + + return Typeson.getJSONType(ret); + } + + if (typeNames.length) { + if (opts.returnTypeNames) { + return _toConsumableArray(new Set(typeNames)); + } // Special if array (or a primitive) was serialized + // because JSON would ignore custom `$types` prop on it + + + if (!ret || !isPlainObject(ret) || // Also need to handle if this is an object with its + // own `$types` property (to avoid ambiguity) + hasOwn$1.call(ret, '$types')) { + ret = { + $: ret, + $types: { + $: types + } + }; + } else { + ret.$types = types; + } // No special types + + } else if (isObject(ret) && hasOwn$1.call(ret, '$types')) { + ret = { + $: ret, + $types: true + }; + } + + if (opts.returnTypeNames) { + return false; + } + + return ret; + } + /** + * + * @param {Any} ret + * @param {GenericArray} promisesData + * @returns {Promise<Any>} + */ + + + function checkPromises(_x, _x2) { + return _checkPromises.apply(this, arguments); + } + /** + * + * @param {object} stateObj + * @param {object} ownKeysObj + * @param {function} cb + * @returns {undefined} + */ + + + function _checkPromises() { + _checkPromises = _asyncToGenerator( + /*#__PURE__*/ + regeneratorRuntime.mark(function _callee2(ret, promisesData) { + var promResults; + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + _context2.next = 2; + return Promise.all(promisesData.map(function (pd) { + return pd[1].p; + })); + + case 2: + promResults = _context2.sent; + _context2.next = 5; + return Promise.all(promResults.map( + /*#__PURE__*/ + function () { + var _ref = _asyncToGenerator( + /*#__PURE__*/ + regeneratorRuntime.mark(function _callee(promResult) { + var newPromisesData, _promisesData$splice, _promisesData$splice2, prData, _prData, keyPath, cyclic, stateObj, parentObj, key, detectedType, encaps, isTypesonPromise, encaps2; + + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + newPromisesData = []; + _promisesData$splice = promisesData.splice(0, 1), _promisesData$splice2 = _slicedToArray(_promisesData$splice, 1), prData = _promisesData$splice2[0]; + _prData = _slicedToArray(prData, 7), keyPath = _prData[0], cyclic = _prData[2], stateObj = _prData[3], parentObj = _prData[4], key = _prData[5], detectedType = _prData[6]; + encaps = _encapsulate(keyPath, promResult, cyclic, stateObj, newPromisesData, true, detectedType); + isTypesonPromise = hasConstructorOf(encaps, TypesonPromise); // Handle case where an embedded custom type itself + // returns a `Typeson.Promise` + + if (!(keyPath && isTypesonPromise)) { + _context.next = 11; + break; + } + + _context.next = 8; + return encaps.p; + + case 8: + encaps2 = _context.sent; + parentObj[key] = encaps2; + return _context.abrupt("return", checkPromises(ret, newPromisesData)); + + case 11: + if (keyPath) { + parentObj[key] = encaps; + } else if (isTypesonPromise) { + ret = encaps.p; + } else { + // If this is itself a `Typeson.Promise` (because the + // original value supplied was a `Promise` or + // because the supplied custom type value resolved + // to one), returning it below will be fine since + // a `Promise` is expected anyways given current + // config (and if not a `Promise`, it will be ready + // as the resolve value) + ret = encaps; + } + + return _context.abrupt("return", checkPromises(ret, newPromisesData)); + + case 13: + case "end": + return _context.stop(); + } + } + }, _callee); + })); + + return function (_x3) { + return _ref.apply(this, arguments); + }; + }())); + + case 5: + return _context2.abrupt("return", ret); + + case 6: + case "end": + return _context2.stop(); + } + } + }, _callee2); + })); + return _checkPromises.apply(this, arguments); + } + + function _adaptBuiltinStateObjectProperties(stateObj, ownKeysObj, cb) { + Object.assign(stateObj, ownKeysObj); + var vals = internalStateObjPropsToIgnore.map(function (prop) { + var tmp = stateObj[prop]; + delete stateObj[prop]; + return tmp; + }); // eslint-disable-next-line callback-return + + cb(); + internalStateObjPropsToIgnore.forEach(function (prop, i) { + stateObj[prop] = vals[i]; + }); + } + /** + * + * @param {string} keypath + * @param {Any} value + * @param {boolean} cyclic + * @param {PlainObject} stateObj + * @param {boolean} promisesData + * @param {boolean} resolvingTypesonPromise + * @param {string} detectedType + * @returns {Any} + */ + + + function _encapsulate(keypath, value, cyclic, stateObj, promisesData, resolvingTypesonPromise, detectedType) { + var ret; + var observerData = {}; + + var $typeof = _typeof(value); + + var runObserver = encapsulateObserver ? function (obj) { + var type = detectedType || stateObj.type || Typeson.getJSONType(value); + encapsulateObserver(Object.assign(obj || observerData, { + keypath: keypath, + value: value, + cyclic: cyclic, + stateObj: stateObj, + promisesData: promisesData, + resolvingTypesonPromise: resolvingTypesonPromise, + awaitingTypesonPromise: hasConstructorOf(value, TypesonPromise) + }, { + type: type + })); + } : null; + + if (['string', 'boolean', 'number', 'undefined'].includes($typeof)) { + if (value === undefined || $typeof === 'number' && (isNaN(value) || value === -Infinity || value === Infinity)) { + if (stateObj.replaced) { + ret = value; + } else { + ret = replace(keypath, value, stateObj, promisesData, false, resolvingTypesonPromise, runObserver); + } + + if (ret !== value) { + observerData = { + replaced: ret + }; + } + } else { + ret = value; + } + + if (runObserver) { + runObserver(); + } + + return ret; + } + + if (value === null) { + if (runObserver) { + runObserver(); + } + + return value; + } + + if (cyclic && !stateObj.iterateIn && !stateObj.iterateUnsetNumeric && value && _typeof(value) === 'object') { + // Options set to detect cyclic references and be able + // to rewrite them. + var refIndex = refObjs.indexOf(value); + + if (refIndex < 0) { + if (cyclic === true) { + refObjs.push(value); + refKeys.push(keypath); + } + } else { + types[keypath] = '#'; + + if (runObserver) { + runObserver({ + cyclicKeypath: refKeys[refIndex] + }); + } + + return '#' + refKeys[refIndex]; + } + } + + var isPlainObj = isPlainObject(value); + var isArr = isArray(value); + var replaced = // Running replace will cause infinite loop as will test + // positive again + (isPlainObj || isArr) && (!that.plainObjectReplacers.length || stateObj.replaced) || stateObj.iterateIn ? // Optimization: if plain object and no plain-object + // replacers, don't try finding a replacer + value : replace(keypath, value, stateObj, promisesData, isPlainObj || isArr, null, runObserver); + var clone; + + if (replaced !== value) { + ret = replaced; + observerData = { + replaced: replaced + }; + } else { + // eslint-disable-next-line no-lonely-if + if (keypath === '' && hasConstructorOf(value, TypesonPromise)) { + promisesData.push([keypath, value, cyclic, stateObj, undefined, undefined, stateObj.type]); + ret = value; + } else if (isArr && stateObj.iterateIn !== 'object' || stateObj.iterateIn === 'array') { + clone = new Array(value.length); + observerData = { + clone: clone + }; + } else if (!['function', 'symbol'].includes(_typeof(value)) && !('toJSON' in value) && !hasConstructorOf(value, TypesonPromise) && !hasConstructorOf(value, Promise) && !hasConstructorOf(value, ArrayBuffer) || isPlainObj || stateObj.iterateIn === 'object') { + clone = {}; + + if (stateObj.addLength) { + clone.length = value.length; + } + + observerData = { + clone: clone + }; + } else { + ret = value; // Only clone vanilla objects and arrays + } + } + + if (runObserver) { + runObserver(); + } + + if (opts.iterateNone) { + return clone || ret; + } + + if (!clone) { + return ret; + } // Iterate object or array + + + if (stateObj.iterateIn) { + var _loop = function _loop(key) { + var ownKeysObj = { + ownKeys: hasOwn$1.call(value, key) + }; + + _adaptBuiltinStateObjectProperties(stateObj, ownKeysObj, function () { + var kp = keypath + (keypath ? '.' : '') + escapeKeyPathComponent(key); + + var val = _encapsulate(kp, value[key], Boolean(cyclic), stateObj, promisesData, resolvingTypesonPromise); + + if (hasConstructorOf(val, TypesonPromise)) { + promisesData.push([kp, val, Boolean(cyclic), stateObj, clone, key, stateObj.type]); + } else if (val !== undefined) { + clone[key] = val; + } + }); + }; + + // eslint-disable-next-line guard-for-in + for (var key in value) { + _loop(key); + } + + if (runObserver) { + runObserver({ + endIterateIn: true, + end: true + }); + } + } else { + // Note: Non-indexes on arrays won't survive stringify so + // somewhat wasteful for arrays, but so too is iterating + // all numeric indexes on sparse arrays when not wanted + // or filtering own keys for positive integers + keys(value).forEach(function (key) { + var kp = keypath + (keypath ? '.' : '') + escapeKeyPathComponent(key); + var ownKeysObj = { + ownKeys: true + }; + + _adaptBuiltinStateObjectProperties(stateObj, ownKeysObj, function () { + var val = _encapsulate(kp, value[key], Boolean(cyclic), stateObj, promisesData, resolvingTypesonPromise); + + if (hasConstructorOf(val, TypesonPromise)) { + promisesData.push([kp, val, Boolean(cyclic), stateObj, clone, key, stateObj.type]); + } else if (val !== undefined) { + clone[key] = val; + } + }); + }); + + if (runObserver) { + runObserver({ + endIterateOwn: true, + end: true + }); + } + } // Iterate array for non-own numeric properties (we can't + // replace the prior loop though as it iterates non-integer + // keys) + + + if (stateObj.iterateUnsetNumeric) { + var vl = value.length; + + var _loop2 = function _loop2(i) { + if (!(i in value)) { + // No need to escape numeric + var kp = keypath + (keypath ? '.' : '') + i; + var ownKeysObj = { + ownKeys: false + }; + + _adaptBuiltinStateObjectProperties(stateObj, ownKeysObj, function () { + var val = _encapsulate(kp, undefined, Boolean(cyclic), stateObj, promisesData, resolvingTypesonPromise); + + if (hasConstructorOf(val, TypesonPromise)) { + promisesData.push([kp, val, Boolean(cyclic), stateObj, clone, i, stateObj.type]); + } else if (val !== undefined) { + clone[i] = val; + } + }); + } + }; + + for (var i = 0; i < vl; i++) { + _loop2(i); + } + + if (runObserver) { + runObserver({ + endIterateUnsetNumeric: true, + end: true + }); + } + } + + return clone; + } + /** + * + * @param {string} keypath + * @param {Any} value + * @param {PlainObject} stateObj + * @param {GenericArray} promisesData + * @param {boolean} plainObject + * @param {boolean} resolvingTypesonPromise + * @param {function} [runObserver] + * @returns {*} + */ + + + function replace(keypath, value, stateObj, promisesData, plainObject, resolvingTypesonPromise, runObserver) { + // Encapsulate registered types + var replacers = plainObject ? that.plainObjectReplacers : that.nonplainObjectReplacers; + var i = replacers.length; + + while (i--) { + var replacer = replacers[i]; + + if (replacer.test(value, stateObj)) { + var type = replacer.type; + + if (that.revivers[type]) { + // Record the type only if a corresponding reviver + // exists. This is to support specs where only + // replacement is done. + // For example, ensuring deep cloning of the object, + // or replacing a type to its equivalent without + // the need to revive it. + var existing = types[keypath]; // type can comprise an array of types (see test + // "should support intermediate types") + + types[keypath] = existing ? [type].concat(existing) : type; + } + + Object.assign(stateObj, { + type: type, + replaced: true + }); + + if ((sync || !replacer.replaceAsync) && !replacer.replace) { + if (runObserver) { + runObserver({ + typeDetected: true + }); + } + + return _encapsulate(keypath, value, cyclic && 'readonly', stateObj, promisesData, resolvingTypesonPromise, type); + } + + if (runObserver) { + runObserver({ + replacing: true + }); + } // Now, also traverse the result in case it contains its + // own types to replace + + + var replaceMethod = sync || !replacer.replaceAsync ? 'replace' : 'replaceAsync'; + return _encapsulate(keypath, replacer[replaceMethod](value, stateObj), cyclic && 'readonly', stateObj, promisesData, resolvingTypesonPromise, type); + } + } + + return value; + } + + return promisesDataRoot.length ? sync && opts.throwOnBadSyncType ? function () { + throw new TypeError('Sync method requested but async result obtained'); + }() : Promise.resolve(checkPromises(ret, promisesDataRoot)).then(finish) : !sync && opts.throwOnBadSyncType ? function () { + throw new TypeError('Async method requested but sync result obtained'); + }() // If this is a synchronous request for stringification, yet + // a promise is the result, we don't want to resolve leading + // to an async result, so we return an array to avoid + // ambiguity + : opts.stringification && sync ? [finish(ret)] : sync ? finish(ret) : Promise.resolve(finish(ret)); + } + /** + * Also sync but throws on non-sync result. + * @param {*} obj + * @param {object} stateObj + * @param {object} opts + * @returns {*} + */ + + }, { + key: "encapsulateSync", + value: function encapsulateSync(obj, stateObj, opts) { + return this.encapsulate(obj, stateObj, _objectSpread2({ + throwOnBadSyncType: true + }, opts, { + sync: true + })); + } + /** + * @param {*} obj + * @param {object} stateObj + * @param {object} opts + * @returns {*} + */ + + }, { + key: "encapsulateAsync", + value: function encapsulateAsync(obj, stateObj, opts) { + return this.encapsulate(obj, stateObj, _objectSpread2({ + throwOnBadSyncType: true + }, opts, { + sync: false + })); + } + /** + * Revive an encapsulated object. + * This method is used internally by `Typeson.parse()`. + * @param {object} obj - Object to revive. If it has `$types` member, the + * properties that are listed there will be replaced with its true type + * instead of just plain objects. + * @param {object} opts + * @throws TypeError If mismatch between sync/async type and result + * @returns {Promise|*} If async, returns a Promise that resolves to `*` + */ + + }, { + key: "revive", + value: function revive(obj, opts) { + var types = obj && obj.$types; // No type info added. Revival not needed. + + if (!types) { + return obj; + } // Object happened to have own `$types` property but with + // no actual types, so we unescape and return that object + + + if (types === true) { + return obj.$; + } + + opts = _objectSpread2({ + sync: true + }, this.options, {}, opts); + var _opts3 = opts, + sync = _opts3.sync; + var keyPathResolutions = []; + var stateObj = {}; + var ignore$Types = true; // Special when root object is not a trivial Object, it will + // be encapsulated in `$`. It will also be encapsulated in + // `$` if it has its own `$` property to avoid ambiguity + + if (types.$ && isPlainObject(types.$)) { + obj = obj.$; + types = types.$; + ignore$Types = false; + } + + var that = this; + /** + * @callback RevivalReducer + * @param {Any} value + * @param {string} type + * @returns {Any} + */ + + /** + * + * @param {string} type + * @param {Any} val + * @returns {[type]} [description] + */ + + function executeReviver(type, val) { + var _ref2 = that.revivers[type] || [], + _ref3 = _slicedToArray(_ref2, 1), + reviver = _ref3[0]; + + if (!reviver) { + throw new Error('Unregistered type: ' + type); + } // Only `sync` expected here, as problematic async would + // be missing both `reviver` and `reviverAsync`, and + // encapsulation shouldn't have added types, so + // should have made an early exit + + + if (sync && !('revive' in reviver)) { + // Just return value as is + return val; + } + + return reviver[sync && reviver.revive ? 'revive' : !sync && reviver.reviveAsync ? 'reviveAsync' : 'revive'](val, stateObj); + } + /** + * + * @returns {void|TypesonPromise<void>} + */ + + + function revivePlainObjects() { + // const references = []; + // const reviveTypes = []; + var plainObjectTypes = []; + Object.entries(types).forEach(function (_ref4) { + var _ref5 = _slicedToArray(_ref4, 2), + keypath = _ref5[0], + type = _ref5[1]; + + if (type === '#') { + /* + references.push({ + keypath, + reference: getByKeyPath(obj, keypath) + }); + */ + return; + } + + [].concat(type).forEach(function (type) { + var _ref6 = that.revivers[type] || [null, {}], + _ref7 = _slicedToArray(_ref6, 2), + plain = _ref7[1].plain; + + if (!plain) { + // reviveTypes.push({keypath, type}); + return; + } + + plainObjectTypes.push({ + keypath: keypath, + type: type + }); + delete types[keypath]; // Avoid repeating + }); + }); + + if (!plainObjectTypes.length) { + return undefined; + } // console.log(plainObjectTypes.sort(nestedPathsFirst)); + + /** + * @typedef {PlainObject} PlainObjectType + * @property {string} keypath + * @property {string} type + */ + + + return plainObjectTypes.sort(nestedPathsFirst).reduce(function reducer(possibleTypesonPromise, _ref8) { + var keypath = _ref8.keypath, + type = _ref8.type; + + if (isThenable(possibleTypesonPromise)) { + return possibleTypesonPromise.then(function (val) { + return reducer(val, { + keypath: keypath, + type: type + }); + }); + } // console.log('obj', JSON.stringify(keypath), obj); + + + var val = getByKeyPath(obj, keypath); + val = executeReviver(type, val); + + if (hasConstructorOf(val, TypesonPromise)) { + return val.then(function (v) { + var newVal = setAtKeyPath(obj, keypath, v); + + if (newVal === v) { + obj = newVal; + } + + return undefined; + }); + } + + var newVal = setAtKeyPath(obj, keypath, val); + + if (newVal === val) { + obj = newVal; + } + + return undefined; + }, undefined // This argument must be explicit + ); // references.forEach(({keypath, reference}) => {}); + // reviveTypes.sort(nestedPathsFirst).forEach(() => {}); + } + + var revivalPromises = []; + /** + * + * @param {string} keypath + * @param {Any} value + * @param {?(Array|object)} target + * @param {Array|object} [clone] + * @param {string} [key] + * @returns {Any} + */ + + function _revive(keypath, value, target, clone, key) { + if (ignore$Types && keypath === '$types') { + return undefined; + } + + var type = types[keypath]; + var isArr = isArray(value); + + if (isArr || isPlainObject(value)) { + var _clone = isArr ? new Array(value.length) : {}; // Iterate object or array + + + keys(value).forEach(function (k) { + var val = _revive(keypath + (keypath ? '.' : '') + escapeKeyPathComponent(k), value[k], target || _clone, _clone, k); + + var set = function set(v) { + if (hasConstructorOf(v, Undefined)) { + _clone[k] = undefined; + } else if (v !== undefined) { + _clone[k] = v; + } + + return v; + }; + + if (hasConstructorOf(val, TypesonPromise)) { + revivalPromises.push(val.then(function (ret) { + return set(ret); + })); + } else { + set(val); + } + }); + value = _clone; // Try to resolve cyclic reference as soon as available + + while (keyPathResolutions.length) { + var _keyPathResolutions$ = _slicedToArray(keyPathResolutions[0], 4), + _target = _keyPathResolutions$[0], + keyPath = _keyPathResolutions$[1], + _clone2 = _keyPathResolutions$[2], + k = _keyPathResolutions$[3]; + + var val = getByKeyPath(_target, keyPath); // Typeson.Undefined not expected here as not cyclic or + // `undefined` + + if (val !== undefined) { + _clone2[k] = val; + } else { + break; + } + + keyPathResolutions.splice(0, 1); + } + } + + if (!type) { + return value; + } + + if (type === '#') { + var _ret = getByKeyPath(target, value.slice(1)); + + if (_ret === undefined) { + // Cyclic reference not yet available + keyPathResolutions.push([target, value.slice(1), clone, key]); + } + + return _ret; + } // `type` can be an array here + + + return [].concat(type).reduce(function reducer(val, typ) { + if (hasConstructorOf(val, TypesonPromise)) { + return val.then(function (v) { + // TypesonPromise here too + return reducer(v, typ); + }); + } + + return executeReviver(typ, val); + }, value); + } + /** + * + * @param {Any} retrn + * @returns {undefined|Any} + */ + + + function checkUndefined(retrn) { + return hasConstructorOf(retrn, Undefined) ? undefined : retrn; + } + + var possibleTypesonPromise = revivePlainObjects(); + var ret; + + if (hasConstructorOf(possibleTypesonPromise, TypesonPromise)) { + ret = possibleTypesonPromise.then(function () { + return obj; + }); + } else { + ret = _revive('', obj, null); + + if (revivalPromises.length) { + // Ensure children resolved + ret = TypesonPromise.resolve(ret).then(function (r) { + return TypesonPromise.all([// May be a TypesonPromise or not + r].concat(revivalPromises)); + }).then(function (_ref9) { + var _ref10 = _slicedToArray(_ref9, 1), + r = _ref10[0]; + + return r; + }); + } + } + + return isThenable(ret) ? sync && opts.throwOnBadSyncType ? function () { + throw new TypeError('Sync method requested but async result obtained'); + }() : hasConstructorOf(ret, TypesonPromise) ? ret.p.then(checkUndefined) : ret : !sync && opts.throwOnBadSyncType ? function () { + throw new TypeError('Async method requested but sync result obtained'); + }() : sync ? checkUndefined(ret) : Promise.resolve(checkUndefined(ret)); + } + /** + * Also sync but throws on non-sync result. + * @param {Any} obj + * @param {object} opts + * @returns {Any} + */ + + }, { + key: "reviveSync", + value: function reviveSync(obj, opts) { + return this.revive(obj, _objectSpread2({ + throwOnBadSyncType: true + }, opts, { + sync: true + })); + } + /** + * @param {Any} obj + * @param {object} opts + * @returns {Promise} Resolves to `*` + */ + + }, { + key: "reviveAsync", + value: function reviveAsync(obj, opts) { + return this.revive(obj, _objectSpread2({ + throwOnBadSyncType: true + }, opts, { + sync: false + })); + } + /** + * Register types. + * For examples on how to use this method, see + * {@link https://github.com/dfahlander/typeson-registry/tree/master/types}. + * @param {object.<string,Function[]>[]} typeSpecSets - Types and + * their functions [test, encapsulate, revive]; + * @param {object} opts + * @returns {Typeson} + */ + + }, { + key: "register", + value: function register(typeSpecSets, opts) { + opts = opts || {}; + [].concat(typeSpecSets).forEach(function R(typeSpec) { + var _this = this; + + // Allow arrays of arrays of arrays... + if (isArray(typeSpec)) { + return typeSpec.map(function (typSpec) { + return R.call(_this, typSpec); + }); + } + + typeSpec && keys(typeSpec).forEach(function (typeId) { + if (typeId === '#') { + throw new TypeError('# cannot be used as a type name as it is reserved ' + 'for cyclic objects'); + } else if (Typeson.JSON_TYPES.includes(typeId)) { + throw new TypeError('Plain JSON object types are reserved as type names'); + } + + var spec = typeSpec[typeId]; + var replacers = spec && spec.testPlainObjects ? this.plainObjectReplacers : this.nonplainObjectReplacers; + var existingReplacer = replacers.filter(function (r) { + return r.type === typeId; + }); + + if (existingReplacer.length) { + // Remove existing spec and replace with this one. + replacers.splice(replacers.indexOf(existingReplacer[0]), 1); + delete this.revivers[typeId]; + delete this.types[typeId]; + } + + if (typeof spec === 'function') { + // Support registering just a class without replacer/reviver + var Class = spec; + spec = { + test: function test(x) { + return x && x.constructor === Class; + }, + replace: function replace(x) { + return _objectSpread2({}, x); + }, + revive: function revive(x) { + return Object.assign(Object.create(Class.prototype), x); + } + }; + } else if (isArray(spec)) { + var _spec = spec, + _spec2 = _slicedToArray(_spec, 3), + test = _spec2[0], + replace = _spec2[1], + revive = _spec2[2]; + + spec = { + test: test, + replace: replace, + revive: revive + }; + } + + if (!spec || !spec.test) { + return; + } + + var replacerObj = { + type: typeId, + test: spec.test.bind(spec) + }; + + if (spec.replace) { + replacerObj.replace = spec.replace.bind(spec); + } + + if (spec.replaceAsync) { + replacerObj.replaceAsync = spec.replaceAsync.bind(spec); + } + + var start = typeof opts.fallback === 'number' ? opts.fallback : opts.fallback ? 0 : Infinity; + + if (spec.testPlainObjects) { + this.plainObjectReplacers.splice(start, 0, replacerObj); + } else { + this.nonplainObjectReplacers.splice(start, 0, replacerObj); + } // Todo: We might consider a testAsync type + + + if (spec.revive || spec.reviveAsync) { + var reviverObj = {}; + + if (spec.revive) { + reviverObj.revive = spec.revive.bind(spec); + } + + if (spec.reviveAsync) { + reviverObj.reviveAsync = spec.reviveAsync.bind(spec); + } + + this.revivers[typeId] = [reviverObj, { + plain: spec.testPlainObjects + }]; + } // Record to be retrieved via public types property. + + + this.types[typeId] = spec; + }, this); + }, this); + return this; + } + }]); + + return Typeson; + }(); + /** + * We keep this function minimized so if using two instances of this + * library, where one is minimized and one is not, it will still work + * with `hasConstructorOf`. + * @class + */ + + + var Undefined = function Undefined() { + _classCallCheck(this, Undefined); + }; // eslint-disable-line space-before-blocks + + + Undefined.__typeson__type__ = 'TypesonUndefined'; // The following provide classes meant to avoid clashes with other values + // To insist `undefined` should be added + + Typeson.Undefined = Undefined; // To support async encapsulation/stringification + + Typeson.Promise = TypesonPromise; // Some fundamental type-checking utilities + + Typeson.isThenable = isThenable; + Typeson.toStringTag = toStringTag; + Typeson.hasConstructorOf = hasConstructorOf; + Typeson.isObject = isObject; + Typeson.isPlainObject = isPlainObject; + Typeson.isUserObject = isUserObject; + Typeson.escapeKeyPathComponent = escapeKeyPathComponent; + Typeson.unescapeKeyPathComponent = unescapeKeyPathComponent; + Typeson.getByKeyPath = getByKeyPath; + Typeson.getJSONType = getJSONType; + Typeson.JSON_TYPES = ['null', 'boolean', 'number', 'string', 'array', 'object']; + + return Typeson; + + }))); + }); + + var structuredCloning = createCommonjsModule(function (module, exports) { + !function(e,t){module.exports=t();}(commonjsGlobal,(function(){function _typeof$1(e){return (_typeof$1="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function _classCallCheck$1(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties$1(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n);}}function _defineProperty$1(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function ownKeys$1(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n);}return r}function _toConsumableArray$1(e){return function _arrayWithoutHoles$1(e){if(Array.isArray(e))return _arrayLikeToArray$1(e)}(e)||function _iterableToArray$1(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||function _unsupportedIterableToArray$1(e,t){if(!e)return;if("string"==typeof e)return _arrayLikeToArray$1(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);"Object"===r&&e.constructor&&(r=e.constructor.name);if("Map"===r||"Set"===r)return Array.from(e);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return _arrayLikeToArray$1(e,t)}(e)||function _nonIterableSpread$1(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function _arrayLikeToArray$1(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function _typeof(e){return (_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function _typeof(e){return typeof e}:function _typeof(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n);}}function _defineProperty(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function ownKeys(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n);}return r}function _objectSpread2(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?ownKeys(Object(r),!0).forEach((function(t){_defineProperty(e,t,r[t]);})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):ownKeys(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t));}));}return e}function _slicedToArray(e,t){return function _arrayWithHoles(e){if(Array.isArray(e))return e}(e)||function _iterableToArrayLimit(e,t){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(e)))return;var r=[],n=!0,i=!1,o=void 0;try{for(var a,c=e[Symbol.iterator]();!(n=(a=c.next()).done)&&(r.push(a.value),!t||r.length!==t);n=!0);}catch(e){i=!0,o=e;}finally{try{n||null==c.return||c.return();}finally{if(i)throw o}}return r}(e,t)||_unsupportedIterableToArray(e,t)||function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function _toConsumableArray(e){return function _arrayWithoutHoles(e){if(Array.isArray(e))return _arrayLikeToArray(e)}(e)||function _iterableToArray(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||_unsupportedIterableToArray(e)||function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return "Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?_arrayLikeToArray(e,t):void 0}}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}var e=function TypesonPromise(e){_classCallCheck(this,TypesonPromise),this.p=new Promise(e);};e.__typeson__type__="TypesonPromise","undefined"!=typeof Symbol&&(e.prototype[Symbol.toStringTag]="TypesonPromise"),e.prototype.then=function(t,r){var n=this;return new e((function(e,i){n.p.then((function(r){e(t?t(r):r);})).catch((function(e){return r?r(e):Promise.reject(e)})).then(e,i);}))},e.prototype.catch=function(e){return this.then(null,e)},e.resolve=function(t){return new e((function(e){e(t);}))},e.reject=function(t){return new e((function(e,r){r(t);}))},["all","race"].forEach((function(t){e[t]=function(r){return new e((function(e,n){Promise[t](r.map((function(e){return e&&e.constructor&&"TypesonPromise"===e.constructor.__typeson__type__?e.p:e}))).then(e,n);}))};}));var t={}.toString,r={}.hasOwnProperty,n=Object.getPrototypeOf,i=r.toString;function isThenable(e,t){return isObject(e)&&"function"==typeof e.then&&(!t||"function"==typeof e.catch)}function toStringTag(e){return t.call(e).slice(8,-1)}function hasConstructorOf(e,t){if(!e||"object"!==_typeof(e))return !1;var o=n(e);if(!o)return null===t;var a=r.call(o,"constructor")&&o.constructor;return "function"!=typeof a?null===t:t===a||(null!==t&&i.call(a)===i.call(t)||"function"==typeof t&&"string"==typeof a.__typeson__type__&&a.__typeson__type__===t.__typeson__type__)}function isPlainObject(e){return !(!e||"Object"!==toStringTag(e))&&(!n(e)||hasConstructorOf(e,Object))}function isObject(e){return e&&"object"===_typeof(e)}function escapeKeyPathComponent(e){return e.replace(/~/g,"~0").replace(/\./g,"~1")}function unescapeKeyPathComponent(e){return e.replace(/~1/g,".").replace(/~0/g,"~")}function getByKeyPath(e,t){if(""===t)return e;var r=t.indexOf(".");if(r>-1){var n=e[unescapeKeyPathComponent(t.slice(0,r))];return void 0===n?void 0:getByKeyPath(n,t.slice(r+1))}return e[unescapeKeyPathComponent(t)]}function setAtKeyPath(e,t,r){if(""===t)return r;var n=t.indexOf(".");return n>-1?setAtKeyPath(e[unescapeKeyPathComponent(t.slice(0,n))],t.slice(n+1),r):(e[unescapeKeyPathComponent(t)]=r,e)}function _await(e,t,r){return r?t?t(e):e:(e&&e.then||(e=Promise.resolve(e)),t?e.then(t):e)}var o=Object.keys,a=Array.isArray,c={}.hasOwnProperty,u=["type","replaced","iterateIn","iterateUnsetNumeric"];function _async(e){return function(){for(var t=[],r=0;r<arguments.length;r++)t[r]=arguments[r];try{return Promise.resolve(e.apply(this,t))}catch(e){return Promise.reject(e)}}}function nestedPathsFirst(e,t){if(""===e.keypath)return -1;var r=e.keypath.match(/\./g)||0,n=t.keypath.match(/\./g)||0;return r&&(r=r.length),n&&(n=n.length),r>n?-1:r<n?1:e.keypath<t.keypath?-1:e.keypath>t.keypath}var s=function(){function Typeson(e){_classCallCheck(this,Typeson),this.options=e,this.plainObjectReplacers=[],this.nonplainObjectReplacers=[],this.revivers={},this.types={};}return function _createClass(e,t,r){return t&&_defineProperties(e.prototype,t),r&&_defineProperties(e,r),e}(Typeson,[{key:"stringify",value:function stringify(e,t,r,n){n=_objectSpread2(_objectSpread2(_objectSpread2({},this.options),n),{},{stringification:!0});var i=this.encapsulate(e,null,n);return a(i)?JSON.stringify(i[0],t,r):i.then((function(e){return JSON.stringify(e,t,r)}))}},{key:"stringifySync",value:function stringifySync(e,t,r,n){return this.stringify(e,t,r,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},n),{},{sync:!0}))}},{key:"stringifyAsync",value:function stringifyAsync(e,t,r,n){return this.stringify(e,t,r,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},n),{},{sync:!1}))}},{key:"parse",value:function parse(e,t,r){return r=_objectSpread2(_objectSpread2(_objectSpread2({},this.options),r),{},{parse:!0}),this.revive(JSON.parse(e,t),r)}},{key:"parseSync",value:function parseSync(e,t,r){return this.parse(e,t,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},r),{},{sync:!0}))}},{key:"parseAsync",value:function parseAsync(e,t,r){return this.parse(e,t,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},r),{},{sync:!1}))}},{key:"specialTypeNames",value:function specialTypeNames(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return r.returnTypeNames=!0,this.encapsulate(e,t,r)}},{key:"rootTypeName",value:function rootTypeName(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return r.iterateNone=!0,this.encapsulate(e,t,r)}},{key:"encapsulate",value:function encapsulate(t,r,n){var i=_async((function(t,r){return _await(Promise.all(r.map((function(e){return e[1].p}))),(function(n){return _await(Promise.all(n.map(_async((function(n){var o=!1,a=[],c=_slicedToArray(r.splice(0,1),1),u=_slicedToArray(c[0],7),s=u[0],f=u[2],l=u[3],p=u[4],y=u[5],v=u[6],b=_encapsulate(s,n,f,l,a,!0,v),d=hasConstructorOf(b,e);return function _invoke(e,t){var r=e();return r&&r.then?r.then(t):t(r)}((function(){if(s&&d)return _await(b.p,(function(e){return p[y]=e,o=!0,i(t,a)}))}),(function(e){return o?e:(s?p[y]=b:t=d?b.p:b,i(t,a))}))})))),(function(){return t}))}))})),s=(n=_objectSpread2(_objectSpread2({sync:!0},this.options),n)).sync,f=this,l={},p=[],y=[],v=[],b=!("cyclic"in n)||n.cyclic,d=n.encapsulateObserver,h=_encapsulate("",t,b,r||{},v);function finish(e){var t=Object.values(l);if(n.iterateNone)return t.length?t[0]:Typeson.getJSONType(e);if(t.length){if(n.returnTypeNames)return _toConsumableArray(new Set(t));e&&isPlainObject(e)&&!c.call(e,"$types")?e.$types=l:e={$:e,$types:{$:l}};}else isObject(e)&&c.call(e,"$types")&&(e={$:e,$types:!0});return !n.returnTypeNames&&e}function _adaptBuiltinStateObjectProperties(e,t,r){Object.assign(e,t);var n=u.map((function(t){var r=e[t];return delete e[t],r}));r(),u.forEach((function(t,r){e[t]=n[r];}));}function _encapsulate(t,r,i,u,s,v,b){var h,g={},m=_typeof(r),O=d?function(n){var o=b||u.type||Typeson.getJSONType(r);d(Object.assign(n||g,{keypath:t,value:r,cyclic:i,stateObj:u,promisesData:s,resolvingTypesonPromise:v,awaitingTypesonPromise:hasConstructorOf(r,e)},{type:o}));}:null;if(["string","boolean","number","undefined"].includes(m))return void 0===r||Number.isNaN(r)||r===Number.NEGATIVE_INFINITY||r===Number.POSITIVE_INFINITY?(h=u.replaced?r:replace(t,r,u,s,!1,v,O))!==r&&(g={replaced:h}):h=r,O&&O(),h;if(null===r)return O&&O(),r;if(i&&!u.iterateIn&&!u.iterateUnsetNumeric&&r&&"object"===_typeof(r)){var _=p.indexOf(r);if(!(_<0))return l[t]="#",O&&O({cyclicKeypath:y[_]}),"#"+y[_];!0===i&&(p.push(r),y.push(t));}var j,S=isPlainObject(r),T=a(r),w=(S||T)&&(!f.plainObjectReplacers.length||u.replaced)||u.iterateIn?r:replace(t,r,u,s,S||T,null,O);if(w!==r?(h=w,g={replaced:w}):""===t&&hasConstructorOf(r,e)?(s.push([t,r,i,u,void 0,void 0,u.type]),h=r):T&&"object"!==u.iterateIn||"array"===u.iterateIn?(j=new Array(r.length),g={clone:j}):(["function","symbol"].includes(_typeof(r))||"toJSON"in r||hasConstructorOf(r,e)||hasConstructorOf(r,Promise)||hasConstructorOf(r,ArrayBuffer))&&!S&&"object"!==u.iterateIn?h=r:(j={},u.addLength&&(j.length=r.length),g={clone:j}),O&&O(),n.iterateNone)return j||h;if(!j)return h;if(u.iterateIn){var A=function _loop(n){var o={ownKeys:c.call(r,n)};_adaptBuiltinStateObjectProperties(u,o,(function(){var o=t+(t?".":"")+escapeKeyPathComponent(n),a=_encapsulate(o,r[n],Boolean(i),u,s,v);hasConstructorOf(a,e)?s.push([o,a,Boolean(i),u,j,n,u.type]):void 0!==a&&(j[n]=a);}));};for(var P in r)A(P);O&&O({endIterateIn:!0,end:!0});}else o(r).forEach((function(n){var o=t+(t?".":"")+escapeKeyPathComponent(n);_adaptBuiltinStateObjectProperties(u,{ownKeys:!0},(function(){var t=_encapsulate(o,r[n],Boolean(i),u,s,v);hasConstructorOf(t,e)?s.push([o,t,Boolean(i),u,j,n,u.type]):void 0!==t&&(j[n]=t);}));})),O&&O({endIterateOwn:!0,end:!0});if(u.iterateUnsetNumeric){for(var I=r.length,C=function _loop2(n){if(!(n in r)){var o=t+(t?".":"")+n;_adaptBuiltinStateObjectProperties(u,{ownKeys:!1},(function(){var t=_encapsulate(o,void 0,Boolean(i),u,s,v);hasConstructorOf(t,e)?s.push([o,t,Boolean(i),u,j,n,u.type]):void 0!==t&&(j[n]=t);}));}},N=0;N<I;N++)C(N);O&&O({endIterateUnsetNumeric:!0,end:!0});}return j}function replace(e,t,r,n,i,o,a){for(var c=i?f.plainObjectReplacers:f.nonplainObjectReplacers,u=c.length;u--;){var p=c[u];if(p.test(t,r)){var y=p.type;if(f.revivers[y]){var v=l[e];l[e]=v?[y].concat(v):y;}return Object.assign(r,{type:y,replaced:!0}),!s&&p.replaceAsync||p.replace?(a&&a({replacing:!0}),_encapsulate(e,p[s||!p.replaceAsync?"replace":"replaceAsync"](t,r),b&&"readonly",r,n,o,y)):(a&&a({typeDetected:!0}),_encapsulate(e,t,b&&"readonly",r,n,o,y))}}return t}return v.length?s&&n.throwOnBadSyncType?function(){throw new TypeError("Sync method requested but async result obtained")}():Promise.resolve(i(h,v)).then(finish):!s&&n.throwOnBadSyncType?function(){throw new TypeError("Async method requested but sync result obtained")}():n.stringification&&s?[finish(h)]:s?finish(h):Promise.resolve(finish(h))}},{key:"encapsulateSync",value:function encapsulateSync(e,t,r){return this.encapsulate(e,t,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},r),{},{sync:!0}))}},{key:"encapsulateAsync",value:function encapsulateAsync(e,t,r){return this.encapsulate(e,t,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},r),{},{sync:!1}))}},{key:"revive",value:function revive(t,r){var n=t&&t.$types;if(!n)return t;if(!0===n)return t.$;var i=(r=_objectSpread2(_objectSpread2({sync:!0},this.options),r)).sync,c=[],u={},s=!0;n.$&&isPlainObject(n.$)&&(t=t.$,n=n.$,s=!1);var l=this;function executeReviver(e,t){var r=_slicedToArray(l.revivers[e]||[],1)[0];if(!r)throw new Error("Unregistered type: "+e);return i&&!("revive"in r)?t:r[i&&r.revive?"revive":!i&&r.reviveAsync?"reviveAsync":"revive"](t,u)}var p=[];function checkUndefined(e){return hasConstructorOf(e,f)?void 0:e}var y,v=function revivePlainObjects(){var r=[];if(Object.entries(n).forEach((function(e){var t=_slicedToArray(e,2),i=t[0],o=t[1];"#"!==o&&[].concat(o).forEach((function(e){_slicedToArray(l.revivers[e]||[null,{}],2)[1].plain&&(r.push({keypath:i,type:e}),delete n[i]);}));})),r.length)return r.sort(nestedPathsFirst).reduce((function reducer(r,n){var i=n.keypath,o=n.type;if(isThenable(r))return r.then((function(e){return reducer(e,{keypath:i,type:o})}));var a=getByKeyPath(t,i);if(hasConstructorOf(a=executeReviver(o,a),e))return a.then((function(e){var r=setAtKeyPath(t,i,e);r===e&&(t=r);}));var c=setAtKeyPath(t,i,a);c===a&&(t=c);}),void 0)}();return hasConstructorOf(v,e)?y=v.then((function(){return t})):(y=function _revive(t,r,i,u,l){if(!s||"$types"!==t){var y=n[t],v=a(r);if(v||isPlainObject(r)){var b=v?new Array(r.length):{};for(o(r).forEach((function(n){var o=_revive(t+(t?".":"")+escapeKeyPathComponent(n),r[n],i||b,b,n),a=function set(e){return hasConstructorOf(e,f)?b[n]=void 0:void 0!==e&&(b[n]=e),e};hasConstructorOf(o,e)?p.push(o.then((function(e){return a(e)}))):a(o);})),r=b;c.length;){var d=_slicedToArray(c[0],4),h=d[0],g=d[1],m=d[2],O=d[3],_=getByKeyPath(h,g);if(void 0===_)break;m[O]=_,c.splice(0,1);}}if(!y)return r;if("#"===y){var j=getByKeyPath(i,r.slice(1));return void 0===j&&c.push([i,r.slice(1),u,l]),j}return [].concat(y).reduce((function reducer(t,r){return hasConstructorOf(t,e)?t.then((function(e){return reducer(e,r)})):executeReviver(r,t)}),r)}}("",t,null),p.length&&(y=e.resolve(y).then((function(t){return e.all([t].concat(p))})).then((function(e){return _slicedToArray(e,1)[0]})))),isThenable(y)?i&&r.throwOnBadSyncType?function(){throw new TypeError("Sync method requested but async result obtained")}():hasConstructorOf(y,e)?y.p.then(checkUndefined):y:!i&&r.throwOnBadSyncType?function(){throw new TypeError("Async method requested but sync result obtained")}():i?checkUndefined(y):Promise.resolve(checkUndefined(y))}},{key:"reviveSync",value:function reviveSync(e,t){return this.revive(e,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},t),{},{sync:!0}))}},{key:"reviveAsync",value:function reviveAsync(e,t){return this.revive(e,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},t),{},{sync:!1}))}},{key:"register",value:function register(e,t){return t=t||{},[].concat(e).forEach((function R(e){var r=this;if(a(e))return e.map((function(e){return R.call(r,e)}));e&&o(e).forEach((function(r){if("#"===r)throw new TypeError("# cannot be used as a type name as it is reserved for cyclic objects");if(Typeson.JSON_TYPES.includes(r))throw new TypeError("Plain JSON object types are reserved as type names");var n=e[r],i=n&&n.testPlainObjects?this.plainObjectReplacers:this.nonplainObjectReplacers,o=i.filter((function(e){return e.type===r}));if(o.length&&(i.splice(i.indexOf(o[0]),1),delete this.revivers[r],delete this.types[r]),"function"==typeof n){var c=n;n={test:function test(e){return e&&e.constructor===c},replace:function replace(e){return _objectSpread2({},e)},revive:function revive(e){return Object.assign(Object.create(c.prototype),e)}};}else if(a(n)){var u=_slicedToArray(n,3);n={test:u[0],replace:u[1],revive:u[2]};}if(n&&n.test){var s={type:r,test:n.test.bind(n)};n.replace&&(s.replace=n.replace.bind(n)),n.replaceAsync&&(s.replaceAsync=n.replaceAsync.bind(n));var f="number"==typeof t.fallback?t.fallback:t.fallback?0:Number.POSITIVE_INFINITY;if(n.testPlainObjects?this.plainObjectReplacers.splice(f,0,s):this.nonplainObjectReplacers.splice(f,0,s),n.revive||n.reviveAsync){var l={};n.revive&&(l.revive=n.revive.bind(n)),n.reviveAsync&&(l.reviveAsync=n.reviveAsync.bind(n)),this.revivers[r]=[l,{plain:n.testPlainObjects}];}this.types[r]=n;}}),this);}),this),this}}]),Typeson}(),f=function Undefined(){_classCallCheck(this,Undefined);};f.__typeson__type__="TypesonUndefined",s.Undefined=f,s.Promise=e,s.isThenable=isThenable,s.toStringTag=toStringTag,s.hasConstructorOf=hasConstructorOf,s.isObject=isObject,s.isPlainObject=isPlainObject,s.isUserObject=function isUserObject(e){if(!e||"Object"!==toStringTag(e))return !1;var t=n(e);return !t||(hasConstructorOf(e,Object)||isUserObject(t))},s.escapeKeyPathComponent=escapeKeyPathComponent,s.unescapeKeyPathComponent=unescapeKeyPathComponent,s.getByKeyPath=getByKeyPath,s.getJSONType=function getJSONType(e){return null===e?"null":Array.isArray(e)?"array":_typeof(e)},s.JSON_TYPES=["null","boolean","number","string","array","object"];for(var l={userObject:{test:function test(e,t){return s.isUserObject(e)},replace:function replace(e){return function _objectSpread2$1(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?ownKeys$1(Object(r),!0).forEach((function(t){_defineProperty$1(e,t,r[t]);})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):ownKeys$1(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t));}));}return e}({},e)},revive:function revive(e){return e}}},p=[{arrayNonindexKeys:{testPlainObjects:!0,test:function test(e,t){return !!Array.isArray(e)&&(Object.keys(e).some((function(e){return String(Number.parseInt(e))!==e}))&&(t.iterateIn="object",t.addLength=!0),!0)},replace:function replace(e,t){return t.iterateUnsetNumeric=!0,e},revive:function revive(e){if(Array.isArray(e))return e;var t=[];return Object.keys(e).forEach((function(r){var n=e[r];t[r]=n;})),t}}},{sparseUndefined:{test:function test(e,t){return void 0===e&&!1===t.ownKeys},replace:function replace(e){return 0},revive:function revive(e){}}}],y={undef:{test:function test(e,t){return void 0===e&&(t.ownKeys||!("ownKeys"in t))},replace:function replace(e){return 0},revive:function revive(e){return new s.Undefined}}},v={StringObject:{test:function test(e){return "String"===s.toStringTag(e)&&"object"===_typeof$1(e)},replace:function replace(e){return String(e)},revive:function revive(e){return new String(e)}},BooleanObject:{test:function test(e){return "Boolean"===s.toStringTag(e)&&"object"===_typeof$1(e)},replace:function replace(e){return Boolean(e)},revive:function revive(e){return new Boolean(e)}},NumberObject:{test:function test(e){return "Number"===s.toStringTag(e)&&"object"===_typeof$1(e)},replace:function replace(e){return Number(e)},revive:function revive(e){return new Number(e)}}},b=[{nan:{test:function test(e){return Number.isNaN(e)},replace:function replace(e){return "NaN"},revive:function revive(e){return Number.NaN}}},{infinity:{test:function test(e){return e===Number.POSITIVE_INFINITY},replace:function replace(e){return "Infinity"},revive:function revive(e){return Number.POSITIVE_INFINITY}}},{negativeInfinity:{test:function test(e){return e===Number.NEGATIVE_INFINITY},replace:function replace(e){return "-Infinity"},revive:function revive(e){return Number.NEGATIVE_INFINITY}}}],d={date:{test:function test(e){return "Date"===s.toStringTag(e)},replace:function replace(e){var t=e.getTime();return Number.isNaN(t)?"NaN":t},revive:function revive(e){return "NaN"===e?new Date(Number.NaN):new Date(e)}}},h={regexp:{test:function test(e){return "RegExp"===s.toStringTag(e)},replace:function replace(e){return {source:e.source,flags:(e.global?"g":"")+(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.sticky?"y":"")+(e.unicode?"u":"")}},revive:function revive(e){var t=e.source,r=e.flags;return new RegExp(t,r)}}},g={map:{test:function test(e){return "Map"===s.toStringTag(e)},replace:function replace(e){return _toConsumableArray$1(e.entries())},revive:function revive(e){return new Map(e)}}},m={set:{test:function test(e){return "Set"===s.toStringTag(e)},replace:function replace(e){return _toConsumableArray$1(e.values())},revive:function revive(e){return new Set(e)}}},O="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",_=new Uint8Array(256),j=0;j<O.length;j++)_[O.charCodeAt(j)]=j;var S=function encode(e,t,r){null==r&&(r=e.byteLength);for(var n=new Uint8Array(e,t||0,r),i=n.length,o="",a=0;a<i;a+=3)o+=O[n[a]>>2],o+=O[(3&n[a])<<4|n[a+1]>>4],o+=O[(15&n[a+1])<<2|n[a+2]>>6],o+=O[63&n[a+2]];return i%3==2?o=o.slice(0,-1)+"=":i%3==1&&(o=o.slice(0,-2)+"=="),o},T=function decode(e){var t,r,n,i,o=e.length,a=.75*e.length,c=0;"="===e[e.length-1]&&(a--,"="===e[e.length-2]&&a--);for(var u=new ArrayBuffer(a),s=new Uint8Array(u),f=0;f<o;f+=4)t=_[e.charCodeAt(f)],r=_[e.charCodeAt(f+1)],n=_[e.charCodeAt(f+2)],i=_[e.charCodeAt(f+3)],s[c++]=t<<2|r>>4,s[c++]=(15&r)<<4|n>>2,s[c++]=(3&n)<<6|63&i;return u},w={arraybuffer:{test:function test(e){return "ArrayBuffer"===s.toStringTag(e)},replace:function replace(e,t){t.buffers||(t.buffers=[]);var r=t.buffers.indexOf(e);return r>-1?{index:r}:(t.buffers.push(e),S(e))},revive:function revive(e,t){if(t.buffers||(t.buffers=[]),"object"===_typeof$1(e))return t.buffers[e.index];var r=T(e);return t.buffers.push(r),r}}},A="undefined"==typeof self?commonjsGlobal:self,P={};["Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array"].forEach((function(e){var t=e,r=A[t];r&&(P[e.toLowerCase()]={test:function test(e){return s.toStringTag(e)===t},replace:function replace(e,t){var r=e.buffer,n=e.byteOffset,i=e.length;t.buffers||(t.buffers=[]);var o=t.buffers.indexOf(r);return o>-1?{index:o,byteOffset:n,length:i}:(t.buffers.push(r),{encoded:S(r),byteOffset:n,length:i})},revive:function revive(e,t){t.buffers||(t.buffers=[]);var n,i=e.byteOffset,o=e.length,a=e.encoded,c=e.index;return "index"in e?n=t.buffers[c]:(n=T(a),t.buffers.push(n)),new r(n,i,o)}});}));var I={dataview:{test:function test(e){return "DataView"===s.toStringTag(e)},replace:function replace(e,t){var r=e.buffer,n=e.byteOffset,i=e.byteLength;t.buffers||(t.buffers=[]);var o=t.buffers.indexOf(r);return o>-1?{index:o,byteOffset:n,byteLength:i}:(t.buffers.push(r),{encoded:S(r),byteOffset:n,byteLength:i})},revive:function revive(e,t){t.buffers||(t.buffers=[]);var r,n=e.byteOffset,i=e.byteLength,o=e.encoded,a=e.index;return "index"in e?r=t.buffers[a]:(r=T(o),t.buffers.push(r)),new DataView(r,n,i)}}},C={IntlCollator:{test:function test(e){return s.hasConstructorOf(e,Intl.Collator)},replace:function replace(e){return e.resolvedOptions()},revive:function revive(e){return new Intl.Collator(e.locale,e)}},IntlDateTimeFormat:{test:function test(e){return s.hasConstructorOf(e,Intl.DateTimeFormat)},replace:function replace(e){return e.resolvedOptions()},revive:function revive(e){return new Intl.DateTimeFormat(e.locale,e)}},IntlNumberFormat:{test:function test(e){return s.hasConstructorOf(e,Intl.NumberFormat)},replace:function replace(e){return e.resolvedOptions()},revive:function revive(e){return new Intl.NumberFormat(e.locale,e)}}};function string2arraybuffer(e){for(var t=new Uint8Array(e.length),r=0;r<e.length;r++)t[r]=e.charCodeAt(r);return t.buffer}var N={file:{test:function test(e){return "File"===s.toStringTag(e)},replace:function replace(e){var t=new XMLHttpRequest;if(t.overrideMimeType("text/plain; charset=x-user-defined"),t.open("GET",URL.createObjectURL(e),!1),t.send(),200!==t.status&&0!==t.status)throw new Error("Bad File access: "+t.status);return {type:e.type,stringContents:t.responseText,name:e.name,lastModified:e.lastModified}},revive:function revive(e){var t=e.name,r=e.type,n=e.stringContents,i=e.lastModified;return new File([string2arraybuffer(n)],t,{type:r,lastModified:i})},replaceAsync:function replaceAsync(e){return new s.Promise((function(t,r){var n=new FileReader;n.addEventListener("load",(function(){t({type:e.type,stringContents:n.result,name:e.name,lastModified:e.lastModified});})),n.addEventListener("error",(function(){r(n.error);})),n.readAsBinaryString(e);}))}}},k={bigint:{test:function test(e){return "bigint"==typeof e},replace:function replace(e){return String(e)},revive:function revive(e){return BigInt(e)}}},E={bigintObject:{test:function test(e){return "object"===_typeof$1(e)&&s.hasConstructorOf(e,BigInt)},replace:function replace(e){return String(e)},revive:function revive(e){return new Object(BigInt(e))}}},B={cryptokey:{test:function test(e){return "CryptoKey"===s.toStringTag(e)&&e.extractable},replaceAsync:function replaceAsync(e){return new s.Promise((function(t,r){crypto.subtle.exportKey("jwk",e).catch((function(e){r(e);})).then((function(r){t({jwk:r,algorithm:e.algorithm,usages:e.usages});}));}))},revive:function revive(e){var t=e.jwk,r=e.algorithm,n=e.usages;return crypto.subtle.importKey("jwk",t,r,!0,n)}}};return [l,y,p,v,b,d,h,{imagedata:{test:function test(e){return "ImageData"===s.toStringTag(e)},replace:function replace(e){return {array:_toConsumableArray$1(e.data),width:e.width,height:e.height}},revive:function revive(e){return new ImageData(new Uint8ClampedArray(e.array),e.width,e.height)}}},{imagebitmap:{test:function test(e){return "ImageBitmap"===s.toStringTag(e)||e&&e.dataset&&"ImageBitmap"===e.dataset.toStringTag},replace:function replace(e){var t=document.createElement("canvas");return t.getContext("2d").drawImage(e,0,0),t.toDataURL()},revive:function revive(e){var t=document.createElement("canvas"),r=t.getContext("2d"),n=document.createElement("img");return n.addEventListener("load",(function(){r.drawImage(n,0,0);})),n.src=e,t},reviveAsync:function reviveAsync(e){var t=document.createElement("canvas"),r=t.getContext("2d"),n=document.createElement("img");return n.addEventListener("load",(function(){r.drawImage(n,0,0);})),n.src=e,createImageBitmap(t)}}},N,{file:N.file,filelist:{test:function test(e){return "FileList"===s.toStringTag(e)},replace:function replace(e){for(var t=[],r=0;r<e.length;r++)t[r]=e.item(r);return t},revive:function revive(e){return new(function(){function FileList(){_classCallCheck$1(this,FileList),this._files=arguments[0],this.length=this._files.length;}return function _createClass$1(e,t,r){return t&&_defineProperties$1(e.prototype,t),r&&_defineProperties$1(e,r),e}(FileList,[{key:"item",value:function item(e){return this._files[e]}},{key:Symbol.toStringTag,get:function get(){return "FileList"}}]),FileList}())(e)}}},{blob:{test:function test(e){return "Blob"===s.toStringTag(e)},replace:function replace(e){var t=new XMLHttpRequest;if(t.overrideMimeType("text/plain; charset=x-user-defined"),t.open("GET",URL.createObjectURL(e),!1),t.send(),200!==t.status&&0!==t.status)throw new Error("Bad Blob access: "+t.status);return {type:e.type,stringContents:t.responseText}},revive:function revive(e){var t=e.type,r=e.stringContents;return new Blob([string2arraybuffer(r)],{type:t})},replaceAsync:function replaceAsync(e){return new s.Promise((function(t,r){var n=new FileReader;n.addEventListener("load",(function(){t({type:e.type,stringContents:n.result});})),n.addEventListener("error",(function(){r(n.error);})),n.readAsBinaryString(e);}))}}}].concat("function"==typeof Map?g:[],"function"==typeof Set?m:[],"function"==typeof ArrayBuffer?w:[],"function"==typeof Uint8Array?P:[],"function"==typeof DataView?I:[],"undefined"!=typeof Intl?C:[],"undefined"!=typeof crypto?B:[],"undefined"!=typeof BigInt?[k,E]:[])})); + + }); + + /* + * base64-arraybuffer + * https://github.com/niklasvh/base64-arraybuffer + * + * Copyright (c) 2017 Brett Zamir, 2012 Niklas von Hertzen + * Licensed under the MIT license. + */ + var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; // Use a lookup table to find the index. + + var lookup = new Uint8Array(256); + + for (var i = 0; i < chars.length; i++) { + lookup[chars.codePointAt(i)] = i; + } + /** + * @param {ArrayBuffer} arraybuffer + * @param {Integer} byteOffset + * @param {Integer} lngth + * @returns {string} + */ + + + var encode = function encode(arraybuffer, byteOffset, lngth) { + if (lngth === null || lngth === undefined) { + lngth = arraybuffer.byteLength; // Needed for Safari + } + + var bytes = new Uint8Array(arraybuffer, byteOffset || 0, // Default needed for Safari + lngth); + var len = bytes.length; + var base64 = ''; + + for (var _i = 0; _i < len; _i += 3) { + base64 += chars[bytes[_i] >> 2]; + base64 += chars[(bytes[_i] & 3) << 4 | bytes[_i + 1] >> 4]; + base64 += chars[(bytes[_i + 1] & 15) << 2 | bytes[_i + 2] >> 6]; + base64 += chars[bytes[_i + 2] & 63]; + } + + if (len % 3 === 2) { + base64 = base64.slice(0, -1) + '='; + } else if (len % 3 === 1) { + base64 = base64.slice(0, -2) + '=='; + } + + return base64; + }; + /** + * @param {string} base64 + * @returns {ArrayBuffer} + */ + + var decode = function decode(base64) { + var len = base64.length; + var bufferLength = base64.length * 0.75; + var p = 0; + var encoded1, encoded2, encoded3, encoded4; + + if (base64[base64.length - 1] === '=') { + bufferLength--; + + if (base64[base64.length - 2] === '=') { + bufferLength--; + } + } + + var arraybuffer = new ArrayBuffer(bufferLength), + bytes = new Uint8Array(arraybuffer); + + for (var _i2 = 0; _i2 < len; _i2 += 4) { + encoded1 = lookup[base64.codePointAt(_i2)]; + encoded2 = lookup[base64.codePointAt(_i2 + 1)]; + encoded3 = lookup[base64.codePointAt(_i2 + 2)]; + encoded4 = lookup[base64.codePointAt(_i2 + 3)]; + bytes[p++] = encoded1 << 2 | encoded2 >> 4; + bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2; + bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63; + } + + return arraybuffer; + }; + + /* eslint-env browser, node */ + var _global = typeof self === 'undefined' ? global : self; + var exportObj = {}; + [ + 'Int8Array', + 'Uint8Array', + 'Uint8ClampedArray', + 'Int16Array', + 'Uint16Array', + 'Int32Array', + 'Uint32Array', + 'Float32Array', + 'Float64Array' + ].forEach(function (typeName) { + var arrType = typeName; + var TypedArray = _global[arrType]; + if (TypedArray) { + exportObj[typeName.toLowerCase() + "2"] = { + test: function (x) { return typeson.toStringTag(x) === arrType; }, + replace: function (_a) { + var buffer = _a.buffer, byteOffset = _a.byteOffset, length = _a.length; + return { + buffer: buffer, + byteOffset: byteOffset, + length: length + }; + }, + revive: function (b64Obj) { + var buffer = b64Obj.buffer, byteOffset = b64Obj.byteOffset, length = b64Obj.length; + return new TypedArray(buffer, byteOffset, length); + } + }; + } + }); + + var arrayBuffer = { + arraybuffer: { + test: function (x) { return typeson.toStringTag(x) === 'ArrayBuffer'; }, + replace: function (b) { + return encode(b, 0, b.byteLength); + }, + revive: function (b64) { + var buffer = decode(b64); + return buffer; + } + } + }; + // See also typed-arrays! + + var TSON = new typeson().register(structuredCloning); + var readBlobsSynchronously = 'FileReaderSync' in self; // true in workers only. + var blobsToAwait = []; + var blobsToAwaitPos = 0; + // Need to patch encapsulateAsync as it does not work as of typeson 5.8.2 + // Also, current version of typespn-registry-1.0.0-alpha.21 does not + // encapsulate/revive Blobs correctly (fails one of the unit tests in + // this library (test 'export-format')) + TSON.register([ + arrayBuffer, + exportObj, { + blob2: { + test: function (x) { return typeson.toStringTag(x) === 'Blob'; }, + replace: function (b) { + if (b.isClosed) { // On MDN, but not in https://w3c.github.io/FileAPI/#dfn-Blob + throw new Error('The Blob is closed'); + } + if (readBlobsSynchronously) { + var data = readBlobSync(b, 'binary'); + var base64 = encode(data, 0, data.byteLength); + return { + type: b.type, + data: base64 + }; + } + else { + blobsToAwait.push(b); // This will also make TSON.mustFinalize() return true. + var result = { + type: b.type, + data: { start: blobsToAwaitPos, end: blobsToAwaitPos + b.size } + }; + blobsToAwaitPos += b.size; + return result; + } + }, + finalize: function (b, ba) { + b.data = encode(ba, 0, ba.byteLength); + }, + revive: function (_a) { + var type = _a.type, data = _a.data; + return new Blob([decode(data)], { type: type }); + } + } + } + ]); + TSON.mustFinalize = function () { return blobsToAwait.length > 0; }; + TSON.finalize = function (items) { return __awaiter(void 0, void 0, void 0, function () { + var allChunks, _i, items_1, item, types, arrayType, keyPath, typeName, typeSpec, b; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, readBlobAsync(new Blob(blobsToAwait), 'binary')]; + case 1: + allChunks = _a.sent(); + if (items) { + for (_i = 0, items_1 = items; _i < items_1.length; _i++) { + item = items_1[_i]; + // Manually go through all "blob" types in the result + // and lookup the data slice they point at. + if (item.$types) { + types = item.$types; + arrayType = types.$; + if (arrayType) + types = types.$; + for (keyPath in types) { + typeName = types[keyPath]; + typeSpec = TSON.types[typeName]; + if (typeSpec && typeSpec.finalize) { + b = Dexie__default["default"].getByKeyPath(item, arrayType ? "$." + keyPath : keyPath); + typeSpec.finalize(b, allChunks.slice(b.start, b.end)); + } + } + } + } + } + // Free up memory + blobsToAwait = []; + return [2 /*return*/]; + } + }); + }); }; + + var DEFAULT_ROWS_PER_CHUNK = 2000; + function exportDB(db, options) { + return __awaiter(this, void 0, void 0, function () { + function exportAll() { + return __awaiter(this, void 0, void 0, function () { + var tablesRowCounts, emptyExportJson, posEndDataArray, firstJsonSlice, filter, _loop_1, _i, tables_1, tableName; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, Promise.all(db.tables.map(function (table) { return table.count(); }))]; + case 1: + tablesRowCounts = _a.sent(); + tablesRowCounts.forEach(function (rowCount, i) { return tables[i].rowCount = rowCount; }); + progress.totalRows = tablesRowCounts.reduce(function (p, c) { return p + c; }); + emptyExportJson = JSON.stringify(emptyExport, undefined, prettyJson ? 2 : undefined); + posEndDataArray = emptyExportJson.lastIndexOf(']'); + firstJsonSlice = emptyExportJson.substring(0, posEndDataArray); + slices.push(firstJsonSlice); + filter = options.filter; + _loop_1 = function (tableName) { + var table, primKey, inbound, LIMIT, emptyTableExport, emptyTableExportJson, posEndRowsArray, lastKey, lastNumRows, mayHaveMoreRows, _loop_2, state_1; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + table = db.table(tableName); + primKey = table.schema.primKey; + inbound = !!primKey.keyPath; + LIMIT = options.numRowsPerChunk || DEFAULT_ROWS_PER_CHUNK; + emptyTableExport = inbound ? { + tableName: table.name, + inbound: true, + rows: [] + } : { + tableName: table.name, + inbound: false, + rows: [] + }; + emptyTableExportJson = JSON.stringify(emptyTableExport, undefined, prettyJson ? 2 : undefined); + if (prettyJson) { + // Increase indentation according to this: + // { + // ... + // data: [ + // ... + // data: [ + // 123456<---- here + // ] + // ] + // } + emptyTableExportJson = emptyTableExportJson.split('\n').join('\n '); + } + posEndRowsArray = emptyTableExportJson.lastIndexOf(']'); + slices.push(emptyTableExportJson.substring(0, posEndRowsArray)); + lastKey = null; + lastNumRows = 0; + mayHaveMoreRows = true; + _loop_2 = function () { + var chunkedCollection, values, filteredValues, tsonValues, json, keys, keyvals, tsonTuples, json; + return __generator(this, function (_c) { + switch (_c.label) { + case 0: + if (progressCallback) { + // Keep ongoing transaction private + Dexie__default["default"].ignoreTransaction(function () { return progressCallback(progress); }); + } + chunkedCollection = lastKey == null ? + table.limit(LIMIT) : + table.where(':id').above(lastKey).limit(LIMIT); + return [4 /*yield*/, chunkedCollection.toArray()]; + case 1: + values = _c.sent(); + if (values.length === 0) + return [2 /*return*/, "break"]; + if (lastKey != null && lastNumRows > 0) { + // Not initial chunk. Must add a comma: + slices.push(","); + if (prettyJson) { + slices.push("\n "); + } + } + mayHaveMoreRows = values.length === LIMIT; + if (!inbound) return [3 /*break*/, 4]; + filteredValues = filter ? + values.filter(function (value) { return filter(tableName, value); }) : + values; + tsonValues = filteredValues.map(function (value) { return TSON.encapsulate(value); }); + if (!TSON.mustFinalize()) return [3 /*break*/, 3]; + return [4 /*yield*/, Dexie__default["default"].waitFor(TSON.finalize(tsonValues))]; + case 2: + _c.sent(); + _c.label = 3; + case 3: + json = JSON.stringify(tsonValues, undefined, prettyJson ? 2 : undefined); + if (prettyJson) + json = json.split('\n').join('\n '); + // By generating a blob here, we give web platform the opportunity to store the contents + // on disk and release RAM. + slices.push(new Blob([json.substring(1, json.length - 1)])); + lastNumRows = filteredValues.length; + lastKey = values.length > 0 ? + Dexie__default["default"].getByKeyPath(values[values.length - 1], primKey.keyPath) : + null; + return [3 /*break*/, 8]; + case 4: return [4 /*yield*/, chunkedCollection.primaryKeys()]; + case 5: + keys = _c.sent(); + keyvals = keys.map(function (key, i) { return [key, values[i]]; }); + if (filter) + keyvals = keyvals.filter(function (_a) { + var key = _a[0], value = _a[1]; + return filter(tableName, value, key); + }); + tsonTuples = keyvals.map(function (tuple) { return TSON.encapsulate(tuple); }); + if (!TSON.mustFinalize()) return [3 /*break*/, 7]; + return [4 /*yield*/, Dexie__default["default"].waitFor(TSON.finalize(tsonTuples))]; + case 6: + _c.sent(); + _c.label = 7; + case 7: + json = JSON.stringify(tsonTuples, undefined, prettyJson ? 2 : undefined); + if (prettyJson) + json = json.split('\n').join('\n '); + // By generating a blob here, we give web platform the opportunity to store the contents + // on disk and release RAM. + slices.push(new Blob([json.substring(1, json.length - 1)])); + lastNumRows = keyvals.length; + lastKey = keys.length > 0 ? + keys[keys.length - 1] : + null; + _c.label = 8; + case 8: + progress.completedRows += values.length; + return [2 /*return*/]; + } + }); + }; + _b.label = 1; + case 1: + if (!mayHaveMoreRows) return [3 /*break*/, 3]; + return [5 /*yield**/, _loop_2()]; + case 2: + state_1 = _b.sent(); + if (state_1 === "break") + return [3 /*break*/, 3]; + return [3 /*break*/, 1]; + case 3: + slices.push(emptyTableExportJson.substr(posEndRowsArray)); // "]}" + progress.completedTables += 1; + if (progress.completedTables < progress.totalTables) { + slices.push(","); + } + return [2 /*return*/]; + } + }); + }; + _i = 0, tables_1 = tables; + _a.label = 2; + case 2: + if (!(_i < tables_1.length)) return [3 /*break*/, 5]; + tableName = tables_1[_i].name; + return [5 /*yield**/, _loop_1(tableName)]; + case 3: + _a.sent(); + _a.label = 4; + case 4: + _i++; + return [3 /*break*/, 2]; + case 5: + slices.push(emptyExportJson.substr(posEndDataArray)); + progress.done = true; + if (progressCallback) { + // Keep ongoing transaction private + Dexie__default["default"].ignoreTransaction(function () { return progressCallback(progress); }); + } + return [2 /*return*/]; + } + }); + }); + } + var slices, tables, prettyJson, emptyExport, progressCallback, progress; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + options = options || {}; + slices = []; + tables = db.tables.map(function (table) { return ({ + name: table.name, + schema: getSchemaString(table), + rowCount: 0 + }); }); + prettyJson = options.prettyJson; + emptyExport = { + formatName: "dexie", + formatVersion: 1, + data: { + databaseName: db.name, + databaseVersion: db.verno, + tables: tables, + data: [] + } + }; + progressCallback = options.progressCallback; + progress = { + done: false, + completedRows: 0, + completedTables: 0, + totalRows: NaN, + totalTables: db.tables.length + }; + _a.label = 1; + case 1: + _a.trys.push([1, , 6, 7]); + if (!options.noTransaction) return [3 /*break*/, 3]; + return [4 /*yield*/, exportAll()]; + case 2: + _a.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, db.transaction('r', db.tables, exportAll)]; + case 4: + _a.sent(); + _a.label = 5; + case 5: return [3 /*break*/, 7]; + case 6: + TSON.finalize(); // Free up mem if error has occurred + return [7 /*endfinally*/]; + case 7: return [2 /*return*/, new Blob(slices, { type: "text/json" })]; + } + }); + }); + } + + var VERSION = 1; + + var fakeStream = {Stream: function(){}}; + + var clarinet_1 = createCommonjsModule(function (module, exports) { + (function (clarinet) { + + // non node-js needs to set clarinet debug on root + var env =(typeof process === 'object' && process.env) + ? process.env + : self; + + clarinet.parser = function (opt) { return new CParser(opt);}; + clarinet.CParser = CParser; + clarinet.CStream = CStream; + clarinet.createStream = createStream; + clarinet.MAX_BUFFER_LENGTH = 10 * 1024 * 1024; + clarinet.DEBUG = (env.CDEBUG==='debug'); + clarinet.INFO = (env.CDEBUG==='debug' || env.CDEBUG==='info'); + clarinet.EVENTS = + [ "value" + , "string" + , "key" + , "openobject" + , "closeobject" + , "openarray" + , "closearray" + , "error" + , "end" + , "ready" + ]; + + var buffers = { + textNode: undefined, + numberNode: "" + } + , streamWraps = clarinet.EVENTS.filter(function (ev) { + return ev !== "error" && ev !== "end"; + }) + , S = 0 + , Stream + ; + + clarinet.STATE = + { BEGIN : S++ + , VALUE : S++ // general stuff + , OPEN_OBJECT : S++ // { + , CLOSE_OBJECT : S++ // } + , OPEN_ARRAY : S++ // [ + , CLOSE_ARRAY : S++ // ] + , TEXT_ESCAPE : S++ // \ stuff + , STRING : S++ // "" + , BACKSLASH : S++ + , END : S++ // No more stack + , OPEN_KEY : S++ // , "a" + , CLOSE_KEY : S++ // : + , TRUE : S++ // r + , TRUE2 : S++ // u + , TRUE3 : S++ // e + , FALSE : S++ // a + , FALSE2 : S++ // l + , FALSE3 : S++ // s + , FALSE4 : S++ // e + , NULL : S++ // u + , NULL2 : S++ // l + , NULL3 : S++ // l + , NUMBER_DECIMAL_POINT : S++ // . + , NUMBER_DIGIT : S++ // [0-9] + }; + + for (var s_ in clarinet.STATE) clarinet.STATE[clarinet.STATE[s_]] = s_; + + // switcharoo + S = clarinet.STATE; + + const Char = { + tab : 0x09, // \t + lineFeed : 0x0A, // \n + carriageReturn : 0x0D, // \r + space : 0x20, // " " + + doubleQuote : 0x22, // " + plus : 0x2B, // + + comma : 0x2C, // , + minus : 0x2D, // - + period : 0x2E, // . + + _0 : 0x30, // 0 + _9 : 0x39, // 9 + + colon : 0x3A, // : + + E : 0x45, // E + + openBracket : 0x5B, // [ + backslash : 0x5C, // \ + closeBracket : 0x5D, // ] + + a : 0x61, // a + b : 0x62, // b + e : 0x65, // e + f : 0x66, // f + l : 0x6C, // l + n : 0x6E, // n + r : 0x72, // r + s : 0x73, // s + t : 0x74, // t + u : 0x75, // u + + openBrace : 0x7B, // { + closeBrace : 0x7D, // } + }; + + if (!Object.create) { + Object.create = function (o) { + function f () { this["__proto__"] = o; } + f.prototype = o; + return new f; + }; + } + + if (!Object.getPrototypeOf) { + Object.getPrototypeOf = function (o) { + return o["__proto__"]; + }; + } + + if (!Object.keys) { + Object.keys = function (o) { + var a = []; + for (var i in o) if (o.hasOwnProperty(i)) a.push(i); + return a; + }; + } + + function checkBufferLength (parser) { + var maxAllowed = Math.max(clarinet.MAX_BUFFER_LENGTH, 10) + , maxActual = 0 + ; + for (var buffer in buffers) { + var len = parser[buffer] === undefined ? 0 : parser[buffer].length; + if (len > maxAllowed) { + switch (buffer) { + case "text": + closeText(parser); + break; + + default: + error(parser, "Max buffer length exceeded: "+ buffer); + } + } + maxActual = Math.max(maxActual, len); + } + parser.bufferCheckPosition = (clarinet.MAX_BUFFER_LENGTH - maxActual) + + parser.position; + } + + function clearBuffers (parser) { + for (var buffer in buffers) { + parser[buffer] = buffers[buffer]; + } + } + + var stringTokenPattern = /[\\"\n]/g; + + function CParser (opt) { + if (!(this instanceof CParser)) return new CParser (opt); + + var parser = this; + clearBuffers(parser); + parser.bufferCheckPosition = clarinet.MAX_BUFFER_LENGTH; + parser.q = parser.c = parser.p = ""; + parser.opt = opt || {}; + parser.closed = parser.closedRoot = parser.sawRoot = false; + parser.tag = parser.error = null; + parser.state = S.BEGIN; + parser.stack = new Array(); + // mostly just for error reporting + parser.position = parser.column = 0; + parser.line = 1; + parser.slashed = false; + parser.unicodeI = 0; + parser.unicodeS = null; + parser.depth = 0; + emit(parser, "onready"); + } + + CParser.prototype = + { end : function () { end(this); } + , write : write + , resume : function () { this.error = null; return this; } + , close : function () { return this.write(null); } + }; + + try { Stream = fakeStream.Stream; } + catch (ex) { Stream = function () {}; } + + function createStream (opt) { return new CStream(opt); } + + function CStream (opt) { + if (!(this instanceof CStream)) return new CStream(opt); + + this._parser = new CParser(opt); + this.writable = true; + this.readable = true; + + //var Buffer = this.Buffer || function Buffer () {}; // if we don't have Buffers, fake it so we can do `var instanceof Buffer` and not throw an error + this.bytes_remaining = 0; // number of bytes remaining in multi byte utf8 char to read after split boundary + this.bytes_in_sequence = 0; // bytes in multi byte utf8 char to read + this.temp_buffs = { "2": new Buffer(2), "3": new Buffer(3), "4": new Buffer(4) }; // for rebuilding chars split before boundary is reached + this.string = ''; + + var me = this; + Stream.apply(me); + + this._parser.onend = function () { me.emit("end"); }; + this._parser.onerror = function (er) { + me.emit("error", er); + me._parser.error = null; + }; + + streamWraps.forEach(function (ev) { + Object.defineProperty(me, "on" + ev, + { get : function () { return me._parser["on" + ev]; } + , set : function (h) { + if (!h) { + me.removeAllListeners(ev); + me._parser["on"+ev] = h; + return h; + } + me.on(ev, h); + } + , enumerable : true + , configurable : false + }); + }); + } + + CStream.prototype = Object.create(Stream.prototype, + { constructor: { value: CStream } }); + + CStream.prototype.write = function (data) { + data = new Buffer(data); + for (var i = 0; i < data.length; i++) { + var n = data[i]; + + // check for carry over of a multi byte char split between data chunks + // & fill temp buffer it with start of this data chunk up to the boundary limit set in the last iteration + if (this.bytes_remaining > 0) { + for (var j = 0; j < this.bytes_remaining; j++) { + this.temp_buffs[this.bytes_in_sequence][this.bytes_in_sequence - this.bytes_remaining + j] = data[j]; + } + this.string = this.temp_buffs[this.bytes_in_sequence].toString(); + this.bytes_in_sequence = this.bytes_remaining = 0; + + // move iterator forward by number of byte read during sequencing + i = i + j - 1; + + // pass data to parser and move forward to parse rest of data + this._parser.write(this.string); + this.emit("data", this.string); + continue; + } + + // if no remainder bytes carried over, parse multi byte (>=128) chars one at a time + if (this.bytes_remaining === 0 && n >= 128) { + if ((n >= 194) && (n <= 223)) this.bytes_in_sequence = 2; + if ((n >= 224) && (n <= 239)) this.bytes_in_sequence = 3; + if ((n >= 240) && (n <= 244)) this.bytes_in_sequence = 4; + if ((this.bytes_in_sequence + i) > data.length) { // if bytes needed to complete char fall outside data length, we have a boundary split + + for (var k = 0; k <= (data.length - 1 - i); k++) { + this.temp_buffs[this.bytes_in_sequence][k] = data[i + k]; // fill temp data of correct size with bytes available in this chunk + } + this.bytes_remaining = (i + this.bytes_in_sequence) - data.length; + + // immediately return as we need another chunk to sequence the character + return true; + } else { + this.string = data.slice(i, (i + this.bytes_in_sequence)).toString(); + i = i + this.bytes_in_sequence - 1; + + this._parser.write(this.string); + this.emit("data", this.string); + continue; + } + } + + // is there a range of characters that are immediately parsable? + for (var p = i; p < data.length; p++) { + if (data[p] >= 128) break; + } + this.string = data.slice(i, p).toString(); + this._parser.write(this.string); + this.emit("data", this.string); + i = p - 1; + + // handle any remaining characters using multibyte logic + continue; + } + }; + + CStream.prototype.end = function (chunk) { + if (chunk && chunk.length) this._parser.write(chunk.toString()); + this._parser.end(); + return true; + }; + + CStream.prototype.on = function (ev, handler) { + var me = this; + if (!me._parser["on"+ev] && streamWraps.indexOf(ev) !== -1) { + me._parser["on"+ev] = function () { + var args = arguments.length === 1 ? [arguments[0]] + : Array.apply(null, arguments); + args.splice(0, 0, ev); + me.emit.apply(me, args); + }; + } + return Stream.prototype.on.call(me, ev, handler); + }; + + CStream.prototype.destroy = function () { + clearBuffers(this._parser); + this.emit("close"); + }; + + function emit(parser, event, data) { + if(clarinet.INFO) console.log('-- emit', event, data); + if (parser[event]) parser[event](data); + } + + function emitNode(parser, event, data) { + closeValue(parser); + emit(parser, event, data); + } + + function closeValue(parser, event) { + parser.textNode = textopts(parser.opt, parser.textNode); + if (parser.textNode !== undefined) { + emit(parser, (event ? event : "onvalue"), parser.textNode); + } + parser.textNode = undefined; + } + + function closeNumber(parser) { + if (parser.numberNode) + emit(parser, "onvalue", parseFloat(parser.numberNode)); + parser.numberNode = ""; + } + + function textopts (opt, text) { + if (text === undefined) { + return text; + } + if (opt.trim) text = text.trim(); + if (opt.normalize) text = text.replace(/\s+/g, " "); + return text; + } + + function error (parser, er) { + closeValue(parser); + er += "\nLine: "+parser.line+ + "\nColumn: "+parser.column+ + "\nChar: "+parser.c; + er = new Error(er); + parser.error = er; + emit(parser, "onerror", er); + return parser; + } + + function end(parser) { + if (parser.state !== S.VALUE || parser.depth !== 0) + error(parser, "Unexpected end"); + + closeValue(parser); + parser.c = ""; + parser.closed = true; + emit(parser, "onend"); + CParser.call(parser, parser.opt); + return parser; + } + + function isWhitespace(c) { + return c === Char.carriageReturn || c === Char.lineFeed || c === Char.space || c === Char.tab; + } + + function write (chunk) { + var parser = this; + if (this.error) throw this.error; + if (parser.closed) return error(parser, + "Cannot write after close. Assign an onready handler."); + if (chunk === null) return end(parser); + var i = 0, c = chunk.charCodeAt(0), p = parser.p; + if (clarinet.DEBUG) console.log('write -> [' + chunk + ']'); + while (c) { + p = c; + parser.c = c = chunk.charCodeAt(i++); + // if chunk doesnt have next, like streaming char by char + // this way we need to check if previous is really previous + // if not we need to reset to what the parser says is the previous + // from buffer + if(p !== c ) parser.p = p; + else p = parser.p; + + if(!c) break; + + if (clarinet.DEBUG) console.log(i,c,clarinet.STATE[parser.state]); + parser.position ++; + if (c === Char.lineFeed) { + parser.line ++; + parser.column = 0; + } else parser.column ++; + switch (parser.state) { + + case S.BEGIN: + if (c === Char.openBrace) parser.state = S.OPEN_OBJECT; + else if (c === Char.openBracket) parser.state = S.OPEN_ARRAY; + else if (!isWhitespace(c)) + error(parser, "Non-whitespace before {[."); + continue; + + case S.OPEN_KEY: + case S.OPEN_OBJECT: + if (isWhitespace(c)) continue; + if(parser.state === S.OPEN_KEY) parser.stack.push(S.CLOSE_KEY); + else { + if(c === Char.closeBrace) { + emit(parser, 'onopenobject'); + this.depth++; + emit(parser, 'oncloseobject'); + this.depth--; + parser.state = parser.stack.pop() || S.VALUE; + continue; + } else parser.stack.push(S.CLOSE_OBJECT); + } + if(c === Char.doubleQuote) parser.state = S.STRING; + else error(parser, "Malformed object key should start with \""); + continue; + + case S.CLOSE_KEY: + case S.CLOSE_OBJECT: + if (isWhitespace(c)) continue; + (parser.state === S.CLOSE_KEY) ? 'key' : 'object'; + if(c === Char.colon) { + if(parser.state === S.CLOSE_OBJECT) { + parser.stack.push(S.CLOSE_OBJECT); + closeValue(parser, 'onopenobject'); + this.depth++; + } else closeValue(parser, 'onkey'); + parser.state = S.VALUE; + } else if (c === Char.closeBrace) { + emitNode(parser, 'oncloseobject'); + this.depth--; + parser.state = parser.stack.pop() || S.VALUE; + } else if(c === Char.comma) { + if(parser.state === S.CLOSE_OBJECT) + parser.stack.push(S.CLOSE_OBJECT); + closeValue(parser); + parser.state = S.OPEN_KEY; + } else error(parser, 'Bad object'); + continue; + + case S.OPEN_ARRAY: // after an array there always a value + case S.VALUE: + if (isWhitespace(c)) continue; + if(parser.state===S.OPEN_ARRAY) { + emit(parser, 'onopenarray'); + this.depth++; + parser.state = S.VALUE; + if(c === Char.closeBracket) { + emit(parser, 'onclosearray'); + this.depth--; + parser.state = parser.stack.pop() || S.VALUE; + continue; + } else { + parser.stack.push(S.CLOSE_ARRAY); + } + } + if(c === Char.doubleQuote) parser.state = S.STRING; + else if(c === Char.openBrace) parser.state = S.OPEN_OBJECT; + else if(c === Char.openBracket) parser.state = S.OPEN_ARRAY; + else if(c === Char.t) parser.state = S.TRUE; + else if(c === Char.f) parser.state = S.FALSE; + else if(c === Char.n) parser.state = S.NULL; + else if(c === Char.minus) { // keep and continue + parser.numberNode += "-"; + } else if(Char._0 <= c && c <= Char._9) { + parser.numberNode += String.fromCharCode(c); + parser.state = S.NUMBER_DIGIT; + } else error(parser, "Bad value"); + continue; + + case S.CLOSE_ARRAY: + if(c === Char.comma) { + parser.stack.push(S.CLOSE_ARRAY); + closeValue(parser, 'onvalue'); + parser.state = S.VALUE; + } else if (c === Char.closeBracket) { + emitNode(parser, 'onclosearray'); + this.depth--; + parser.state = parser.stack.pop() || S.VALUE; + } else if (isWhitespace(c)) + continue; + else error(parser, 'Bad array'); + continue; + + case S.STRING: + if (parser.textNode === undefined) { + parser.textNode = ""; + } + + // thanks thejh, this is an about 50% performance improvement. + var starti = i-1 + , slashed = parser.slashed + , unicodeI = parser.unicodeI + ; + STRING_BIGLOOP: while (true) { + if (clarinet.DEBUG) + console.log(i,c,clarinet.STATE[parser.state] + ,slashed); + // zero means "no unicode active". 1-4 mean "parse some more". end after 4. + while (unicodeI > 0) { + parser.unicodeS += String.fromCharCode(c); + c = chunk.charCodeAt(i++); + parser.position++; + if (unicodeI === 4) { + // TODO this might be slow? well, probably not used too often anyway + parser.textNode += String.fromCharCode(parseInt(parser.unicodeS, 16)); + unicodeI = 0; + starti = i-1; + } else { + unicodeI++; + } + // we can just break here: no stuff we skipped that still has to be sliced out or so + if (!c) break STRING_BIGLOOP; + } + if (c === Char.doubleQuote && !slashed) { + parser.state = parser.stack.pop() || S.VALUE; + parser.textNode += chunk.substring(starti, i-1); + parser.position += i - 1 - starti; + break; + } + if (c === Char.backslash && !slashed) { + slashed = true; + parser.textNode += chunk.substring(starti, i-1); + parser.position += i - 1 - starti; + c = chunk.charCodeAt(i++); + parser.position++; + if (!c) break; + } + if (slashed) { + slashed = false; + if (c === Char.n) { parser.textNode += '\n'; } + else if (c === Char.r) { parser.textNode += '\r'; } + else if (c === Char.t) { parser.textNode += '\t'; } + else if (c === Char.f) { parser.textNode += '\f'; } + else if (c === Char.b) { parser.textNode += '\b'; } + else if (c === Char.u) { + // \uxxxx. meh! + unicodeI = 1; + parser.unicodeS = ''; + } else { + parser.textNode += String.fromCharCode(c); + } + c = chunk.charCodeAt(i++); + parser.position++; + starti = i-1; + if (!c) break; + else continue; + } + + stringTokenPattern.lastIndex = i; + var reResult = stringTokenPattern.exec(chunk); + if (reResult === null) { + i = chunk.length+1; + parser.textNode += chunk.substring(starti, i-1); + parser.position += i - 1 - starti; + break; + } + i = reResult.index+1; + c = chunk.charCodeAt(reResult.index); + if (!c) { + parser.textNode += chunk.substring(starti, i-1); + parser.position += i - 1 - starti; + break; + } + } + parser.slashed = slashed; + parser.unicodeI = unicodeI; + continue; + + case S.TRUE: + if (c === Char.r) parser.state = S.TRUE2; + else error(parser, 'Invalid true started with t'+ c); + continue; + + case S.TRUE2: + if (c === Char.u) parser.state = S.TRUE3; + else error(parser, 'Invalid true started with tr'+ c); + continue; + + case S.TRUE3: + if(c === Char.e) { + emit(parser, "onvalue", true); + parser.state = parser.stack.pop() || S.VALUE; + } else error(parser, 'Invalid true started with tru'+ c); + continue; + + case S.FALSE: + if (c === Char.a) parser.state = S.FALSE2; + else error(parser, 'Invalid false started with f'+ c); + continue; + + case S.FALSE2: + if (c === Char.l) parser.state = S.FALSE3; + else error(parser, 'Invalid false started with fa'+ c); + continue; + + case S.FALSE3: + if (c === Char.s) parser.state = S.FALSE4; + else error(parser, 'Invalid false started with fal'+ c); + continue; + + case S.FALSE4: + if (c === Char.e) { + emit(parser, "onvalue", false); + parser.state = parser.stack.pop() || S.VALUE; + } else error(parser, 'Invalid false started with fals'+ c); + continue; + + case S.NULL: + if (c === Char.u) parser.state = S.NULL2; + else error(parser, 'Invalid null started with n'+ c); + continue; + + case S.NULL2: + if (c === Char.l) parser.state = S.NULL3; + else error(parser, 'Invalid null started with nu'+ c); + continue; + + case S.NULL3: + if(c === Char.l) { + emit(parser, "onvalue", null); + parser.state = parser.stack.pop() || S.VALUE; + } else error(parser, 'Invalid null started with nul'+ c); + continue; + + case S.NUMBER_DECIMAL_POINT: + if(c === Char.period) { + parser.numberNode += "."; + parser.state = S.NUMBER_DIGIT; + } else error(parser, 'Leading zero not followed by .'); + continue; + + case S.NUMBER_DIGIT: + if(Char._0 <= c && c <= Char._9) parser.numberNode += String.fromCharCode(c); + else if (c === Char.period) { + if(parser.numberNode.indexOf('.')!==-1) + error(parser, 'Invalid number has two dots'); + parser.numberNode += "."; + } else if (c === Char.e || c === Char.E) { + if(parser.numberNode.indexOf('e')!==-1 || + parser.numberNode.indexOf('E')!==-1 ) + error(parser, 'Invalid number has two exponential'); + parser.numberNode += "e"; + } else if (c === Char.plus || c === Char.minus) { + if(!(p === Char.e || p === Char.E)) + error(parser, 'Invalid symbol in number'); + parser.numberNode += String.fromCharCode(c); + } else { + closeNumber(parser); + i--; // go back one + parser.state = parser.stack.pop() || S.VALUE; + } + continue; + + default: + error(parser, "Unknown state: " + parser.state); + } + } + if (parser.position >= parser.bufferCheckPosition) + checkBufferLength(parser); + return parser; + } + + })(exports); + }); + + function JsonStream(blob) { + var pos = 0; + var parser = JsonParser(true); + var rv = { + pullAsync: function (numBytes) { + return __awaiter(this, void 0, void 0, function () { + var slize, jsonPart, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + slize = blob.slice(pos, pos + numBytes); + pos += numBytes; + return [4 /*yield*/, readBlobAsync(slize, 'text')]; + case 1: + jsonPart = _a.sent(); + result = parser.write(jsonPart); + rv.result = result || {}; + return [2 /*return*/, result]; + } + }); + }); + }, + pullSync: function (numBytes) { + var slize = blob.slice(pos, pos + numBytes); + pos += numBytes; + var jsonPart = readBlobSync(slize, 'text'); + var result = parser.write(jsonPart); + rv.result = result || {}; + return result; + }, + done: function () { + return parser.done(); + }, + eof: function () { + return pos >= blob.size; + }, + result: {} + }; + return rv; + } + function JsonParser(allowPartial) { + var parser = clarinet_1.parser(); + var level = 0; + var result; + var stack = []; + var obj; + var key; + var done = false; + var array = false; + parser.onopenobject = function (newKey) { + var newObj = {}; + newObj.incomplete = true; + if (!result) + result = newObj; + if (obj) { + stack.push([key, obj, array]); + if (allowPartial) { + if (array) { + obj.push(newObj); + } + else { + obj[key] = newObj; + } + } + } + obj = newObj; + key = newKey; + array = false; + ++level; + }; + parser.onkey = function (newKey) { return key = newKey; }; + parser.onvalue = function (value) { return array ? obj.push(value) : obj[key] = value; }; + parser.oncloseobject = function () { + var _a; + delete obj.incomplete; + key = null; + if (--level === 0) { + done = true; + } + else { + var completedObj = obj; + _a = stack.pop(), key = _a[0], obj = _a[1], array = _a[2]; + if (!allowPartial) { + if (array) { + obj.push(completedObj); + } + else { + obj[key] = completedObj; + } + } + } + }; + parser.onopenarray = function () { + var newObj = []; + newObj.incomplete = true; + if (!result) + result = newObj; + if (obj) { + stack.push([key, obj, array]); + if (allowPartial) { + if (array) { + obj.push(newObj); + } + else { + obj[key] = newObj; + } + } + } + obj = newObj; + array = true; + key = null; + ++level; + }; + parser.onclosearray = function () { + var _a; + delete obj.incomplete; + key = null; + if (--level === 0) { + done = true; + } + else { + var completedObj = obj; + _a = stack.pop(), key = _a[0], obj = _a[1], array = _a[2]; + if (!allowPartial) { + if (array) { + obj.push(completedObj); + } + else { + obj[key] = completedObj; + } + } + } + }; + return { + write: function (jsonPart) { + parser.write(jsonPart); + return result; + }, + done: function () { + return done; + } + }; + } + + var DEFAULT_KILOBYTES_PER_CHUNK = 1024; + function importDB(exportedData, options) { + return __awaiter(this, void 0, void 0, function () { + var CHUNK_SIZE, stream, dbExport, db; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + options = options || {}; // All booleans defaults to false. + CHUNK_SIZE = options.chunkSizeBytes || (DEFAULT_KILOBYTES_PER_CHUNK * 1024); + return [4 /*yield*/, loadUntilWeGotEnoughData(exportedData, CHUNK_SIZE)]; + case 1: + stream = _a.sent(); + dbExport = stream.result.data; + db = new Dexie__default["default"](dbExport.databaseName); + db.version(dbExport.databaseVersion).stores(extractDbSchema(dbExport)); + return [4 /*yield*/, importInto(db, stream, options)]; + case 2: + _a.sent(); + return [2 /*return*/, db]; + } + }); + }); + } + function peakImportFile(exportedData) { + return __awaiter(this, void 0, void 0, function () { + var stream; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + stream = JsonStream(exportedData); + _a.label = 1; + case 1: + if (!!stream.eof()) return [3 /*break*/, 3]; + return [4 /*yield*/, stream.pullAsync(5 * 1024)]; + case 2: + _a.sent(); // 5 k is normally enough for the headers. If not, it will just do another go. + if (stream.result.data && stream.result.data.data) { + // @ts-ignore - TS won't allow us to delete a required property - but we are going to cast it. + delete stream.result.data.data; // Don't return half-baked data array. + return [3 /*break*/, 3]; + } + return [3 /*break*/, 1]; + case 3: return [2 /*return*/, stream.result]; + } + }); + }); + } + function importInto(db, exportedData, options) { + return __awaiter(this, void 0, void 0, function () { + function importAll() { + return __awaiter(this, void 0, void 0, function () { + var _loop_1, _i, _a, tableExport, state_1; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + _loop_1 = function (tableExport) { + var tableName, table, tableSchemaStr, sourceRows, rows, i, obj, filter, filteredRows, _c, keys, values; + return __generator(this, function (_d) { + switch (_d.label) { + case 0: + if (!tableExport.rows) + return [2 /*return*/, "break"]; // Need to pull more! + if (!tableExport.rows.incomplete && tableExport.rows.length === 0) + return [2 /*return*/, "continue"]; + if (progressCallback) { + // Keep ongoing transaction private + Dexie__default["default"].ignoreTransaction(function () { return progressCallback(progress); }); + } + tableName = tableExport.tableName; + table = db.table(tableName); + tableSchemaStr = dbExport.tables.filter(function (t) { return t.name === tableName; })[0].schema; + if (!table) { + if (!options.acceptMissingTables) + throw new Error("Exported table ".concat(tableExport.tableName, " is missing in installed database")); + else + return [2 /*return*/, "continue"]; + } + if (!options.acceptChangedPrimaryKey && + tableSchemaStr.split(',')[0] != table.schema.primKey.src) { + throw new Error("Primary key differs for table ".concat(tableExport.tableName, ". ")); + } + sourceRows = tableExport.rows; + rows = []; + for (i = 0; i < sourceRows.length; i++) { + obj = sourceRows[i]; + if (!obj.incomplete) { + rows.push(TSON.revive(obj)); + } + else { + break; + } + } + filter = options.filter; + filteredRows = filter ? + tableExport.inbound ? + rows.filter(function (value) { return filter(tableName, value); }) : + rows.filter(function (_a) { + var key = _a[0], value = _a[1]; + return filter(tableName, value, key); + }) : + rows; + _c = tableExport.inbound ? + [undefined, filteredRows] : + [filteredRows.map(function (row) { return row[0]; }), rows.map(function (row) { return row[1]; })], keys = _c[0], values = _c[1]; + if (!options.overwriteValues) return [3 /*break*/, 2]; + return [4 /*yield*/, table.bulkPut(values, keys)]; + case 1: + _d.sent(); + return [3 /*break*/, 4]; + case 2: return [4 /*yield*/, table.bulkAdd(values, keys)]; + case 3: + _d.sent(); + _d.label = 4; + case 4: + progress.completedRows += rows.length; + if (!rows.incomplete) { + progress.completedTables += 1; + } + sourceRows.splice(0, rows.length); // Free up RAM, keep existing array instance. + return [2 /*return*/]; + } + }); + }; + _i = 0, _a = dbExport.data; + _b.label = 1; + case 1: + if (!(_i < _a.length)) return [3 /*break*/, 4]; + tableExport = _a[_i]; + return [5 /*yield**/, _loop_1(tableExport)]; + case 2: + state_1 = _b.sent(); + if (state_1 === "break") + return [3 /*break*/, 4]; + _b.label = 3; + case 3: + _i++; + return [3 /*break*/, 1]; + case 4: + // Avoid unnescessary loops in "for (const tableExport of dbExport.data)" + while (dbExport.data.length > 0 && dbExport.data[0].rows && !dbExport.data[0].rows.incomplete) { + // We've already imported all rows from the first table. Delete its occurrence + dbExport.data.splice(0, 1); + } + if (!(!jsonStream.done() && !jsonStream.eof())) return [3 /*break*/, 8]; + if (!readBlobsSynchronously) return [3 /*break*/, 5]; + // If we can pull from blob synchronically, we don't have to + // keep transaction alive using Dexie.waitFor(). + // This will only be possible in workers. + jsonStream.pullSync(CHUNK_SIZE); + return [3 /*break*/, 7]; + case 5: return [4 /*yield*/, Dexie__default["default"].waitFor(jsonStream.pullAsync(CHUNK_SIZE))]; + case 6: + _b.sent(); + _b.label = 7; + case 7: return [3 /*break*/, 9]; + case 8: return [3 /*break*/, 10]; + case 9: + return [3 /*break*/, 0]; + case 10: return [2 /*return*/]; + } + }); + }); + } + var CHUNK_SIZE, jsonStream, dbExportFile, readBlobsSynchronously, dbExport, progressCallback, progress, _i, _a, table; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + options = options || {}; // All booleans defaults to false. + CHUNK_SIZE = options.chunkSizeBytes || (DEFAULT_KILOBYTES_PER_CHUNK * 1024); + return [4 /*yield*/, loadUntilWeGotEnoughData(exportedData, CHUNK_SIZE)]; + case 1: + jsonStream = _b.sent(); + dbExportFile = jsonStream.result; + readBlobsSynchronously = 'FileReaderSync' in self; + dbExport = dbExportFile.data; + if (!options.acceptNameDiff && db.name !== dbExport.databaseName) + throw new Error("Name differs. Current database name is ".concat(db.name, " but export is ").concat(dbExport.databaseName)); + if (!options.acceptVersionDiff && db.verno !== dbExport.databaseVersion) { + // Possible feature: Call upgraders in some isolated way if this happens... ? + throw new Error("Database version differs. Current database is in version ".concat(db.verno, " but export is ").concat(dbExport.databaseVersion)); + } + progressCallback = options.progressCallback; + progress = { + done: false, + completedRows: 0, + completedTables: 0, + totalRows: dbExport.tables.reduce(function (p, c) { return p + c.rowCount; }, 0), + totalTables: dbExport.tables.length + }; + if (progressCallback) { + // Keep ongoing transaction private + Dexie__default["default"].ignoreTransaction(function () { return progressCallback(progress); }); + } + if (!options.clearTablesBeforeImport) return [3 /*break*/, 5]; + _i = 0, _a = db.tables; + _b.label = 2; + case 2: + if (!(_i < _a.length)) return [3 /*break*/, 5]; + table = _a[_i]; + return [4 /*yield*/, table.clear()]; + case 3: + _b.sent(); + _b.label = 4; + case 4: + _i++; + return [3 /*break*/, 2]; + case 5: + if (!options.noTransaction) return [3 /*break*/, 7]; + return [4 /*yield*/, importAll()]; + case 6: + _b.sent(); + return [3 /*break*/, 9]; + case 7: return [4 /*yield*/, db.transaction('rw', db.tables, importAll)]; + case 8: + _b.sent(); + _b.label = 9; + case 9: + progress.done = true; + if (progressCallback) { + // Keep ongoing transaction private + Dexie__default["default"].ignoreTransaction(function () { return progressCallback(progress); }); + } + return [2 /*return*/]; + } + }); + }); + } + function loadUntilWeGotEnoughData(exportedData, CHUNK_SIZE) { + return __awaiter(this, void 0, void 0, function () { + var stream, dbExportFile; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + stream = ('slice' in exportedData ? + JsonStream(exportedData) : + exportedData); + _a.label = 1; + case 1: + if (!!stream.eof()) return [3 /*break*/, 3]; + return [4 /*yield*/, stream.pullAsync(CHUNK_SIZE)]; + case 2: + _a.sent(); + if (stream.result.data && stream.result.data.data) + return [3 /*break*/, 3]; + return [3 /*break*/, 1]; + case 3: + dbExportFile = stream.result; + if (!dbExportFile || dbExportFile.formatName != "dexie") + throw new Error("Given file is not a dexie export"); + if (dbExportFile.formatVersion > VERSION) { + throw new Error("Format version ".concat(dbExportFile.formatVersion, " not supported")); + } + if (!dbExportFile.data) { + throw new Error("No data in export file"); + } + if (!dbExportFile.data.databaseName) { + throw new Error("Missing databaseName in export file"); + } + if (!dbExportFile.data.databaseVersion) { + throw new Error("Missing databaseVersion in export file"); + } + if (!dbExportFile.data.tables) { + throw new Error("Missing tables in export file"); + } + return [2 /*return*/, stream]; + } + }); + }); + } + + // + // Extend Dexie interface (runtime wise) + // + Dexie__default["default"].prototype.export = function (options) { + return exportDB(this, options); + }; + Dexie__default["default"].prototype.import = function (blob, options) { + return importInto(this, blob, options); + }; + Dexie__default["default"].import = function (blob, options) { return importDB(blob, options); }; + var dexieExportImport = (function () { + throw new Error("This addon extends Dexie.prototype globally and does not have be included in Dexie constructor's addons options."); + }); + + exports["default"] = dexieExportImport; + exports.exportDB = exportDB; + exports.importDB = importDB; + exports.importInto = importInto; + exports.peakImportFile = peakImportFile; + + Object.defineProperty(exports, '__esModule', { value: true }); + +})); +//# sourceMappingURL=dexie-export-import.js.map diff --git a/ext/lib/dexie-export-import.min.js.map b/ext/lib/dexie-export-import.js.map index f3684f32..f3684f32 100644 --- a/ext/lib/dexie-export-import.min.js.map +++ b/ext/lib/dexie-export-import.js.map diff --git a/ext/lib/dexie-export-import.min.js b/ext/lib/dexie-export-import.min.js deleted file mode 100644 index 684f702d..00000000 --- a/ext/lib/dexie-export-import.min.js +++ /dev/null @@ -1,271 +0,0 @@ -(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?factory(exports,require('dexie')):typeof define==='function'&&define.amd?define(['exports','dexie'],factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,factory(global.DexieExportImport={},global.Dexie))})(this,(function(exports,Dexie){'use strict';function _interopDefaultLegacy(e){return e&&typeof e==='object'&&'default' in e?e:{'default':e}} - var Dexie__default=_interopDefaultLegacy(Dexie);/*! ***************************************************************************** - Copyright (c) Microsoft Corporation. - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. - ***************************************************************************** */ - function __awaiter(thisArg,_arguments,P,generator){function adopt(value){return value instanceof P?value:new P(function(resolve){resolve(value)})} - return new(P||(P=Promise))(function(resolve,reject){function fulfilled(value){try{step(generator.next(value))}catch(e){reject(e)}} - function rejected(value){try{step(generator["throw"](value))}catch(e){reject(e)}} - function step(result){result.done?resolve(result.value):adopt(result.value).then(fulfilled,rejected)} - step((generator=generator.apply(thisArg,_arguments||[])).next())})} - function __generator(thisArg,body){var _={label:0,sent:function(){if(t[0]&1)throw t[1];return t[1]},trys:[],ops:[]},f,y,t,g;return g={next:verb(0),"throw":verb(1),"return":verb(2)},typeof Symbol==="function"&&(g[Symbol.iterator]=function(){return this}),g;function verb(n){return function(v){return step([n,v])}} - function step(op){if(f)throw new TypeError("Generator is already executing.");while(_)try{if(f=1,y&&(t=op[0]&2?y["return"]:op[0]?y["throw"]||((t=y["return"])&&t.call(y),0):y.next)&&!(t=t.call(y,op[1])).done)return t;if(y=0,t)op=[op[0]&2,t.value];switch(op[0]){case 0:case 1:t=op;break;case 4:_.label++;return{value:op[1],done:!1};case 5:_.label++;y=op[1];op=[0];continue;case 7:op=_.ops.pop();_.trys.pop();continue;default:if(!(t=_.trys,t=t.length>0&&t[t.length-1])&&(op[0]===6||op[0]===2)){_=0;continue} - if(op[0]===3&&(!t||(op[1]>t[0]&&op[1]<t[3]))){_.label=op[1];break} - if(op[0]===6&&_.label<t[1]){_.label=t[1];t=op;break} - if(t&&_.label<t[2]){_.label=t[2];_.ops.push(op);break} - if(t[2])_.ops.pop();_.trys.pop();continue} - op=body.call(thisArg,_)}catch(e){op=[6,e];y=0}finally{f=t=0} - if(op[0]&5)throw op[1];return{value:op[0]?op[1]:void 0,done:!0}}} - function getSchemaString(table){var primKeyAndIndexes=[table.schema.primKey].concat(table.schema.indexes);return primKeyAndIndexes.map(function(index){return index.src}).join(',')} - function extractDbSchema(exportedDb){var schema={};for(var _i=0,_a=exportedDb.tables;_i<_a.length;_i++){var table=_a[_i];schema[table.name]=table.schema} - return schema} - function readBlobAsync(blob,type){return new Promise(function(resolve,reject){var reader=new FileReader();reader.onabort=function(ev){return reject(new Error("file read aborted"))};reader.onerror=function(ev){return reject(ev.target.error)};reader.onload=function(ev){return resolve(ev.target.result)};if(type==='binary') - reader.readAsArrayBuffer(blob);else reader.readAsText(blob)})} - function readBlobSync(blob,type){if(typeof FileReaderSync==='undefined'){throw new Error('FileReaderSync missing. Reading blobs synchronously requires code to run from within a web worker. Use TSON.encapsulateAsync() to do it from the main thread.')} - var reader=new FileReaderSync();var data=type==='binary'?reader.readAsArrayBuffer(blob):reader.readAsText(blob);return data} - var commonjsGlobal=typeof globalThis!=='undefined'?globalThis:typeof window!=='undefined'?window:typeof global!=='undefined'?global:typeof self!=='undefined'?self:{};function createCommonjsModule(fn,module){return module={exports:{}},fn(module,module.exports),module.exports} - var typeson=createCommonjsModule(function(module,exports){(function(global,factory){module.exports=factory()}(commonjsGlobal,(function(){function _typeof(obj){if(typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"){_typeof=function(obj){return typeof obj}}else{_typeof=function(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj}} - return _typeof(obj)} - function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return} - if(info.done){resolve(value)}else{Promise.resolve(value).then(_next,_throw)}} - function _asyncToGenerator(fn){return function(){var self=this,args=arguments;return new Promise(function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value)} - function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err)} - _next(undefined)})}} - function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}} - function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||!1;descriptor.configurable=!0;if("value" in descriptor)descriptor.writable=!0;Object.defineProperty(target,descriptor.key,descriptor)}} - function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);return Constructor} - function _defineProperty(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0})}else{obj[key]=value} - return obj} - function ownKeys(object,enumerableOnly){var keys=Object.keys(object);if(Object.getOwnPropertySymbols){var symbols=Object.getOwnPropertySymbols(object);if(enumerableOnly)symbols=symbols.filter(function(sym){return Object.getOwnPropertyDescriptor(object,sym).enumerable});keys.push.apply(keys,symbols)} - return keys} - function _objectSpread2(target){for(var i=1;i<arguments.length;i++){var source=arguments[i]!=null?arguments[i]:{};if(i%2){ownKeys(Object(source),!0).forEach(function(key){_defineProperty(target,key,source[key])})}else if(Object.getOwnPropertyDescriptors){Object.defineProperties(target,Object.getOwnPropertyDescriptors(source))}else{ownKeys(Object(source)).forEach(function(key){Object.defineProperty(target,key,Object.getOwnPropertyDescriptor(source,key))})}} - return target} - function _slicedToArray(arr,i){return _arrayWithHoles(arr)||_iterableToArrayLimit(arr,i)||_nonIterableRest()} - function _toConsumableArray(arr){return _arrayWithoutHoles(arr)||_iterableToArray(arr)||_nonIterableSpread()} - function _arrayWithoutHoles(arr){if(Array.isArray(arr)){for(var i=0,arr2=new Array(arr.length);i<arr.length;i++)arr2[i]=arr[i];return arr2}} - function _arrayWithHoles(arr){if(Array.isArray(arr))return arr} - function _iterableToArray(iter){if(Symbol.iterator in Object(iter)||Object.prototype.toString.call(iter)==="[object Arguments]")return Array.from(iter)} - function _iterableToArrayLimit(arr,i){if(!(Symbol.iterator in Object(arr)||Object.prototype.toString.call(arr)==="[object Arguments]")){return} - var _arr=[];var _n=!0;var _d=!1;var _e=undefined;try{for(var _i=arr[Symbol.iterator](),_s;!(_n=(_s=_i.next()).done);_n=!0){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=!0;_e=err}finally{try{if(!_n&&_i["return"]!=null)_i["return"]()}finally{if(_d)throw _e}} - return _arr} - function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance")} - function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance")} - var TypesonPromise=function TypesonPromise(f){_classCallCheck(this,TypesonPromise);this.p=new Promise(f)};TypesonPromise.__typeson__type__='TypesonPromise';if(typeof Symbol!=='undefined'){TypesonPromise.prototype[Symbol.toStringTag]='TypesonPromise'} - TypesonPromise.prototype.then=function(onFulfilled,onRejected){var _this=this;return new TypesonPromise(function(typesonResolve,typesonReject){_this.p.then(function(res){typesonResolve(onFulfilled?onFulfilled(res):res)})["catch"](function(res){return onRejected?onRejected(res):Promise.reject(res)}).then(typesonResolve,typesonReject)})};TypesonPromise.prototype["catch"]=function(onRejected){return this.then(null,onRejected)};TypesonPromise.resolve=function(v){return new TypesonPromise(function(typesonResolve){typesonResolve(v)})};TypesonPromise.reject=function(v){return new TypesonPromise(function(typesonResolve,typesonReject){typesonReject(v)})};['all','race'].forEach(function(meth){TypesonPromise[meth]=function(promArr){return new TypesonPromise(function(typesonResolve,typesonReject){Promise[meth](promArr.map(function(prom){return prom&&prom.constructor&&prom.constructor.__typeson__type__==='TypesonPromise'?prom.p:prom})).then(typesonResolve,typesonReject)})}});var _ref={},toStr=_ref.toString,hasOwn={}.hasOwnProperty,getProto=Object.getPrototypeOf,fnToString=hasOwn.toString;function isThenable(v,catchCheck){return isObject(v)&&typeof v.then==='function'&&(!catchCheck||typeof v["catch"]==='function')} - function toStringTag(val){return toStr.call(val).slice(8,-1)} - function hasConstructorOf(a,b){if(!a||_typeof(a)!=='object'){return!1} - var proto=getProto(a);if(!proto){return b===null} - var Ctor=hasOwn.call(proto,'constructor')&&proto.constructor;if(typeof Ctor!=='function'){return b===null} - if(b===Ctor){return!0} - if(b!==null&&fnToString.call(Ctor)===fnToString.call(b)){return!0} - if(typeof b==='function'&&typeof Ctor.__typeson__type__==='string'&&Ctor.__typeson__type__===b.__typeson__type__){return!0} - return!1} - function isPlainObject(val){if(!val||toStringTag(val)!=='Object'){return!1} - var proto=getProto(val);if(!proto){return!0} - return hasConstructorOf(val,Object)} - function isUserObject(val){if(!val||toStringTag(val)!=='Object'){return!1} - var proto=getProto(val);if(!proto){return!0} - return hasConstructorOf(val,Object)||isUserObject(proto)} - function isObject(v){return v&&_typeof(v)==='object'} - function escapeKeyPathComponent(keyPathComponent){return keyPathComponent.replace(/~/g,'~0').replace(/\./g,'~1')} - function unescapeKeyPathComponent(keyPathComponent){return keyPathComponent.replace(/~1/g,'.').replace(/~0/g,'~')} - function getByKeyPath(obj,keyPath){if(keyPath===''){return obj} - var period=keyPath.indexOf('.');if(period>-1){var innerObj=obj[unescapeKeyPathComponent(keyPath.slice(0,period))];return innerObj===undefined?undefined:getByKeyPath(innerObj,keyPath.slice(period+1))} - return obj[unescapeKeyPathComponent(keyPath)]} - function setAtKeyPath(obj,keyPath,value){if(keyPath===''){return value} - var period=keyPath.indexOf('.');if(period>-1){var innerObj=obj[unescapeKeyPathComponent(keyPath.slice(0,period))];return setAtKeyPath(innerObj,keyPath.slice(period+1),value)} - obj[unescapeKeyPathComponent(keyPath)]=value;return obj} - function getJSONType(value){return value===null?'null':Array.isArray(value)?'array':_typeof(value)} - var keys=Object.keys,isArray=Array.isArray,hasOwn$1={}.hasOwnProperty,internalStateObjPropsToIgnore=['type','replaced','iterateIn','iterateUnsetNumeric'];function nestedPathsFirst(a,b){if(a.keypath===''){return-1} - var as=a.keypath.match(/\./g)||0;var bs=b.keypath.match(/\./g)||0;if(as){as=as.length} - if(bs){bs=bs.length} - return as>bs?-1:as<bs?1:a.keypath<b.keypath?-1:a.keypath>b.keypath} - var Typeson=function(){function Typeson(options){_classCallCheck(this,Typeson);this.options=options;this.plainObjectReplacers=[];this.nonplainObjectReplacers=[];this.revivers={};this.types={}} - _createClass(Typeson,[{key:"stringify",value:function stringify(obj,replacer,space,opts){opts=_objectSpread2({},this.options,{},opts,{stringification:!0});var encapsulated=this.encapsulate(obj,null,opts);if(isArray(encapsulated)){return JSON.stringify(encapsulated[0],replacer,space)} - return encapsulated.then(function(res){return JSON.stringify(res,replacer,space)})}},{key:"stringifySync",value:function stringifySync(obj,replacer,space,opts){return this.stringify(obj,replacer,space,_objectSpread2({throwOnBadSyncType:!0},opts,{sync:!0}))}},{key:"stringifyAsync",value:function stringifyAsync(obj,replacer,space,opts){return this.stringify(obj,replacer,space,_objectSpread2({throwOnBadSyncType:!0},opts,{sync:!1}))}},{key:"parse",value:function parse(text,reviver,opts){opts=_objectSpread2({},this.options,{},opts,{parse:!0});return this.revive(JSON.parse(text,reviver),opts)}},{key:"parseSync",value:function parseSync(text,reviver,opts){return this.parse(text,reviver,_objectSpread2({throwOnBadSyncType:!0},opts,{sync:!0}))}},{key:"parseAsync",value:function parseAsync(text,reviver,opts){return this.parse(text,reviver,_objectSpread2({throwOnBadSyncType:!0},opts,{sync:!1}))}},{key:"specialTypeNames",value:function specialTypeNames(obj,stateObj){var opts=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};opts.returnTypeNames=!0;return this.encapsulate(obj,stateObj,opts)}},{key:"rootTypeName",value:function rootTypeName(obj,stateObj){var opts=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};opts.iterateNone=!0;return this.encapsulate(obj,stateObj,opts)}},{key:"encapsulate",value:function encapsulate(obj,stateObj,opts){opts=_objectSpread2({sync:!0},this.options,{},opts);var _opts=opts,sync=_opts.sync;var that=this,types={},refObjs=[],refKeys=[],promisesDataRoot=[];var cyclic='cyclic' in opts?opts.cyclic:!0;var _opts2=opts,encapsulateObserver=_opts2.encapsulateObserver;var ret=_encapsulate('',obj,cyclic,stateObj||{},promisesDataRoot);function finish(ret){var typeNames=Object.values(types);if(opts.iterateNone){if(typeNames.length){return typeNames[0]} - return Typeson.getJSONType(ret)} - if(typeNames.length){if(opts.returnTypeNames){return _toConsumableArray(new Set(typeNames))} - if(!ret||!isPlainObject(ret)||hasOwn$1.call(ret,'$types')){ret={$:ret,$types:{$:types}}}else{ret.$types=types}}else if(isObject(ret)&&hasOwn$1.call(ret,'$types')){ret={$:ret,$types:!0}} - if(opts.returnTypeNames){return!1} - return ret} - function checkPromises(_x,_x2){return _checkPromises.apply(this,arguments)} - function _checkPromises(){_checkPromises=_asyncToGenerator(regeneratorRuntime.mark(function _callee2(ret,promisesData){var promResults;return regeneratorRuntime.wrap(function _callee2$(_context2){while(1){switch(_context2.prev=_context2.next){case 0:_context2.next=2;return Promise.all(promisesData.map(function(pd){return pd[1].p}));case 2:promResults=_context2.sent;_context2.next=5;return Promise.all(promResults.map(function(){var _ref=_asyncToGenerator(regeneratorRuntime.mark(function _callee(promResult){var newPromisesData,_promisesData$splice,_promisesData$splice2,prData,_prData,keyPath,cyclic,stateObj,parentObj,key,detectedType,encaps,isTypesonPromise,encaps2;return regeneratorRuntime.wrap(function _callee$(_context){while(1){switch(_context.prev=_context.next){case 0:newPromisesData=[];_promisesData$splice=promisesData.splice(0,1),_promisesData$splice2=_slicedToArray(_promisesData$splice,1),prData=_promisesData$splice2[0];_prData=_slicedToArray(prData,7),keyPath=_prData[0],cyclic=_prData[2],stateObj=_prData[3],parentObj=_prData[4],key=_prData[5],detectedType=_prData[6];encaps=_encapsulate(keyPath,promResult,cyclic,stateObj,newPromisesData,!0,detectedType);isTypesonPromise=hasConstructorOf(encaps,TypesonPromise);if(!(keyPath&&isTypesonPromise)){_context.next=11;break} - _context.next=8;return encaps.p;case 8:encaps2=_context.sent;parentObj[key]=encaps2;return _context.abrupt("return",checkPromises(ret,newPromisesData));case 11:if(keyPath){parentObj[key]=encaps}else if(isTypesonPromise){ret=encaps.p}else{ret=encaps} - return _context.abrupt("return",checkPromises(ret,newPromisesData));case 13:case "end":return _context.stop()}}},_callee)}));return function(_x3){return _ref.apply(this,arguments)}}()));case 5:return _context2.abrupt("return",ret);case 6:case "end":return _context2.stop()}}},_callee2)}));return _checkPromises.apply(this,arguments)} - function _adaptBuiltinStateObjectProperties(stateObj,ownKeysObj,cb){Object.assign(stateObj,ownKeysObj);var vals=internalStateObjPropsToIgnore.map(function(prop){var tmp=stateObj[prop];delete stateObj[prop];return tmp});cb();internalStateObjPropsToIgnore.forEach(function(prop,i){stateObj[prop]=vals[i]})} - function _encapsulate(keypath,value,cyclic,stateObj,promisesData,resolvingTypesonPromise,detectedType){var ret;var observerData={};var $typeof=_typeof(value);var runObserver=encapsulateObserver?function(obj){var type=detectedType||stateObj.type||Typeson.getJSONType(value);encapsulateObserver(Object.assign(obj||observerData,{keypath:keypath,value:value,cyclic:cyclic,stateObj:stateObj,promisesData:promisesData,resolvingTypesonPromise:resolvingTypesonPromise,awaitingTypesonPromise:hasConstructorOf(value,TypesonPromise)},{type:type}))}:null;if(['string','boolean','number','undefined'].includes($typeof)){if(value===undefined||$typeof==='number'&&(isNaN(value)||value===-Infinity||value===Infinity)){if(stateObj.replaced){ret=value}else{ret=replace(keypath,value,stateObj,promisesData,!1,resolvingTypesonPromise,runObserver)} - if(ret!==value){observerData={replaced:ret}}}else{ret=value} - if(runObserver){runObserver()} - return ret} - if(value===null){if(runObserver){runObserver()} - return value} - if(cyclic&&!stateObj.iterateIn&&!stateObj.iterateUnsetNumeric&&value&&_typeof(value)==='object'){var refIndex=refObjs.indexOf(value);if(refIndex<0){if(cyclic===!0){refObjs.push(value);refKeys.push(keypath)}}else{types[keypath]='#';if(runObserver){runObserver({cyclicKeypath:refKeys[refIndex]})} - return'#'+refKeys[refIndex]}} - var isPlainObj=isPlainObject(value);var isArr=isArray(value);var replaced=(isPlainObj||isArr)&&(!that.plainObjectReplacers.length||stateObj.replaced)||stateObj.iterateIn?value:replace(keypath,value,stateObj,promisesData,isPlainObj||isArr,null,runObserver);var clone;if(replaced!==value){ret=replaced;observerData={replaced:replaced}}else{if(keypath===''&&hasConstructorOf(value,TypesonPromise)){promisesData.push([keypath,value,cyclic,stateObj,undefined,undefined,stateObj.type]);ret=value}else if(isArr&&stateObj.iterateIn!=='object'||stateObj.iterateIn==='array'){clone=new Array(value.length);observerData={clone:clone}}else if(!['function','symbol'].includes(_typeof(value))&&!('toJSON' in value)&&!hasConstructorOf(value,TypesonPromise)&&!hasConstructorOf(value,Promise)&&!hasConstructorOf(value,ArrayBuffer)||isPlainObj||stateObj.iterateIn==='object'){clone={};if(stateObj.addLength){clone.length=value.length} - observerData={clone:clone}}else{ret=value}} - if(runObserver){runObserver()} - if(opts.iterateNone){return clone||ret} - if(!clone){return ret} - if(stateObj.iterateIn){var _loop=function _loop(key){var ownKeysObj={ownKeys:hasOwn$1.call(value,key)};_adaptBuiltinStateObjectProperties(stateObj,ownKeysObj,function(){var kp=keypath+(keypath?'.':'')+escapeKeyPathComponent(key);var val=_encapsulate(kp,value[key],Boolean(cyclic),stateObj,promisesData,resolvingTypesonPromise);if(hasConstructorOf(val,TypesonPromise)){promisesData.push([kp,val,Boolean(cyclic),stateObj,clone,key,stateObj.type])}else if(val!==undefined){clone[key]=val}})};for(var key in value){_loop(key)} - if(runObserver){runObserver({endIterateIn:!0,end:!0})}}else{keys(value).forEach(function(key){var kp=keypath+(keypath?'.':'')+escapeKeyPathComponent(key);var ownKeysObj={ownKeys:!0};_adaptBuiltinStateObjectProperties(stateObj,ownKeysObj,function(){var val=_encapsulate(kp,value[key],Boolean(cyclic),stateObj,promisesData,resolvingTypesonPromise);if(hasConstructorOf(val,TypesonPromise)){promisesData.push([kp,val,Boolean(cyclic),stateObj,clone,key,stateObj.type])}else if(val!==undefined){clone[key]=val}})});if(runObserver){runObserver({endIterateOwn:!0,end:!0})}} - if(stateObj.iterateUnsetNumeric){var vl=value.length;var _loop2=function _loop2(i){if(!(i in value)){var kp=keypath+(keypath?'.':'')+i;var ownKeysObj={ownKeys:!1};_adaptBuiltinStateObjectProperties(stateObj,ownKeysObj,function(){var val=_encapsulate(kp,undefined,Boolean(cyclic),stateObj,promisesData,resolvingTypesonPromise);if(hasConstructorOf(val,TypesonPromise)){promisesData.push([kp,val,Boolean(cyclic),stateObj,clone,i,stateObj.type])}else if(val!==undefined){clone[i]=val}})}};for(var i=0;i<vl;i++){_loop2(i)} - if(runObserver){runObserver({endIterateUnsetNumeric:!0,end:!0})}} - return clone} - function replace(keypath,value,stateObj,promisesData,plainObject,resolvingTypesonPromise,runObserver){var replacers=plainObject?that.plainObjectReplacers:that.nonplainObjectReplacers;var i=replacers.length;while(i--){var replacer=replacers[i];if(replacer.test(value,stateObj)){var type=replacer.type;if(that.revivers[type]){var existing=types[keypath];types[keypath]=existing?[type].concat(existing):type} - Object.assign(stateObj,{type:type,replaced:!0});if((sync||!replacer.replaceAsync)&&!replacer.replace){if(runObserver){runObserver({typeDetected:!0})} - return _encapsulate(keypath,value,cyclic&&'readonly',stateObj,promisesData,resolvingTypesonPromise,type)} - if(runObserver){runObserver({replacing:!0})} - var replaceMethod=sync||!replacer.replaceAsync?'replace':'replaceAsync';return _encapsulate(keypath,replacer[replaceMethod](value,stateObj),cyclic&&'readonly',stateObj,promisesData,resolvingTypesonPromise,type)}} - return value} - return promisesDataRoot.length?sync&&opts.throwOnBadSyncType?function(){throw new TypeError('Sync method requested but async result obtained')}():Promise.resolve(checkPromises(ret,promisesDataRoot)).then(finish):!sync&&opts.throwOnBadSyncType?function(){throw new TypeError('Async method requested but sync result obtained')}():opts.stringification&&sync?[finish(ret)]:sync?finish(ret):Promise.resolve(finish(ret))}},{key:"encapsulateSync",value:function encapsulateSync(obj,stateObj,opts){return this.encapsulate(obj,stateObj,_objectSpread2({throwOnBadSyncType:!0},opts,{sync:!0}))}},{key:"encapsulateAsync",value:function encapsulateAsync(obj,stateObj,opts){return this.encapsulate(obj,stateObj,_objectSpread2({throwOnBadSyncType:!0},opts,{sync:!1}))}},{key:"revive",value:function revive(obj,opts){var types=obj&&obj.$types;if(!types){return obj} - if(types===!0){return obj.$} - opts=_objectSpread2({sync:!0},this.options,{},opts);var _opts3=opts,sync=_opts3.sync;var keyPathResolutions=[];var stateObj={};var ignore$Types=!0;if(types.$&&isPlainObject(types.$)){obj=obj.$;types=types.$;ignore$Types=!1} - var that=this;function executeReviver(type,val){var _ref2=that.revivers[type]||[],_ref3=_slicedToArray(_ref2,1),reviver=_ref3[0];if(!reviver){throw new Error('Unregistered type: '+type)} - if(sync&&!('revive' in reviver)){return val} - return reviver[sync&&reviver.revive?'revive':!sync&&reviver.reviveAsync?'reviveAsync':'revive'](val,stateObj)} - function revivePlainObjects(){var plainObjectTypes=[];Object.entries(types).forEach(function(_ref4){var _ref5=_slicedToArray(_ref4,2),keypath=_ref5[0],type=_ref5[1];if(type==='#'){return}[].concat(type).forEach(function(type){var _ref6=that.revivers[type]||[null,{}],_ref7=_slicedToArray(_ref6,2),plain=_ref7[1].plain;if(!plain){return} - plainObjectTypes.push({keypath:keypath,type:type});delete types[keypath]})});if(!plainObjectTypes.length){return undefined} - return plainObjectTypes.sort(nestedPathsFirst).reduce(function reducer(possibleTypesonPromise,_ref8){var keypath=_ref8.keypath,type=_ref8.type;if(isThenable(possibleTypesonPromise)){return possibleTypesonPromise.then(function(val){return reducer(val,{keypath:keypath,type:type})})} - var val=getByKeyPath(obj,keypath);val=executeReviver(type,val);if(hasConstructorOf(val,TypesonPromise)){return val.then(function(v){var newVal=setAtKeyPath(obj,keypath,v);if(newVal===v){obj=newVal} - return undefined})} - var newVal=setAtKeyPath(obj,keypath,val);if(newVal===val){obj=newVal} - return undefined},undefined)} - var revivalPromises=[];function _revive(keypath,value,target,clone,key){if(ignore$Types&&keypath==='$types'){return undefined} - var type=types[keypath];var isArr=isArray(value);if(isArr||isPlainObject(value)){var _clone=isArr?new Array(value.length):{};keys(value).forEach(function(k){var val=_revive(keypath+(keypath?'.':'')+escapeKeyPathComponent(k),value[k],target||_clone,_clone,k);var set=function set(v){if(hasConstructorOf(v,Undefined)){_clone[k]=undefined}else if(v!==undefined){_clone[k]=v} - return v};if(hasConstructorOf(val,TypesonPromise)){revivalPromises.push(val.then(function(ret){return set(ret)}))}else{set(val)}});value=_clone;while(keyPathResolutions.length){var _keyPathResolutions$=_slicedToArray(keyPathResolutions[0],4),_target=_keyPathResolutions$[0],keyPath=_keyPathResolutions$[1],_clone2=_keyPathResolutions$[2],k=_keyPathResolutions$[3];var val=getByKeyPath(_target,keyPath);if(val!==undefined){_clone2[k]=val}else{break} - keyPathResolutions.splice(0,1)}} - if(!type){return value} - if(type==='#'){var _ret=getByKeyPath(target,value.slice(1));if(_ret===undefined){keyPathResolutions.push([target,value.slice(1),clone,key])} - return _ret} - return[].concat(type).reduce(function reducer(val,typ){if(hasConstructorOf(val,TypesonPromise)){return val.then(function(v){return reducer(v,typ)})} - return executeReviver(typ,val)},value)} - function checkUndefined(retrn){return hasConstructorOf(retrn,Undefined)?undefined:retrn} - var possibleTypesonPromise=revivePlainObjects();var ret;if(hasConstructorOf(possibleTypesonPromise,TypesonPromise)){ret=possibleTypesonPromise.then(function(){return obj})}else{ret=_revive('',obj,null);if(revivalPromises.length){ret=TypesonPromise.resolve(ret).then(function(r){return TypesonPromise.all([r].concat(revivalPromises))}).then(function(_ref9){var _ref10=_slicedToArray(_ref9,1),r=_ref10[0];return r})}} - return isThenable(ret)?sync&&opts.throwOnBadSyncType?function(){throw new TypeError('Sync method requested but async result obtained')}():hasConstructorOf(ret,TypesonPromise)?ret.p.then(checkUndefined):ret:!sync&&opts.throwOnBadSyncType?function(){throw new TypeError('Async method requested but sync result obtained')}():sync?checkUndefined(ret):Promise.resolve(checkUndefined(ret))}},{key:"reviveSync",value:function reviveSync(obj,opts){return this.revive(obj,_objectSpread2({throwOnBadSyncType:!0},opts,{sync:!0}))}},{key:"reviveAsync",value:function reviveAsync(obj,opts){return this.revive(obj,_objectSpread2({throwOnBadSyncType:!0},opts,{sync:!1}))}},{key:"register",value:function register(typeSpecSets,opts){opts=opts||{};[].concat(typeSpecSets).forEach(function R(typeSpec){var _this=this;if(isArray(typeSpec)){return typeSpec.map(function(typSpec){return R.call(_this,typSpec)})} - typeSpec&&keys(typeSpec).forEach(function(typeId){if(typeId==='#'){throw new TypeError('# cannot be used as a type name as it is reserved '+'for cyclic objects')}else if(Typeson.JSON_TYPES.includes(typeId)){throw new TypeError('Plain JSON object types are reserved as type names')} - var spec=typeSpec[typeId];var replacers=spec&&spec.testPlainObjects?this.plainObjectReplacers:this.nonplainObjectReplacers;var existingReplacer=replacers.filter(function(r){return r.type===typeId});if(existingReplacer.length){replacers.splice(replacers.indexOf(existingReplacer[0]),1);delete this.revivers[typeId];delete this.types[typeId]} - if(typeof spec==='function'){var Class=spec;spec={test:function test(x){return x&&x.constructor===Class},replace:function replace(x){return _objectSpread2({},x)},revive:function revive(x){return Object.assign(Object.create(Class.prototype),x)}}}else if(isArray(spec)){var _spec=spec,_spec2=_slicedToArray(_spec,3),test=_spec2[0],replace=_spec2[1],revive=_spec2[2];spec={test:test,replace:replace,revive:revive}} - if(!spec||!spec.test){return} - var replacerObj={type:typeId,test:spec.test.bind(spec)};if(spec.replace){replacerObj.replace=spec.replace.bind(spec)} - if(spec.replaceAsync){replacerObj.replaceAsync=spec.replaceAsync.bind(spec)} - var start=typeof opts.fallback==='number'?opts.fallback:opts.fallback?0:Infinity;if(spec.testPlainObjects){this.plainObjectReplacers.splice(start,0,replacerObj)}else{this.nonplainObjectReplacers.splice(start,0,replacerObj)} - if(spec.revive||spec.reviveAsync){var reviverObj={};if(spec.revive){reviverObj.revive=spec.revive.bind(spec)} - if(spec.reviveAsync){reviverObj.reviveAsync=spec.reviveAsync.bind(spec)} - this.revivers[typeId]=[reviverObj,{plain:spec.testPlainObjects}]} - this.types[typeId]=spec},this)},this);return this}}]);return Typeson}();var Undefined=function Undefined(){_classCallCheck(this,Undefined)};Undefined.__typeson__type__='TypesonUndefined';Typeson.Undefined=Undefined;Typeson.Promise=TypesonPromise;Typeson.isThenable=isThenable;Typeson.toStringTag=toStringTag;Typeson.hasConstructorOf=hasConstructorOf;Typeson.isObject=isObject;Typeson.isPlainObject=isPlainObject;Typeson.isUserObject=isUserObject;Typeson.escapeKeyPathComponent=escapeKeyPathComponent;Typeson.unescapeKeyPathComponent=unescapeKeyPathComponent;Typeson.getByKeyPath=getByKeyPath;Typeson.getJSONType=getJSONType;Typeson.JSON_TYPES=['null','boolean','number','string','array','object'];return Typeson})))});var structuredCloning=createCommonjsModule(function(module,exports){!function(e,t){module.exports=t()}(commonjsGlobal,(function(){function _typeof$1(e){return(_typeof$1="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function _classCallCheck$1(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties$1(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function _defineProperty$1(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function ownKeys$1(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function _toConsumableArray$1(e){return function _arrayWithoutHoles$1(e){if(Array.isArray(e))return _arrayLikeToArray$1(e)}(e)||function _iterableToArray$1(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||function _unsupportedIterableToArray$1(e,t){if(!e)return;if("string"==typeof e)return _arrayLikeToArray$1(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);"Object"===r&&e.constructor&&(r=e.constructor.name);if("Map"===r||"Set"===r)return Array.from(e);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return _arrayLikeToArray$1(e,t)}(e)||function _nonIterableSpread$1(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function _arrayLikeToArray$1(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function _typeof(e){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function _typeof(e){return typeof e}:function _typeof(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function _defineProperty(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function ownKeys(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function _objectSpread2(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?ownKeys(Object(r),!0).forEach((function(t){_defineProperty(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):ownKeys(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function _slicedToArray(e,t){return function _arrayWithHoles(e){if(Array.isArray(e))return e}(e)||function _iterableToArrayLimit(e,t){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(e)))return;var r=[],n=!0,i=!1,o=void 0;try{for(var a,c=e[Symbol.iterator]();!(n=(a=c.next()).done)&&(r.push(a.value),!t||r.length!==t);n=!0);}catch(e){i=!0,o=e}finally{try{n||null==c.return||c.return()}finally{if(i)throw o}}return r}(e,t)||_unsupportedIterableToArray(e,t)||function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function _toConsumableArray(e){return function _arrayWithoutHoles(e){if(Array.isArray(e))return _arrayLikeToArray(e)}(e)||function _iterableToArray(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||_unsupportedIterableToArray(e)||function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?_arrayLikeToArray(e,t):void 0}}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}var e=function TypesonPromise(e){_classCallCheck(this,TypesonPromise),this.p=new Promise(e)};e.__typeson__type__="TypesonPromise","undefined"!=typeof Symbol&&(e.prototype[Symbol.toStringTag]="TypesonPromise"),e.prototype.then=function(t,r){var n=this;return new e((function(e,i){n.p.then((function(r){e(t?t(r):r)})).catch((function(e){return r?r(e):Promise.reject(e)})).then(e,i)}))},e.prototype.catch=function(e){return this.then(null,e)},e.resolve=function(t){return new e((function(e){e(t)}))},e.reject=function(t){return new e((function(e,r){r(t)}))},["all","race"].forEach((function(t){e[t]=function(r){return new e((function(e,n){Promise[t](r.map((function(e){return e&&e.constructor&&"TypesonPromise"===e.constructor.__typeson__type__?e.p:e}))).then(e,n)}))}}));var t={}.toString,r={}.hasOwnProperty,n=Object.getPrototypeOf,i=r.toString;function isThenable(e,t){return isObject(e)&&"function"==typeof e.then&&(!t||"function"==typeof e.catch)}function toStringTag(e){return t.call(e).slice(8,-1)}function hasConstructorOf(e,t){if(!e||"object"!==_typeof(e))return!1;var o=n(e);if(!o)return null===t;var a=r.call(o,"constructor")&&o.constructor;return"function"!=typeof a?null===t:t===a||(null!==t&&i.call(a)===i.call(t)||"function"==typeof t&&"string"==typeof a.__typeson__type__&&a.__typeson__type__===t.__typeson__type__)}function isPlainObject(e){return!(!e||"Object"!==toStringTag(e))&&(!n(e)||hasConstructorOf(e,Object))}function isObject(e){return e&&"object"===_typeof(e)}function escapeKeyPathComponent(e){return e.replace(/~/g,"~0").replace(/\./g,"~1")}function unescapeKeyPathComponent(e){return e.replace(/~1/g,".").replace(/~0/g,"~")}function getByKeyPath(e,t){if(""===t)return e;var r=t.indexOf(".");if(r>-1){var n=e[unescapeKeyPathComponent(t.slice(0,r))];return void 0===n?void 0:getByKeyPath(n,t.slice(r+1))}return e[unescapeKeyPathComponent(t)]}function setAtKeyPath(e,t,r){if(""===t)return r;var n=t.indexOf(".");return n>-1?setAtKeyPath(e[unescapeKeyPathComponent(t.slice(0,n))],t.slice(n+1),r):(e[unescapeKeyPathComponent(t)]=r,e)}function _await(e,t,r){return r?t?t(e):e:(e&&e.then||(e=Promise.resolve(e)),t?e.then(t):e)}var o=Object.keys,a=Array.isArray,c={}.hasOwnProperty,u=["type","replaced","iterateIn","iterateUnsetNumeric"];function _async(e){return function(){for(var t=[],r=0;r<arguments.length;r++)t[r]=arguments[r];try{return Promise.resolve(e.apply(this,t))}catch(e){return Promise.reject(e)}}}function nestedPathsFirst(e,t){if(""===e.keypath)return-1;var r=e.keypath.match(/\./g)||0,n=t.keypath.match(/\./g)||0;return r&&(r=r.length),n&&(n=n.length),r>n?-1:r<n?1:e.keypath<t.keypath?-1:e.keypath>t.keypath}var s=function(){function Typeson(e){_classCallCheck(this,Typeson),this.options=e,this.plainObjectReplacers=[],this.nonplainObjectReplacers=[],this.revivers={},this.types={}}return function _createClass(e,t,r){return t&&_defineProperties(e.prototype,t),r&&_defineProperties(e,r),e}(Typeson,[{key:"stringify",value:function stringify(e,t,r,n){n=_objectSpread2(_objectSpread2(_objectSpread2({},this.options),n),{},{stringification:!0});var i=this.encapsulate(e,null,n);return a(i)?JSON.stringify(i[0],t,r):i.then((function(e){return JSON.stringify(e,t,r)}))}},{key:"stringifySync",value:function stringifySync(e,t,r,n){return this.stringify(e,t,r,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},n),{},{sync:!0}))}},{key:"stringifyAsync",value:function stringifyAsync(e,t,r,n){return this.stringify(e,t,r,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},n),{},{sync:!1}))}},{key:"parse",value:function parse(e,t,r){return r=_objectSpread2(_objectSpread2(_objectSpread2({},this.options),r),{},{parse:!0}),this.revive(JSON.parse(e,t),r)}},{key:"parseSync",value:function parseSync(e,t,r){return this.parse(e,t,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},r),{},{sync:!0}))}},{key:"parseAsync",value:function parseAsync(e,t,r){return this.parse(e,t,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},r),{},{sync:!1}))}},{key:"specialTypeNames",value:function specialTypeNames(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return r.returnTypeNames=!0,this.encapsulate(e,t,r)}},{key:"rootTypeName",value:function rootTypeName(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return r.iterateNone=!0,this.encapsulate(e,t,r)}},{key:"encapsulate",value:function encapsulate(t,r,n){var i=_async((function(t,r){return _await(Promise.all(r.map((function(e){return e[1].p}))),(function(n){return _await(Promise.all(n.map(_async((function(n){var o=!1,a=[],c=_slicedToArray(r.splice(0,1),1),u=_slicedToArray(c[0],7),s=u[0],f=u[2],l=u[3],p=u[4],y=u[5],v=u[6],b=_encapsulate(s,n,f,l,a,!0,v),d=hasConstructorOf(b,e);return function _invoke(e,t){var r=e();return r&&r.then?r.then(t):t(r)}((function(){if(s&&d)return _await(b.p,(function(e){return p[y]=e,o=!0,i(t,a)}))}),(function(e){return o?e:(s?p[y]=b:t=d?b.p:b,i(t,a))}))})))),(function(){return t}))}))})),s=(n=_objectSpread2(_objectSpread2({sync:!0},this.options),n)).sync,f=this,l={},p=[],y=[],v=[],b=!("cyclic"in n)||n.cyclic,d=n.encapsulateObserver,h=_encapsulate("",t,b,r||{},v);function finish(e){var t=Object.values(l);if(n.iterateNone)return t.length?t[0]:Typeson.getJSONType(e);if(t.length){if(n.returnTypeNames)return _toConsumableArray(new Set(t));e&&isPlainObject(e)&&!c.call(e,"$types")?e.$types=l:e={$:e,$types:{$:l}}}else isObject(e)&&c.call(e,"$types")&&(e={$:e,$types:!0});return!n.returnTypeNames&&e}function _adaptBuiltinStateObjectProperties(e,t,r){Object.assign(e,t);var n=u.map((function(t){var r=e[t];return delete e[t],r}));r(),u.forEach((function(t,r){e[t]=n[r]}))}function _encapsulate(t,r,i,u,s,v,b){var h,g={},m=_typeof(r),O=d?function(n){var o=b||u.type||Typeson.getJSONType(r);d(Object.assign(n||g,{keypath:t,value:r,cyclic:i,stateObj:u,promisesData:s,resolvingTypesonPromise:v,awaitingTypesonPromise:hasConstructorOf(r,e)},{type:o}))}:null;if(["string","boolean","number","undefined"].includes(m))return void 0===r||Number.isNaN(r)||r===Number.NEGATIVE_INFINITY||r===Number.POSITIVE_INFINITY?(h=u.replaced?r:replace(t,r,u,s,!1,v,O))!==r&&(g={replaced:h}):h=r,O&&O(),h;if(null===r)return O&&O(),r;if(i&&!u.iterateIn&&!u.iterateUnsetNumeric&&r&&"object"===_typeof(r)){var _=p.indexOf(r);if(!(_<0))return l[t]="#",O&&O({cyclicKeypath:y[_]}),"#"+y[_];!0===i&&(p.push(r),y.push(t))}var j,S=isPlainObject(r),T=a(r),w=(S||T)&&(!f.plainObjectReplacers.length||u.replaced)||u.iterateIn?r:replace(t,r,u,s,S||T,null,O);if(w!==r?(h=w,g={replaced:w}):""===t&&hasConstructorOf(r,e)?(s.push([t,r,i,u,void 0,void 0,u.type]),h=r):T&&"object"!==u.iterateIn||"array"===u.iterateIn?(j=new Array(r.length),g={clone:j}):(["function","symbol"].includes(_typeof(r))||"toJSON"in r||hasConstructorOf(r,e)||hasConstructorOf(r,Promise)||hasConstructorOf(r,ArrayBuffer))&&!S&&"object"!==u.iterateIn?h=r:(j={},u.addLength&&(j.length=r.length),g={clone:j}),O&&O(),n.iterateNone)return j||h;if(!j)return h;if(u.iterateIn){var A=function _loop(n){var o={ownKeys:c.call(r,n)};_adaptBuiltinStateObjectProperties(u,o,(function(){var o=t+(t?".":"")+escapeKeyPathComponent(n),a=_encapsulate(o,r[n],Boolean(i),u,s,v);hasConstructorOf(a,e)?s.push([o,a,Boolean(i),u,j,n,u.type]):void 0!==a&&(j[n]=a)}))};for(var P in r)A(P);O&&O({endIterateIn:!0,end:!0})}else o(r).forEach((function(n){var o=t+(t?".":"")+escapeKeyPathComponent(n);_adaptBuiltinStateObjectProperties(u,{ownKeys:!0},(function(){var t=_encapsulate(o,r[n],Boolean(i),u,s,v);hasConstructorOf(t,e)?s.push([o,t,Boolean(i),u,j,n,u.type]):void 0!==t&&(j[n]=t)}))})),O&&O({endIterateOwn:!0,end:!0});if(u.iterateUnsetNumeric){for(var I=r.length,C=function _loop2(n){if(!(n in r)){var o=t+(t?".":"")+n;_adaptBuiltinStateObjectProperties(u,{ownKeys:!1},(function(){var t=_encapsulate(o,void 0,Boolean(i),u,s,v);hasConstructorOf(t,e)?s.push([o,t,Boolean(i),u,j,n,u.type]):void 0!==t&&(j[n]=t)}))}},N=0;N<I;N++)C(N);O&&O({endIterateUnsetNumeric:!0,end:!0})}return j}function replace(e,t,r,n,i,o,a){for(var c=i?f.plainObjectReplacers:f.nonplainObjectReplacers,u=c.length;u--;){var p=c[u];if(p.test(t,r)){var y=p.type;if(f.revivers[y]){var v=l[e];l[e]=v?[y].concat(v):y}return Object.assign(r,{type:y,replaced:!0}),!s&&p.replaceAsync||p.replace?(a&&a({replacing:!0}),_encapsulate(e,p[s||!p.replaceAsync?"replace":"replaceAsync"](t,r),b&&"readonly",r,n,o,y)):(a&&a({typeDetected:!0}),_encapsulate(e,t,b&&"readonly",r,n,o,y))}}return t}return v.length?s&&n.throwOnBadSyncType?function(){throw new TypeError("Sync method requested but async result obtained")}():Promise.resolve(i(h,v)).then(finish):!s&&n.throwOnBadSyncType?function(){throw new TypeError("Async method requested but sync result obtained")}():n.stringification&&s?[finish(h)]:s?finish(h):Promise.resolve(finish(h))}},{key:"encapsulateSync",value:function encapsulateSync(e,t,r){return this.encapsulate(e,t,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},r),{},{sync:!0}))}},{key:"encapsulateAsync",value:function encapsulateAsync(e,t,r){return this.encapsulate(e,t,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},r),{},{sync:!1}))}},{key:"revive",value:function revive(t,r){var n=t&&t.$types;if(!n)return t;if(!0===n)return t.$;var i=(r=_objectSpread2(_objectSpread2({sync:!0},this.options),r)).sync,c=[],u={},s=!0;n.$&&isPlainObject(n.$)&&(t=t.$,n=n.$,s=!1);var l=this;function executeReviver(e,t){var r=_slicedToArray(l.revivers[e]||[],1)[0];if(!r)throw new Error("Unregistered type: "+e);return i&&!("revive"in r)?t:r[i&&r.revive?"revive":!i&&r.reviveAsync?"reviveAsync":"revive"](t,u)}var p=[];function checkUndefined(e){return hasConstructorOf(e,f)?void 0:e}var y,v=function revivePlainObjects(){var r=[];if(Object.entries(n).forEach((function(e){var t=_slicedToArray(e,2),i=t[0],o=t[1];"#"!==o&&[].concat(o).forEach((function(e){_slicedToArray(l.revivers[e]||[null,{}],2)[1].plain&&(r.push({keypath:i,type:e}),delete n[i])}))})),r.length)return r.sort(nestedPathsFirst).reduce((function reducer(r,n){var i=n.keypath,o=n.type;if(isThenable(r))return r.then((function(e){return reducer(e,{keypath:i,type:o})}));var a=getByKeyPath(t,i);if(hasConstructorOf(a=executeReviver(o,a),e))return a.then((function(e){var r=setAtKeyPath(t,i,e);r===e&&(t=r)}));var c=setAtKeyPath(t,i,a);c===a&&(t=c)}),void 0)}();return hasConstructorOf(v,e)?y=v.then((function(){return t})):(y=function _revive(t,r,i,u,l){if(!s||"$types"!==t){var y=n[t],v=a(r);if(v||isPlainObject(r)){var b=v?new Array(r.length):{};for(o(r).forEach((function(n){var o=_revive(t+(t?".":"")+escapeKeyPathComponent(n),r[n],i||b,b,n),a=function set(e){return hasConstructorOf(e,f)?b[n]=void 0:void 0!==e&&(b[n]=e),e};hasConstructorOf(o,e)?p.push(o.then((function(e){return a(e)}))):a(o)})),r=b;c.length;){var d=_slicedToArray(c[0],4),h=d[0],g=d[1],m=d[2],O=d[3],_=getByKeyPath(h,g);if(void 0===_)break;m[O]=_,c.splice(0,1)}}if(!y)return r;if("#"===y){var j=getByKeyPath(i,r.slice(1));return void 0===j&&c.push([i,r.slice(1),u,l]),j}return[].concat(y).reduce((function reducer(t,r){return hasConstructorOf(t,e)?t.then((function(e){return reducer(e,r)})):executeReviver(r,t)}),r)}}("",t,null),p.length&&(y=e.resolve(y).then((function(t){return e.all([t].concat(p))})).then((function(e){return _slicedToArray(e,1)[0]})))),isThenable(y)?i&&r.throwOnBadSyncType?function(){throw new TypeError("Sync method requested but async result obtained")}():hasConstructorOf(y,e)?y.p.then(checkUndefined):y:!i&&r.throwOnBadSyncType?function(){throw new TypeError("Async method requested but sync result obtained")}():i?checkUndefined(y):Promise.resolve(checkUndefined(y))}},{key:"reviveSync",value:function reviveSync(e,t){return this.revive(e,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},t),{},{sync:!0}))}},{key:"reviveAsync",value:function reviveAsync(e,t){return this.revive(e,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},t),{},{sync:!1}))}},{key:"register",value:function register(e,t){return t=t||{},[].concat(e).forEach((function R(e){var r=this;if(a(e))return e.map((function(e){return R.call(r,e)}));e&&o(e).forEach((function(r){if("#"===r)throw new TypeError("# cannot be used as a type name as it is reserved for cyclic objects");if(Typeson.JSON_TYPES.includes(r))throw new TypeError("Plain JSON object types are reserved as type names");var n=e[r],i=n&&n.testPlainObjects?this.plainObjectReplacers:this.nonplainObjectReplacers,o=i.filter((function(e){return e.type===r}));if(o.length&&(i.splice(i.indexOf(o[0]),1),delete this.revivers[r],delete this.types[r]),"function"==typeof n){var c=n;n={test:function test(e){return e&&e.constructor===c},replace:function replace(e){return _objectSpread2({},e)},revive:function revive(e){return Object.assign(Object.create(c.prototype),e)}}}else if(a(n)){var u=_slicedToArray(n,3);n={test:u[0],replace:u[1],revive:u[2]}}if(n&&n.test){var s={type:r,test:n.test.bind(n)};n.replace&&(s.replace=n.replace.bind(n)),n.replaceAsync&&(s.replaceAsync=n.replaceAsync.bind(n));var f="number"==typeof t.fallback?t.fallback:t.fallback?0:Number.POSITIVE_INFINITY;if(n.testPlainObjects?this.plainObjectReplacers.splice(f,0,s):this.nonplainObjectReplacers.splice(f,0,s),n.revive||n.reviveAsync){var l={};n.revive&&(l.revive=n.revive.bind(n)),n.reviveAsync&&(l.reviveAsync=n.reviveAsync.bind(n)),this.revivers[r]=[l,{plain:n.testPlainObjects}]}this.types[r]=n}}),this)}),this),this}}]),Typeson}(),f=function Undefined(){_classCallCheck(this,Undefined)};f.__typeson__type__="TypesonUndefined",s.Undefined=f,s.Promise=e,s.isThenable=isThenable,s.toStringTag=toStringTag,s.hasConstructorOf=hasConstructorOf,s.isObject=isObject,s.isPlainObject=isPlainObject,s.isUserObject=function isUserObject(e){if(!e||"Object"!==toStringTag(e))return!1;var t=n(e);return!t||(hasConstructorOf(e,Object)||isUserObject(t))},s.escapeKeyPathComponent=escapeKeyPathComponent,s.unescapeKeyPathComponent=unescapeKeyPathComponent,s.getByKeyPath=getByKeyPath,s.getJSONType=function getJSONType(e){return null===e?"null":Array.isArray(e)?"array":_typeof(e)},s.JSON_TYPES=["null","boolean","number","string","array","object"];for(var l={userObject:{test:function test(e,t){return s.isUserObject(e)},replace:function replace(e){return function _objectSpread2$1(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?ownKeys$1(Object(r),!0).forEach((function(t){_defineProperty$1(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):ownKeys$1(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}({},e)},revive:function revive(e){return e}}},p=[{arrayNonindexKeys:{testPlainObjects:!0,test:function test(e,t){return!!Array.isArray(e)&&(Object.keys(e).some((function(e){return String(Number.parseInt(e))!==e}))&&(t.iterateIn="object",t.addLength=!0),!0)},replace:function replace(e,t){return t.iterateUnsetNumeric=!0,e},revive:function revive(e){if(Array.isArray(e))return e;var t=[];return Object.keys(e).forEach((function(r){var n=e[r];t[r]=n})),t}}},{sparseUndefined:{test:function test(e,t){return void 0===e&&!1===t.ownKeys},replace:function replace(e){return 0},revive:function revive(e){}}}],y={undef:{test:function test(e,t){return void 0===e&&(t.ownKeys||!("ownKeys"in t))},replace:function replace(e){return 0},revive:function revive(e){return new s.Undefined}}},v={StringObject:{test:function test(e){return"String"===s.toStringTag(e)&&"object"===_typeof$1(e)},replace:function replace(e){return String(e)},revive:function revive(e){return new String(e)}},BooleanObject:{test:function test(e){return"Boolean"===s.toStringTag(e)&&"object"===_typeof$1(e)},replace:function replace(e){return Boolean(e)},revive:function revive(e){return new Boolean(e)}},NumberObject:{test:function test(e){return"Number"===s.toStringTag(e)&&"object"===_typeof$1(e)},replace:function replace(e){return Number(e)},revive:function revive(e){return new Number(e)}}},b=[{nan:{test:function test(e){return Number.isNaN(e)},replace:function replace(e){return"NaN"},revive:function revive(e){return Number.NaN}}},{infinity:{test:function test(e){return e===Number.POSITIVE_INFINITY},replace:function replace(e){return"Infinity"},revive:function revive(e){return Number.POSITIVE_INFINITY}}},{negativeInfinity:{test:function test(e){return e===Number.NEGATIVE_INFINITY},replace:function replace(e){return"-Infinity"},revive:function revive(e){return Number.NEGATIVE_INFINITY}}}],d={date:{test:function test(e){return"Date"===s.toStringTag(e)},replace:function replace(e){var t=e.getTime();return Number.isNaN(t)?"NaN":t},revive:function revive(e){return"NaN"===e?new Date(Number.NaN):new Date(e)}}},h={regexp:{test:function test(e){return"RegExp"===s.toStringTag(e)},replace:function replace(e){return{source:e.source,flags:(e.global?"g":"")+(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.sticky?"y":"")+(e.unicode?"u":"")}},revive:function revive(e){var t=e.source,r=e.flags;return new RegExp(t,r)}}},g={map:{test:function test(e){return"Map"===s.toStringTag(e)},replace:function replace(e){return _toConsumableArray$1(e.entries())},revive:function revive(e){return new Map(e)}}},m={set:{test:function test(e){return"Set"===s.toStringTag(e)},replace:function replace(e){return _toConsumableArray$1(e.values())},revive:function revive(e){return new Set(e)}}},O="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",_=new Uint8Array(256),j=0;j<O.length;j++)_[O.charCodeAt(j)]=j;var S=function encode(e,t,r){null==r&&(r=e.byteLength);for(var n=new Uint8Array(e,t||0,r),i=n.length,o="",a=0;a<i;a+=3)o+=O[n[a]>>2],o+=O[(3&n[a])<<4|n[a+1]>>4],o+=O[(15&n[a+1])<<2|n[a+2]>>6],o+=O[63&n[a+2]];return i%3==2?o=o.slice(0,-1)+"=":i%3==1&&(o=o.slice(0,-2)+"=="),o},T=function decode(e){var t,r,n,i,o=e.length,a=.75*e.length,c=0;"="===e[e.length-1]&&(a--,"="===e[e.length-2]&&a--);for(var u=new ArrayBuffer(a),s=new Uint8Array(u),f=0;f<o;f+=4)t=_[e.charCodeAt(f)],r=_[e.charCodeAt(f+1)],n=_[e.charCodeAt(f+2)],i=_[e.charCodeAt(f+3)],s[c++]=t<<2|r>>4,s[c++]=(15&r)<<4|n>>2,s[c++]=(3&n)<<6|63&i;return u},w={arraybuffer:{test:function test(e){return"ArrayBuffer"===s.toStringTag(e)},replace:function replace(e,t){t.buffers||(t.buffers=[]);var r=t.buffers.indexOf(e);return r>-1?{index:r}:(t.buffers.push(e),S(e))},revive:function revive(e,t){if(t.buffers||(t.buffers=[]),"object"===_typeof$1(e))return t.buffers[e.index];var r=T(e);return t.buffers.push(r),r}}},A="undefined"==typeof self?commonjsGlobal:self,P={};["Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array"].forEach((function(e){var t=e,r=A[t];r&&(P[e.toLowerCase()]={test:function test(e){return s.toStringTag(e)===t},replace:function replace(e,t){var r=e.buffer,n=e.byteOffset,i=e.length;t.buffers||(t.buffers=[]);var o=t.buffers.indexOf(r);return o>-1?{index:o,byteOffset:n,length:i}:(t.buffers.push(r),{encoded:S(r),byteOffset:n,length:i})},revive:function revive(e,t){t.buffers||(t.buffers=[]);var n,i=e.byteOffset,o=e.length,a=e.encoded,c=e.index;return"index"in e?n=t.buffers[c]:(n=T(a),t.buffers.push(n)),new r(n,i,o)}})}));var I={dataview:{test:function test(e){return"DataView"===s.toStringTag(e)},replace:function replace(e,t){var r=e.buffer,n=e.byteOffset,i=e.byteLength;t.buffers||(t.buffers=[]);var o=t.buffers.indexOf(r);return o>-1?{index:o,byteOffset:n,byteLength:i}:(t.buffers.push(r),{encoded:S(r),byteOffset:n,byteLength:i})},revive:function revive(e,t){t.buffers||(t.buffers=[]);var r,n=e.byteOffset,i=e.byteLength,o=e.encoded,a=e.index;return"index"in e?r=t.buffers[a]:(r=T(o),t.buffers.push(r)),new DataView(r,n,i)}}},C={IntlCollator:{test:function test(e){return s.hasConstructorOf(e,Intl.Collator)},replace:function replace(e){return e.resolvedOptions()},revive:function revive(e){return new Intl.Collator(e.locale,e)}},IntlDateTimeFormat:{test:function test(e){return s.hasConstructorOf(e,Intl.DateTimeFormat)},replace:function replace(e){return e.resolvedOptions()},revive:function revive(e){return new Intl.DateTimeFormat(e.locale,e)}},IntlNumberFormat:{test:function test(e){return s.hasConstructorOf(e,Intl.NumberFormat)},replace:function replace(e){return e.resolvedOptions()},revive:function revive(e){return new Intl.NumberFormat(e.locale,e)}}};function string2arraybuffer(e){for(var t=new Uint8Array(e.length),r=0;r<e.length;r++)t[r]=e.charCodeAt(r);return t.buffer}var N={file:{test:function test(e){return"File"===s.toStringTag(e)},replace:function replace(e){var t=new XMLHttpRequest;if(t.overrideMimeType("text/plain; charset=x-user-defined"),t.open("GET",URL.createObjectURL(e),!1),t.send(),200!==t.status&&0!==t.status)throw new Error("Bad File access: "+t.status);return{type:e.type,stringContents:t.responseText,name:e.name,lastModified:e.lastModified}},revive:function revive(e){var t=e.name,r=e.type,n=e.stringContents,i=e.lastModified;return new File([string2arraybuffer(n)],t,{type:r,lastModified:i})},replaceAsync:function replaceAsync(e){return new s.Promise((function(t,r){var n=new FileReader;n.addEventListener("load",(function(){t({type:e.type,stringContents:n.result,name:e.name,lastModified:e.lastModified})})),n.addEventListener("error",(function(){r(n.error)})),n.readAsBinaryString(e)}))}}},k={bigint:{test:function test(e){return"bigint"==typeof e},replace:function replace(e){return String(e)},revive:function revive(e){return BigInt(e)}}},E={bigintObject:{test:function test(e){return"object"===_typeof$1(e)&&s.hasConstructorOf(e,BigInt)},replace:function replace(e){return String(e)},revive:function revive(e){return new Object(BigInt(e))}}},B={cryptokey:{test:function test(e){return"CryptoKey"===s.toStringTag(e)&&e.extractable},replaceAsync:function replaceAsync(e){return new s.Promise((function(t,r){crypto.subtle.exportKey("jwk",e).catch((function(e){r(e)})).then((function(r){t({jwk:r,algorithm:e.algorithm,usages:e.usages})}))}))},revive:function revive(e){var t=e.jwk,r=e.algorithm,n=e.usages;return crypto.subtle.importKey("jwk",t,r,!0,n)}}};return[l,y,p,v,b,d,h,{imagedata:{test:function test(e){return"ImageData"===s.toStringTag(e)},replace:function replace(e){return{array:_toConsumableArray$1(e.data),width:e.width,height:e.height}},revive:function revive(e){return new ImageData(new Uint8ClampedArray(e.array),e.width,e.height)}}},{imagebitmap:{test:function test(e){return"ImageBitmap"===s.toStringTag(e)||e&&e.dataset&&"ImageBitmap"===e.dataset.toStringTag},replace:function replace(e){var t=document.createElement("canvas");return t.getContext("2d").drawImage(e,0,0),t.toDataURL()},revive:function revive(e){var t=document.createElement("canvas"),r=t.getContext("2d"),n=document.createElement("img");return n.addEventListener("load",(function(){r.drawImage(n,0,0)})),n.src=e,t},reviveAsync:function reviveAsync(e){var t=document.createElement("canvas"),r=t.getContext("2d"),n=document.createElement("img");return n.addEventListener("load",(function(){r.drawImage(n,0,0)})),n.src=e,createImageBitmap(t)}}},N,{file:N.file,filelist:{test:function test(e){return"FileList"===s.toStringTag(e)},replace:function replace(e){for(var t=[],r=0;r<e.length;r++)t[r]=e.item(r);return t},revive:function revive(e){return new(function(){function FileList(){_classCallCheck$1(this,FileList),this._files=arguments[0],this.length=this._files.length}return function _createClass$1(e,t,r){return t&&_defineProperties$1(e.prototype,t),r&&_defineProperties$1(e,r),e}(FileList,[{key:"item",value:function item(e){return this._files[e]}},{key:Symbol.toStringTag,get:function get(){return"FileList"}}]),FileList}())(e)}}},{blob:{test:function test(e){return"Blob"===s.toStringTag(e)},replace:function replace(e){var t=new XMLHttpRequest;if(t.overrideMimeType("text/plain; charset=x-user-defined"),t.open("GET",URL.createObjectURL(e),!1),t.send(),200!==t.status&&0!==t.status)throw new Error("Bad Blob access: "+t.status);return{type:e.type,stringContents:t.responseText}},revive:function revive(e){var t=e.type,r=e.stringContents;return new Blob([string2arraybuffer(r)],{type:t})},replaceAsync:function replaceAsync(e){return new s.Promise((function(t,r){var n=new FileReader;n.addEventListener("load",(function(){t({type:e.type,stringContents:n.result})})),n.addEventListener("error",(function(){r(n.error)})),n.readAsBinaryString(e)}))}}}].concat("function"==typeof Map?g:[],"function"==typeof Set?m:[],"function"==typeof ArrayBuffer?w:[],"function"==typeof Uint8Array?P:[],"function"==typeof DataView?I:[],"undefined"!=typeof Intl?C:[],"undefined"!=typeof crypto?B:[],"undefined"!=typeof BigInt?[k,E]:[])}))});var chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';var lookup=new Uint8Array(256);for(var i=0;i<chars.length;i++){lookup[chars.codePointAt(i)]=i} - var encode=function encode(arraybuffer,byteOffset,lngth){if(lngth===null||lngth===undefined){lngth=arraybuffer.byteLength} - var bytes=new Uint8Array(arraybuffer,byteOffset||0,lngth);var len=bytes.length;var base64='';for(var _i=0;_i<len;_i+=3){base64+=chars[bytes[_i]>>2];base64+=chars[(bytes[_i]&3)<<4|bytes[_i+1]>>4];base64+=chars[(bytes[_i+1]&15)<<2|bytes[_i+2]>>6];base64+=chars[bytes[_i+2]&63]} - if(len%3===2){base64=base64.slice(0,-1)+'='}else if(len%3===1){base64=base64.slice(0,-2)+'=='} - return base64};var decode=function decode(base64){var len=base64.length;var bufferLength=base64.length*0.75;var p=0;var encoded1,encoded2,encoded3,encoded4;if(base64[base64.length-1]==='='){bufferLength--;if(base64[base64.length-2]==='='){bufferLength--}} - var arraybuffer=new ArrayBuffer(bufferLength),bytes=new Uint8Array(arraybuffer);for(var _i2=0;_i2<len;_i2+=4){encoded1=lookup[base64.codePointAt(_i2)];encoded2=lookup[base64.codePointAt(_i2+1)];encoded3=lookup[base64.codePointAt(_i2+2)];encoded4=lookup[base64.codePointAt(_i2+3)];bytes[p++]=encoded1<<2|encoded2>>4;bytes[p++]=(encoded2&15)<<4|encoded3>>2;bytes[p++]=(encoded3&3)<<6|encoded4&63} - return arraybuffer};var _global=typeof self==='undefined'?global:self;var exportObj={};['Int8Array','Uint8Array','Uint8ClampedArray','Int16Array','Uint16Array','Int32Array','Uint32Array','Float32Array','Float64Array'].forEach(function(typeName){var arrType=typeName;var TypedArray=_global[arrType];if(TypedArray){exportObj[typeName.toLowerCase()+"2"]={test:function(x){return typeson.toStringTag(x)===arrType},replace:function(_a){var buffer=_a.buffer,byteOffset=_a.byteOffset,length=_a.length;return{buffer:buffer,byteOffset:byteOffset,length:length}},revive:function(b64Obj){var buffer=b64Obj.buffer,byteOffset=b64Obj.byteOffset,length=b64Obj.length;return new TypedArray(buffer,byteOffset,length)}}}});var arrayBuffer={arraybuffer:{test:function(x){return typeson.toStringTag(x)==='ArrayBuffer'},replace:function(b){return encode(b,0,b.byteLength)},revive:function(b64){var buffer=decode(b64);return buffer}}};var TSON=new typeson().register(structuredCloning);var readBlobsSynchronously='FileReaderSync' in self;var blobsToAwait=[];var blobsToAwaitPos=0;TSON.register([arrayBuffer,exportObj,{blob2:{test:function(x){return typeson.toStringTag(x)==='Blob'},replace:function(b){if(b.isClosed){throw new Error('The Blob is closed')} - if(readBlobsSynchronously){var data=readBlobSync(b,'binary');var base64=encode(data,0,data.byteLength);return{type:b.type,data:base64}}else{blobsToAwait.push(b);var result={type:b.type,data:{start:blobsToAwaitPos,end:blobsToAwaitPos+b.size}};blobsToAwaitPos+=b.size;return result}},finalize:function(b,ba){b.data=encode(ba,0,ba.byteLength)},revive:function(_a){var type=_a.type,data=_a.data;return new Blob([decode(data)],{type:type})}}}]);TSON.mustFinalize=function(){return blobsToAwait.length>0};TSON.finalize=function(items){return __awaiter(void 0,void 0,void 0,function(){var allChunks,_i,items_1,item,types,arrayType,keyPath,typeName,typeSpec,b;return __generator(this,function(_a){switch(_a.label){case 0:return[4,readBlobAsync(new Blob(blobsToAwait),'binary')];case 1:allChunks=_a.sent();if(items){for(_i=0,items_1=items;_i<items_1.length;_i++){item=items_1[_i];if(item.$types){types=item.$types;arrayType=types.$;if(arrayType) - types=types.$;for(keyPath in types){typeName=types[keyPath];typeSpec=TSON.types[typeName];if(typeSpec&&typeSpec.finalize){b=Dexie__default["default"].getByKeyPath(item,arrayType?"$."+keyPath:keyPath);typeSpec.finalize(b,allChunks.slice(b.start,b.end))}}}}} - blobsToAwait=[];return[2]}})})};var DEFAULT_ROWS_PER_CHUNK=2000;function exportDB(db,options){return __awaiter(this,void 0,void 0,function(){function exportAll(){return __awaiter(this,void 0,void 0,function(){var tablesRowCounts,emptyExportJson,posEndDataArray,firstJsonSlice,filter,_loop_1,_i,tables_1,tableName;return __generator(this,function(_a){switch(_a.label){case 0:return[4,Promise.all(db.tables.map(function(table){return table.count()}))];case 1:tablesRowCounts=_a.sent();tablesRowCounts.forEach(function(rowCount,i){return tables[i].rowCount=rowCount});progress.totalRows=tablesRowCounts.reduce(function(p,c){return p+c});emptyExportJson=JSON.stringify(emptyExport,undefined,prettyJson?2:undefined);posEndDataArray=emptyExportJson.lastIndexOf(']');firstJsonSlice=emptyExportJson.substring(0,posEndDataArray);slices.push(firstJsonSlice);filter=options.filter;_loop_1=function(tableName){var table,primKey,inbound,LIMIT,emptyTableExport,emptyTableExportJson,posEndRowsArray,lastKey,lastNumRows,mayHaveMoreRows,_loop_2,state_1;return __generator(this,function(_b){switch(_b.label){case 0:table=db.table(tableName);primKey=table.schema.primKey;inbound=!!primKey.keyPath;LIMIT=options.numRowsPerChunk||DEFAULT_ROWS_PER_CHUNK;emptyTableExport=inbound?{tableName:table.name,inbound:!0,rows:[]}:{tableName:table.name,inbound:!1,rows:[]};emptyTableExportJson=JSON.stringify(emptyTableExport,undefined,prettyJson?2:undefined);if(prettyJson){emptyTableExportJson=emptyTableExportJson.split('\n').join('\n ')} - posEndRowsArray=emptyTableExportJson.lastIndexOf(']');slices.push(emptyTableExportJson.substring(0,posEndRowsArray));lastKey=null;lastNumRows=0;mayHaveMoreRows=!0;_loop_2=function(){var chunkedCollection,values,filteredValues,tsonValues,json,keys,keyvals,tsonTuples,json;return __generator(this,function(_c){switch(_c.label){case 0:if(progressCallback){Dexie__default["default"].ignoreTransaction(function(){return progressCallback(progress)})} - chunkedCollection=lastKey==null?table.limit(LIMIT):table.where(':id').above(lastKey).limit(LIMIT);return[4,chunkedCollection.toArray()];case 1:values=_c.sent();if(values.length===0) - return[2,"break"];if(lastKey!=null&&lastNumRows>0){slices.push(",");if(prettyJson){slices.push("\n ")}} - mayHaveMoreRows=values.length===LIMIT;if(!inbound)return[3,4];filteredValues=filter?values.filter(function(value){return filter(tableName,value)}):values;tsonValues=filteredValues.map(function(value){return TSON.encapsulate(value)});if(!TSON.mustFinalize())return[3,3];return[4,Dexie__default["default"].waitFor(TSON.finalize(tsonValues))];case 2:_c.sent();_c.label=3;case 3:json=JSON.stringify(tsonValues,undefined,prettyJson?2:undefined);if(prettyJson) - json=json.split('\n').join('\n ');slices.push(new Blob([json.substring(1,json.length-1)]));lastNumRows=filteredValues.length;lastKey=values.length>0?Dexie__default["default"].getByKeyPath(values[values.length-1],primKey.keyPath):null;return[3,8];case 4:return[4,chunkedCollection.primaryKeys()];case 5:keys=_c.sent();keyvals=keys.map(function(key,i){return[key,values[i]]});if(filter) - keyvals=keyvals.filter(function(_a){var key=_a[0],value=_a[1];return filter(tableName,value,key)});tsonTuples=keyvals.map(function(tuple){return TSON.encapsulate(tuple)});if(!TSON.mustFinalize())return[3,7];return[4,Dexie__default["default"].waitFor(TSON.finalize(tsonTuples))];case 6:_c.sent();_c.label=7;case 7:json=JSON.stringify(tsonTuples,undefined,prettyJson?2:undefined);if(prettyJson) - json=json.split('\n').join('\n ');slices.push(new Blob([json.substring(1,json.length-1)]));lastNumRows=keyvals.length;lastKey=keys.length>0?keys[keys.length-1]:null;_c.label=8;case 8:progress.completedRows+=values.length;return[2]}})};_b.label=1;case 1:if(!mayHaveMoreRows)return[3,3];return[5,_loop_2()];case 2:state_1=_b.sent();if(state_1==="break") - return[3,3];return[3,1];case 3:slices.push(emptyTableExportJson.substr(posEndRowsArray));progress.completedTables+=1;if(progress.completedTables<progress.totalTables){slices.push(",")} - return[2]}})};_i=0,tables_1=tables;_a.label=2;case 2:if(!(_i<tables_1.length))return[3,5];tableName=tables_1[_i].name;return[5,_loop_1(tableName)];case 3:_a.sent();_a.label=4;case 4:_i++;return[3,2];case 5:slices.push(emptyExportJson.substr(posEndDataArray));progress.done=!0;if(progressCallback){Dexie__default["default"].ignoreTransaction(function(){return progressCallback(progress)})} - return[2]}})})} - var slices,tables,prettyJson,emptyExport,progressCallback,progress;return __generator(this,function(_a){switch(_a.label){case 0:options=options||{};slices=[];tables=db.tables.map(function(table){return({name:table.name,schema:getSchemaString(table),rowCount:0})});prettyJson=options.prettyJson;emptyExport={formatName:"dexie",formatVersion:1,data:{databaseName:db.name,databaseVersion:db.verno,tables:tables,data:[]}};progressCallback=options.progressCallback;progress={done:!1,completedRows:0,completedTables:0,totalRows:NaN,totalTables:db.tables.length};_a.label=1;case 1:_a.trys.push([1,,6,7]);if(!options.noTransaction)return[3,3];return[4,exportAll()];case 2:_a.sent();return[3,5];case 3:return[4,db.transaction('r',db.tables,exportAll)];case 4:_a.sent();_a.label=5;case 5:return[3,7];case 6:TSON.finalize();return[7];case 7:return[2,new Blob(slices,{type:"text/json"})]}})})} - var VERSION=1;var fakeStream={Stream:function(){}};var clarinet_1=createCommonjsModule(function(module,exports){(function(clarinet){var env=(typeof process==='object'&&process.env)?process.env:self;clarinet.parser=function(opt){return new CParser(opt)};clarinet.CParser=CParser;clarinet.CStream=CStream;clarinet.createStream=createStream;clarinet.MAX_BUFFER_LENGTH=10*1024*1024;clarinet.DEBUG=(env.CDEBUG==='debug');clarinet.INFO=(env.CDEBUG==='debug'||env.CDEBUG==='info');clarinet.EVENTS=["value","string","key","openobject","closeobject","openarray","closearray","error","end","ready"];var buffers={textNode:undefined,numberNode:""},streamWraps=clarinet.EVENTS.filter(function(ev){return ev!=="error"&&ev!=="end"}),S=0,Stream;clarinet.STATE={BEGIN:S++,VALUE:S++,OPEN_OBJECT:S++,CLOSE_OBJECT:S++,OPEN_ARRAY:S++,CLOSE_ARRAY:S++,TEXT_ESCAPE:S++,STRING:S++,BACKSLASH:S++,END:S++,OPEN_KEY:S++,CLOSE_KEY:S++,TRUE:S++,TRUE2:S++,TRUE3:S++,FALSE:S++,FALSE2:S++,FALSE3:S++,FALSE4:S++,NULL:S++,NULL2:S++,NULL3:S++,NUMBER_DECIMAL_POINT:S++,NUMBER_DIGIT:S++};for(var s_ in clarinet.STATE)clarinet.STATE[clarinet.STATE[s_]]=s_;S=clarinet.STATE;const Char={tab:0x09,lineFeed:0x0A,carriageReturn:0x0D,space:0x20,doubleQuote:0x22,plus:0x2B,comma:0x2C,minus:0x2D,period:0x2E,_0:0x30,_9:0x39,colon:0x3A,E:0x45,openBracket:0x5B,backslash:0x5C,closeBracket:0x5D,a:0x61,b:0x62,e:0x65,f:0x66,l:0x6C,n:0x6E,r:0x72,s:0x73,t:0x74,u:0x75,openBrace:0x7B,closeBrace:0x7D,};if(!Object.create){Object.create=function(o){function f(){this["__proto__"]=o} - f.prototype=o;return new f}} - if(!Object.getPrototypeOf){Object.getPrototypeOf=function(o){return o.__proto__}} - if(!Object.keys){Object.keys=function(o){var a=[];for(var i in o)if(o.hasOwnProperty(i))a.push(i);return a}} - function checkBufferLength(parser){var maxAllowed=Math.max(clarinet.MAX_BUFFER_LENGTH,10),maxActual=0;for(var buffer in buffers){var len=parser[buffer]===undefined?0:parser[buffer].length;if(len>maxAllowed){switch(buffer){case "text":closeText(parser);break;default:error(parser,"Max buffer length exceeded: "+buffer)}} - maxActual=Math.max(maxActual,len)} - parser.bufferCheckPosition=(clarinet.MAX_BUFFER_LENGTH-maxActual)+parser.position} - function clearBuffers(parser){for(var buffer in buffers){parser[buffer]=buffers[buffer]}} - var stringTokenPattern=/[\\"\n]/g;function CParser(opt){if(!(this instanceof CParser))return new CParser(opt);var parser=this;clearBuffers(parser);parser.bufferCheckPosition=clarinet.MAX_BUFFER_LENGTH;parser.q=parser.c=parser.p="";parser.opt=opt||{};parser.closed=parser.closedRoot=parser.sawRoot=!1;parser.tag=parser.error=null;parser.state=S.BEGIN;parser.stack=new Array();parser.position=parser.column=0;parser.line=1;parser.slashed=!1;parser.unicodeI=0;parser.unicodeS=null;parser.depth=0;emit(parser,"onready")} - CParser.prototype={end:function(){end(this)},write:write,resume:function(){this.error=null;return this},close:function(){return this.write(null)}};try{Stream=fakeStream.Stream}catch(ex){Stream=function(){}} - function createStream(opt){return new CStream(opt)} - function CStream(opt){if(!(this instanceof CStream))return new CStream(opt);this._parser=new CParser(opt);this.writable=!0;this.readable=!0;this.bytes_remaining=0;this.bytes_in_sequence=0;this.temp_buffs={"2":new Buffer(2),"3":new Buffer(3),"4":new Buffer(4)};this.string='';var me=this;Stream.apply(me);this._parser.onend=function(){me.emit("end")};this._parser.onerror=function(er){me.emit("error",er);me._parser.error=null};streamWraps.forEach(function(ev){Object.defineProperty(me,"on"+ev,{get:function(){return me._parser["on"+ev]},set:function(h){if(!h){me.removeAllListeners(ev);me._parser["on"+ev]=h;return h} - me.on(ev,h)},enumerable:!0,configurable:!1})})} - CStream.prototype=Object.create(Stream.prototype,{constructor:{value:CStream}});CStream.prototype.write=function(data){data=new Buffer(data);for(var i=0;i<data.length;i++){var n=data[i];if(this.bytes_remaining>0){for(var j=0;j<this.bytes_remaining;j++){this.temp_buffs[this.bytes_in_sequence][this.bytes_in_sequence-this.bytes_remaining+j]=data[j]} - this.string=this.temp_buffs[this.bytes_in_sequence].toString();this.bytes_in_sequence=this.bytes_remaining=0;i=i+j-1;this._parser.write(this.string);this.emit("data",this.string);continue} - if(this.bytes_remaining===0&&n>=128){if((n>=194)&&(n<=223))this.bytes_in_sequence=2;if((n>=224)&&(n<=239))this.bytes_in_sequence=3;if((n>=240)&&(n<=244))this.bytes_in_sequence=4;if((this.bytes_in_sequence+i)>data.length){for(var k=0;k<=(data.length-1-i);k++){this.temp_buffs[this.bytes_in_sequence][k]=data[i+k]} - this.bytes_remaining=(i+this.bytes_in_sequence)-data.length;return!0}else{this.string=data.slice(i,(i+this.bytes_in_sequence)).toString();i=i+this.bytes_in_sequence-1;this._parser.write(this.string);this.emit("data",this.string);continue}} - for(var p=i;p<data.length;p++){if(data[p]>=128)break} - this.string=data.slice(i,p).toString();this._parser.write(this.string);this.emit("data",this.string);i=p-1;continue}};CStream.prototype.end=function(chunk){if(chunk&&chunk.length)this._parser.write(chunk.toString());this._parser.end();return!0};CStream.prototype.on=function(ev,handler){var me=this;if(!me._parser["on"+ev]&&streamWraps.indexOf(ev)!==-1){me._parser["on"+ev]=function(){var args=arguments.length===1?[arguments[0]]:Array.apply(null,arguments);args.splice(0,0,ev);me.emit.apply(me,args)}} - return Stream.prototype.on.call(me,ev,handler)};CStream.prototype.destroy=function(){clearBuffers(this._parser);this.emit("close")};function emit(parser,event,data){if(clarinet.INFO)console.log('-- emit',event,data);if(parser[event])parser[event](data)} - function emitNode(parser,event,data){closeValue(parser);emit(parser,event,data)} - function closeValue(parser,event){parser.textNode=textopts(parser.opt,parser.textNode);if(parser.textNode!==undefined){emit(parser,(event?event:"onvalue"),parser.textNode)} - parser.textNode=undefined} - function closeNumber(parser){if(parser.numberNode) - emit(parser,"onvalue",parseFloat(parser.numberNode));parser.numberNode=""} - function textopts(opt,text){if(text===undefined){return text} - if(opt.trim)text=text.trim();if(opt.normalize)text=text.replace(/\s+/g," ");return text} - function error(parser,er){closeValue(parser);er+="\nLine: "+parser.line+"\nColumn: "+parser.column+"\nChar: "+parser.c;er=new Error(er);parser.error=er;emit(parser,"onerror",er);return parser} - function end(parser){if(parser.state!==S.VALUE||parser.depth!==0) - error(parser,"Unexpected end");closeValue(parser);parser.c="";parser.closed=!0;emit(parser,"onend");CParser.call(parser,parser.opt);return parser} - function isWhitespace(c){return c===Char.carriageReturn||c===Char.lineFeed||c===Char.space||c===Char.tab} - function write(chunk){var parser=this;if(this.error)throw this.error;if(parser.closed)return error(parser,"Cannot write after close. Assign an onready handler.");if(chunk===null)return end(parser);var i=0,c=chunk.charCodeAt(0),p=parser.p;if(clarinet.DEBUG)console.log('write -> ['+chunk+']');while(c){p=c;parser.c=c=chunk.charCodeAt(i++);if(p!==c)parser.p=p;else p=parser.p;if(!c)break;if(clarinet.DEBUG)console.log(i,c,clarinet.STATE[parser.state]);parser.position ++;if(c===Char.lineFeed){parser.line ++;parser.column=0}else parser.column ++;switch(parser.state){case S.BEGIN:if(c===Char.openBrace)parser.state=S.OPEN_OBJECT;else if(c===Char.openBracket)parser.state=S.OPEN_ARRAY;else if(!isWhitespace(c)) - error(parser,"Non-whitespace before {[.");continue;case S.OPEN_KEY:case S.OPEN_OBJECT:if(isWhitespace(c))continue;if(parser.state===S.OPEN_KEY)parser.stack.push(S.CLOSE_KEY);else{if(c===Char.closeBrace){emit(parser,'onopenobject');this.depth++;emit(parser,'oncloseobject');this.depth--;parser.state=parser.stack.pop()||S.VALUE;continue}else parser.stack.push(S.CLOSE_OBJECT)} - if(c===Char.doubleQuote)parser.state=S.STRING;else error(parser,"Malformed object key should start with \"");continue;case S.CLOSE_KEY:case S.CLOSE_OBJECT:if(isWhitespace(c))continue;(parser.state===S.CLOSE_KEY)?'key':'object';if(c===Char.colon){if(parser.state===S.CLOSE_OBJECT){parser.stack.push(S.CLOSE_OBJECT);closeValue(parser,'onopenobject');this.depth++}else closeValue(parser,'onkey');parser.state=S.VALUE}else if(c===Char.closeBrace){emitNode(parser,'oncloseobject');this.depth--;parser.state=parser.stack.pop()||S.VALUE}else if(c===Char.comma){if(parser.state===S.CLOSE_OBJECT) - parser.stack.push(S.CLOSE_OBJECT);closeValue(parser);parser.state=S.OPEN_KEY}else error(parser,'Bad object');continue;case S.OPEN_ARRAY:case S.VALUE:if(isWhitespace(c))continue;if(parser.state===S.OPEN_ARRAY){emit(parser,'onopenarray');this.depth++;parser.state=S.VALUE;if(c===Char.closeBracket){emit(parser,'onclosearray');this.depth--;parser.state=parser.stack.pop()||S.VALUE;continue}else{parser.stack.push(S.CLOSE_ARRAY)}} - if(c===Char.doubleQuote)parser.state=S.STRING;else if(c===Char.openBrace)parser.state=S.OPEN_OBJECT;else if(c===Char.openBracket)parser.state=S.OPEN_ARRAY;else if(c===Char.t)parser.state=S.TRUE;else if(c===Char.f)parser.state=S.FALSE;else if(c===Char.n)parser.state=S.NULL;else if(c===Char.minus){parser.numberNode+="-"}else if(Char._0<=c&&c<=Char._9){parser.numberNode+=String.fromCharCode(c);parser.state=S.NUMBER_DIGIT}else error(parser,"Bad value");continue;case S.CLOSE_ARRAY:if(c===Char.comma){parser.stack.push(S.CLOSE_ARRAY);closeValue(parser,'onvalue');parser.state=S.VALUE}else if(c===Char.closeBracket){emitNode(parser,'onclosearray');this.depth--;parser.state=parser.stack.pop()||S.VALUE}else if(isWhitespace(c)) - continue;else error(parser,'Bad array');continue;case S.STRING:if(parser.textNode===undefined){parser.textNode=""} - var starti=i-1,slashed=parser.slashed,unicodeI=parser.unicodeI;STRING_BIGLOOP:while(!0){if(clarinet.DEBUG) - console.log(i,c,clarinet.STATE[parser.state],slashed);while(unicodeI>0){parser.unicodeS+=String.fromCharCode(c);c=chunk.charCodeAt(i++);parser.position++;if(unicodeI===4){parser.textNode+=String.fromCharCode(parseInt(parser.unicodeS,16));unicodeI=0;starti=i-1}else{unicodeI++} - if(!c)break STRING_BIGLOOP} - if(c===Char.doubleQuote&&!slashed){parser.state=parser.stack.pop()||S.VALUE;parser.textNode+=chunk.substring(starti,i-1);parser.position+=i-1-starti;break} - if(c===Char.backslash&&!slashed){slashed=!0;parser.textNode+=chunk.substring(starti,i-1);parser.position+=i-1-starti;c=chunk.charCodeAt(i++);parser.position++;if(!c)break} - if(slashed){slashed=!1;if(c===Char.n){parser.textNode+='\n'}else if(c===Char.r){parser.textNode+='\r'}else if(c===Char.t){parser.textNode+='\t'}else if(c===Char.f){parser.textNode+='\f'}else if(c===Char.b){parser.textNode+='\b'}else if(c===Char.u){unicodeI=1;parser.unicodeS=''}else{parser.textNode+=String.fromCharCode(c)} - c=chunk.charCodeAt(i++);parser.position++;starti=i-1;if(!c)break;else continue} - stringTokenPattern.lastIndex=i;var reResult=stringTokenPattern.exec(chunk);if(reResult===null){i=chunk.length+1;parser.textNode+=chunk.substring(starti,i-1);parser.position+=i-1-starti;break} - i=reResult.index+1;c=chunk.charCodeAt(reResult.index);if(!c){parser.textNode+=chunk.substring(starti,i-1);parser.position+=i-1-starti;break}} - parser.slashed=slashed;parser.unicodeI=unicodeI;continue;case S.TRUE:if(c===Char.r)parser.state=S.TRUE2;else error(parser,'Invalid true started with t'+c);continue;case S.TRUE2:if(c===Char.u)parser.state=S.TRUE3;else error(parser,'Invalid true started with tr'+c);continue;case S.TRUE3:if(c===Char.e){emit(parser,"onvalue",!0);parser.state=parser.stack.pop()||S.VALUE}else error(parser,'Invalid true started with tru'+c);continue;case S.FALSE:if(c===Char.a)parser.state=S.FALSE2;else error(parser,'Invalid false started with f'+c);continue;case S.FALSE2:if(c===Char.l)parser.state=S.FALSE3;else error(parser,'Invalid false started with fa'+c);continue;case S.FALSE3:if(c===Char.s)parser.state=S.FALSE4;else error(parser,'Invalid false started with fal'+c);continue;case S.FALSE4:if(c===Char.e){emit(parser,"onvalue",!1);parser.state=parser.stack.pop()||S.VALUE}else error(parser,'Invalid false started with fals'+c);continue;case S.NULL:if(c===Char.u)parser.state=S.NULL2;else error(parser,'Invalid null started with n'+c);continue;case S.NULL2:if(c===Char.l)parser.state=S.NULL3;else error(parser,'Invalid null started with nu'+c);continue;case S.NULL3:if(c===Char.l){emit(parser,"onvalue",null);parser.state=parser.stack.pop()||S.VALUE}else error(parser,'Invalid null started with nul'+c);continue;case S.NUMBER_DECIMAL_POINT:if(c===Char.period){parser.numberNode+=".";parser.state=S.NUMBER_DIGIT}else error(parser,'Leading zero not followed by .');continue;case S.NUMBER_DIGIT:if(Char._0<=c&&c<=Char._9)parser.numberNode+=String.fromCharCode(c);else if(c===Char.period){if(parser.numberNode.indexOf('.')!==-1) - error(parser,'Invalid number has two dots');parser.numberNode+="."}else if(c===Char.e||c===Char.E){if(parser.numberNode.indexOf('e')!==-1||parser.numberNode.indexOf('E')!==-1) - error(parser,'Invalid number has two exponential');parser.numberNode+="e"}else if(c===Char.plus||c===Char.minus){if(!(p===Char.e||p===Char.E)) - error(parser,'Invalid symbol in number');parser.numberNode+=String.fromCharCode(c)}else{closeNumber(parser);i--;parser.state=parser.stack.pop()||S.VALUE} - continue;default:error(parser,"Unknown state: "+parser.state)}} - if(parser.position>=parser.bufferCheckPosition) - checkBufferLength(parser);return parser}})(exports)});function JsonStream(blob){var pos=0;var parser=JsonParser(!0);var rv={pullAsync:function(numBytes){return __awaiter(this,void 0,void 0,function(){var slize,jsonPart,result;return __generator(this,function(_a){switch(_a.label){case 0:slize=blob.slice(pos,pos+numBytes);pos+=numBytes;return[4,readBlobAsync(slize,'text')];case 1:jsonPart=_a.sent();result=parser.write(jsonPart);rv.result=result||{};return[2,result]}})})},pullSync:function(numBytes){var slize=blob.slice(pos,pos+numBytes);pos+=numBytes;var jsonPart=readBlobSync(slize,'text');var result=parser.write(jsonPart);rv.result=result||{};return result},done:function(){return parser.done()},eof:function(){return pos>=blob.size},result:{}};return rv} - function JsonParser(allowPartial){var parser=clarinet_1.parser();var level=0;var result;var stack=[];var obj;var key;var done=!1;var array=!1;parser.onopenobject=function(newKey){var newObj={};newObj.incomplete=!0;if(!result) - result=newObj;if(obj){stack.push([key,obj,array]);if(allowPartial){if(array){obj.push(newObj)}else{obj[key]=newObj}}} - obj=newObj;key=newKey;array=!1;++level};parser.onkey=function(newKey){return key=newKey};parser.onvalue=function(value){return array?obj.push(value):obj[key]=value};parser.oncloseobject=function(){var _a;delete obj.incomplete;key=null;if(--level===0){done=!0}else{var completedObj=obj;_a=stack.pop(),key=_a[0],obj=_a[1],array=_a[2];if(!allowPartial){if(array){obj.push(completedObj)}else{obj[key]=completedObj}}}};parser.onopenarray=function(){var newObj=[];newObj.incomplete=!0;if(!result) - result=newObj;if(obj){stack.push([key,obj,array]);if(allowPartial){if(array){obj.push(newObj)}else{obj[key]=newObj}}} - obj=newObj;array=!0;key=null;++level};parser.onclosearray=function(){var _a;delete obj.incomplete;key=null;if(--level===0){done=!0}else{var completedObj=obj;_a=stack.pop(),key=_a[0],obj=_a[1],array=_a[2];if(!allowPartial){if(array){obj.push(completedObj)}else{obj[key]=completedObj}}}};return{write:function(jsonPart){parser.write(jsonPart);return result},done:function(){return done}}} - var DEFAULT_KILOBYTES_PER_CHUNK=1024;function importDB(exportedData,options){return __awaiter(this,void 0,void 0,function(){var CHUNK_SIZE,stream,dbExport,db;return __generator(this,function(_a){switch(_a.label){case 0:options=options||{};CHUNK_SIZE=options.chunkSizeBytes||(DEFAULT_KILOBYTES_PER_CHUNK*1024);return[4,loadUntilWeGotEnoughData(exportedData,CHUNK_SIZE)];case 1:stream=_a.sent();dbExport=stream.result.data;db=new Dexie__default["default"](dbExport.databaseName);db.version(dbExport.databaseVersion).stores(extractDbSchema(dbExport));return[4,importInto(db,stream,options)];case 2:_a.sent();return[2,db]}})})} - function peakImportFile(exportedData){return __awaiter(this,void 0,void 0,function(){var stream;return __generator(this,function(_a){switch(_a.label){case 0:stream=JsonStream(exportedData);_a.label=1;case 1:if(!!stream.eof())return[3,3];return[4,stream.pullAsync(5*1024)];case 2:_a.sent();if(stream.result.data&&stream.result.data.data){delete stream.result.data.data;return[3,3]} - return[3,1];case 3:return[2,stream.result]}})})} - function importInto(db,exportedData,options){return __awaiter(this,void 0,void 0,function(){function importAll(){return __awaiter(this,void 0,void 0,function(){var _loop_1,_i,_a,tableExport,state_1;return __generator(this,function(_b){switch(_b.label){case 0:_loop_1=function(tableExport){var tableName,table,tableSchemaStr,sourceRows,rows,i,obj,filter,filteredRows,_c,keys,values;return __generator(this,function(_d){switch(_d.label){case 0:if(!tableExport.rows) - return[2,"break"];if(!tableExport.rows.incomplete&&tableExport.rows.length===0) - return[2,"continue"];if(progressCallback){Dexie__default["default"].ignoreTransaction(function(){return progressCallback(progress)})} - tableName=tableExport.tableName;table=db.table(tableName);tableSchemaStr=dbExport.tables.filter(function(t){return t.name===tableName})[0].schema;if(!table){if(!options.acceptMissingTables) - throw new Error("Exported table ".concat(tableExport.tableName," is missing in installed database"));else return[2,"continue"]} - if(!options.acceptChangedPrimaryKey&&tableSchemaStr.split(',')[0]!=table.schema.primKey.src){throw new Error("Primary key differs for table ".concat(tableExport.tableName,". "))} - sourceRows=tableExport.rows;rows=[];for(i=0;i<sourceRows.length;i++){obj=sourceRows[i];if(!obj.incomplete){rows.push(TSON.revive(obj))}else{break}} - filter=options.filter;filteredRows=filter?tableExport.inbound?rows.filter(function(value){return filter(tableName,value)}):rows.filter(function(_a){var key=_a[0],value=_a[1];return filter(tableName,value,key)}):rows;_c=tableExport.inbound?[undefined,filteredRows]:[filteredRows.map(function(row){return row[0]}),rows.map(function(row){return row[1]})],keys=_c[0],values=_c[1];if(!options.overwriteValues)return[3,2];return[4,table.bulkPut(values,keys)];case 1:_d.sent();return[3,4];case 2:return[4,table.bulkAdd(values,keys)];case 3:_d.sent();_d.label=4;case 4:progress.completedRows+=rows.length;if(!rows.incomplete){progress.completedTables+=1} - sourceRows.splice(0,rows.length);return[2]}})};_i=0,_a=dbExport.data;_b.label=1;case 1:if(!(_i<_a.length))return[3,4];tableExport=_a[_i];return[5,_loop_1(tableExport)];case 2:state_1=_b.sent();if(state_1==="break") - return[3,4];_b.label=3;case 3:_i++;return[3,1];case 4:while(dbExport.data.length>0&&dbExport.data[0].rows&&!dbExport.data[0].rows.incomplete){dbExport.data.splice(0,1)} - if(!(!jsonStream.done()&&!jsonStream.eof()))return[3,8];if(!readBlobsSynchronously)return[3,5];jsonStream.pullSync(CHUNK_SIZE);return[3,7];case 5:return[4,Dexie__default["default"].waitFor(jsonStream.pullAsync(CHUNK_SIZE))];case 6:_b.sent();_b.label=7;case 7:return[3,9];case 8:return[3,10];case 9:return[3,0];case 10:return[2]}})})} - var CHUNK_SIZE,jsonStream,dbExportFile,readBlobsSynchronously,dbExport,progressCallback,progress,_i,_a,table;return __generator(this,function(_b){switch(_b.label){case 0:options=options||{};CHUNK_SIZE=options.chunkSizeBytes||(DEFAULT_KILOBYTES_PER_CHUNK*1024);return[4,loadUntilWeGotEnoughData(exportedData,CHUNK_SIZE)];case 1:jsonStream=_b.sent();dbExportFile=jsonStream.result;readBlobsSynchronously='FileReaderSync' in self;dbExport=dbExportFile.data;if(!options.acceptNameDiff&&db.name!==dbExport.databaseName) - throw new Error("Name differs. Current database name is ".concat(db.name," but export is ").concat(dbExport.databaseName));if(!options.acceptVersionDiff&&db.verno!==dbExport.databaseVersion){throw new Error("Database version differs. Current database is in version ".concat(db.verno," but export is ").concat(dbExport.databaseVersion))} - progressCallback=options.progressCallback;progress={done:!1,completedRows:0,completedTables:0,totalRows:dbExport.tables.reduce(function(p,c){return p+c.rowCount},0),totalTables:dbExport.tables.length};if(progressCallback){Dexie__default["default"].ignoreTransaction(function(){return progressCallback(progress)})} - if(!options.clearTablesBeforeImport)return[3,5];_i=0,_a=db.tables;_b.label=2;case 2:if(!(_i<_a.length))return[3,5];table=_a[_i];return[4,table.clear()];case 3:_b.sent();_b.label=4;case 4:_i++;return[3,2];case 5:if(!options.noTransaction)return[3,7];return[4,importAll()];case 6:_b.sent();return[3,9];case 7:return[4,db.transaction('rw',db.tables,importAll)];case 8:_b.sent();_b.label=9;case 9:progress.done=!0;if(progressCallback){Dexie__default["default"].ignoreTransaction(function(){return progressCallback(progress)})} - return[2]}})})} - function loadUntilWeGotEnoughData(exportedData,CHUNK_SIZE){return __awaiter(this,void 0,void 0,function(){var stream,dbExportFile;return __generator(this,function(_a){switch(_a.label){case 0:stream=('slice' in exportedData?JsonStream(exportedData):exportedData);_a.label=1;case 1:if(!!stream.eof())return[3,3];return[4,stream.pullAsync(CHUNK_SIZE)];case 2:_a.sent();if(stream.result.data&&stream.result.data.data) - return[3,3];return[3,1];case 3:dbExportFile=stream.result;if(!dbExportFile||dbExportFile.formatName!="dexie") - throw new Error("Given file is not a dexie export");if(dbExportFile.formatVersion>VERSION){throw new Error("Format version ".concat(dbExportFile.formatVersion," not supported"))} - if(!dbExportFile.data){throw new Error("No data in export file")} - if(!dbExportFile.data.databaseName){throw new Error("Missing databaseName in export file")} - if(!dbExportFile.data.databaseVersion){throw new Error("Missing databaseVersion in export file")} - if(!dbExportFile.data.tables){throw new Error("Missing tables in export file")} - return[2,stream]}})})} - Dexie__default["default"].prototype.export=function(options){return exportDB(this,options)};Dexie__default["default"].prototype.import=function(blob,options){return importInto(this,blob,options)};Dexie__default["default"].import=function(blob,options){return importDB(blob,options)};var dexieExportImport=(function(){throw new Error("This addon extends Dexie.prototype globally and does not have be included in Dexie constructor's addons options.")});exports["default"]=dexieExportImport;exports.exportDB=exportDB;exports.importDB=importDB;exports.importInto=importInto;exports.peakImportFile=peakImportFile;Object.defineProperty(exports,'__esModule',{value:!0})})) diff --git a/ext/permissions.html b/ext/permissions.html index bd97e94d..4aaef3c1 100644 --- a/ext/permissions.html +++ b/ext/permissions.html @@ -194,7 +194,7 @@ <div class="settings-item-label">Configure allowed origins…</div> </div> <div class="settings-item-right open-panel-button-container"> - <button class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> + <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> </div> </div></div> </div> @@ -216,8 +216,8 @@ <div class="modal-title">Allowed Origins</div> <div class="modal-header-button-container"> <div class="modal-header-button-group"> - <button class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> - <button class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> </div> </div> </div> @@ -240,7 +240,7 @@ <div id="permissions-origin-list" class="generic-list"> <div class="permissions-origin-index generic-list-index-prefix"></div> <input type="text" class="permissions-origin-input horizontal-flex-fill" autocomplete="off" spellcheck="false" id="permissions-origin-new-input"> - <button class="low-emphasis permissions-origin-button" id="permissions-origin-add">Add</button> + <button type="button" class="low-emphasis permissions-origin-button" id="permissions-origin-add">Add</button> </div> <div id="permissions-origin-list-empty" class="margin-above"> No additional origins specified. @@ -250,18 +250,18 @@ </div> </div> <div class="modal-footer"> - <button class="low-emphasis" data-modal-action="hide">Close</button> + <button type="button" class="low-emphasis" data-modal-action="hide">Close</button> </div> </div></div> <template id="permissions-origin-template"> <div class="permissions-origin-index generic-list-index-prefix"></div> <input type="text" class="permissions-origin-input horizontal-flex-fill" autocomplete="off" spellcheck="false" readonly> - <button class="icon-button permissions-origin-menu-button permissions-origin-button" data-menu="permissions-origin-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> + <button type="button" class="icon-button permissions-origin-menu-button permissions-origin-button" data-menu="permissions-origin-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> </template> <template id="permissions-origin-menu-template"><div class="popup-menu-container" tabindex="-1" role="dialog"><div class="popup-menu"><div class="popup-menu-body"> - <button class="popup-menu-item" data-menu-action="remove">Remove</button> + <button type="button" class="popup-menu-item" data-menu-action="remove">Remove</button> </div></div></div></template> diff --git a/ext/popup.html b/ext/popup.html index 02248b17..92186e4f 100644 --- a/ext/popup.html +++ b/ext/popup.html @@ -70,14 +70,14 @@ <div class="content-sidebar scrollbar" id="content-sidebar"> <div class="content-sidebar-inner"> <div class="content-sidebar-top-pre"> - <button class="sidebar-button danger" id="close-button" title="Close popup" data-hotkey='["close","title","Close popup ({0})"]'><span class="sidebar-button-icon icon" data-icon="cross"></span></button> + <button type="button" class="sidebar-button danger" id="close-button" title="Close popup" data-hotkey='["close","title","Close popup ({0})"]'><span class="sidebar-button-icon icon" data-icon="cross"></span></button> </div> <div class="content-sidebar-top"> - <button class="sidebar-button" disabled id="navigate-previous-button" title="Previous definition" data-hotkey='["historyBackward","title","Previous definition ({0})"]'><span class="sidebar-button-icon icon" data-icon="left-chevron"></span></button> - <button class="sidebar-button" disabled id="navigate-next-button" title="Next definition" data-hotkey='["historyForward","title","Next definition ({0})"]'><span class="sidebar-button-icon icon" data-icon="right-chevron"></span></button> + <button type="button" class="sidebar-button" disabled id="navigate-previous-button" title="Previous definition" data-hotkey='["historyBackward","title","Previous definition ({0})"]'><span class="sidebar-button-icon icon" data-icon="left-chevron"></span></button> + <button type="button" class="sidebar-button" disabled id="navigate-next-button" title="Next definition" data-hotkey='["historyForward","title","Next definition ({0})"]'><span class="sidebar-button-icon icon" data-icon="right-chevron"></span></button> </div> <div class="content-sidebar-bottom"> - <button class="sidebar-button" id="profile-button"><span class="sidebar-button-icon icon" data-icon="profile"></span></button> + <button type="button" class="sidebar-button" id="profile-button"><span class="sidebar-button-icon icon" data-icon="profile"></span></button> </div> </div> </div> diff --git a/ext/search.html b/ext/search.html index be295937..460c0df8 100644 --- a/ext/search.html +++ b/ext/search.html @@ -50,8 +50,8 @@ </div> <div class="search-textbox-container"> <textarea id="search-textbox" class="scrollbar" placeholder="Input a term, expression, sentence, or block of text" autocomplete="off" lang="ja" autofocus></textarea> - <button id="search-back-button" class="search-button" hidden><span class="icon" data-icon="left-chevron"></span></button> - <button id="search-button" class="search-button"><span class="icon" data-icon="magnifying-glass"></span></button> + <button type="button" id="search-back-button" class="search-button" hidden><span class="icon" data-icon="left-chevron"></span></button> + <button type="button" id="search-button" class="search-button"><span class="icon" data-icon="magnifying-glass"></span></button> </div> </div> diff --git a/ext/settings.html b/ext/settings.html index 3b410cce..f1001f90 100644 --- a/ext/settings.html +++ b/ext/settings.html @@ -106,7 +106,7 @@ <div class="settings-item-label">Configure profiles…</div> </div> <div class="settings-item-right open-panel-button-container"> - <button class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> + <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> </div> </div></div> </div> @@ -127,7 +127,7 @@ </div> </div> <div class="settings-item-right open-panel-button-container"> - <button class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> + <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> </div> </div></div> <div class="settings-item"> @@ -147,7 +147,7 @@ </div> </div> <div class="settings-item-right"> - <button id="storage-refresh" class="low-emphasis">Refresh</button> + <button type="button" id="storage-refresh" class="low-emphasis">Refresh</button> </div> </div> </div> @@ -280,7 +280,7 @@ <div class="settings-item-label">Secondary dictionaries…</div> </div> <div class="settings-item-right open-panel-button-container"> - <button class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> + <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> </div> </div></div> </div> @@ -319,7 +319,7 @@ </div> <div class="settings-item-right"> <div class="horizontal-flex horizontal-flex-nowrap"> - <button class="low-emphasis" id="sort-frequency-dictionary-order-auto">Auto</button> + <button type="button" class="low-emphasis" id="sort-frequency-dictionary-order-auto">Auto</button> <select id="sort-frequency-dictionary-order"> <option value="descending">Occurrence-based</option> <option value="ascending">Rank-based</option> @@ -411,7 +411,7 @@ <div class="settings-item-label">Configure advanced scanning inputs… <span class="light no-wrap">(<span class="scanning-input-count">#</span> defined)</span></div> </div> <div class="settings-item-right open-panel-button-container"> - <button class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> + <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> </div> </div></div> <div class="settings-item"> @@ -615,7 +615,7 @@ <div class="settings-item-label">Configure input action prevention…</div> </div> <div class="settings-item-right open-panel-button-container"> - <button class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> + <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> </div> </div></div> </div> @@ -938,7 +938,7 @@ <div class="settings-item-label">Configure collapsible dictionaries…</div> </div> <div class="settings-item-right open-panel-button-container"> - <button class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> + <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> </div> </div></div> <div class="settings-item settings-item-button" data-modal-action="show,custom-css"><div class="settings-item-inner"> @@ -946,7 +946,7 @@ <div class="settings-item-label">Configure custom CSS…</div> </div> <div class="settings-item-right open-panel-button-container"> - <button class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> + <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> </div> </div></div> </div> @@ -1323,7 +1323,7 @@ <div class="settings-item-label">Configure audio playback sources…</div> </div> <div class="settings-item-right open-panel-button-container"> - <button class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> + <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> </div> </div></div> </div> @@ -1398,7 +1398,7 @@ A setup guide can be found <a href="https://github.com/siikamiika/yomichan-mecab-installer/blob/master/README.md" target="_blank" rel="noopener noreferrer">here</a>. </p> <div class="margin-above flex-row-nowrap"> - <button id="test-mecab-button">Test</button> + <button type="button" id="test-mecab-button">Test</button> <div id="test-mecab-results" class="flex-margin-left" hidden></div> </div> <p class="margin-above"> @@ -1444,7 +1444,7 @@ </div> <div class="settings-item-right"> <div class="horizontal-flex horizontal-flex-nowrap"> - <button class="low-emphasis" data-modal-action="show,sentence-termination-characters" id="configure-sentence-termination-characters-button" hidden>Configure…</button> + <button type="button" class="low-emphasis" data-modal-action="show,sentence-termination-characters" id="configure-sentence-termination-characters-button" hidden>Configure…</button> <select data-setting="sentenceParsing.terminationCharacterMode" data-transform='{ "type": "setVisibility", @@ -1510,7 +1510,7 @@ <div class="settings-item-label">Configure custom text replacement patterns…</div> </div> <div class="settings-item-right open-panel-button-container"> - <button class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> + <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> </div> </div></div> <div class="settings-item"><div class="settings-item-inner settings-item-inner-wrappable"> @@ -1849,8 +1849,8 @@ If an error occurs, Anki and/or AnkiConnect may need to be updated. </p> <div class="test-anki-note-viewer-container"> - <button class="test-anki-note-viewer-button" data-mode="browse">Test <em>Card browser</em></button> - <button class="test-anki-note-viewer-button" data-mode="edit">Test <em>Note editor</em></button> + <button type="button" class="test-anki-note-viewer-button" data-mode="browse">Test <em>Card browser</em></button> + <button type="button" class="test-anki-note-viewer-button" data-mode="edit">Test <em>Note editor</em></button> <div class="test-anki-note-viewer-results" id="test-anki-note-viewer-results" hidden></div> </div> <p class="margin-above"> @@ -1891,7 +1891,7 @@ <div class="settings-item-label">Configure Anki card format…</div> </div> <div class="settings-item-right open-panel-button-container"> - <button class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> + <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> </div> </div></div> <div class="settings-item settings-item-button advanced-only" data-modal-action="show,anki-card-templates"><div class="settings-item-inner"> @@ -1899,7 +1899,7 @@ <div class="settings-item-label">Configure Anki card templates…</div> </div> <div class="settings-item-right open-panel-button-container"> - <button class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> + <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> </div> </div></div> </div> @@ -2011,7 +2011,7 @@ <div class="settings-item-label">Configure standard keyboard shortcuts…</div> </div> <div class="settings-item-right open-panel-button-container"> - <button class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> + <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> </div> </div></div> <div class="settings-item settings-item-button" data-modal-action="show,extension-keyboard-shortcuts"><div class="settings-item-inner"> @@ -2019,7 +2019,7 @@ <div class="settings-item-label">Configure native keyboard shortcuts…</div> </div> <div class="settings-item-right open-panel-button-container"> - <button class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> + <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> </div> </div></div> </div> @@ -2047,14 +2047,14 @@ <div class="settings-item-right settings-item-button-group-container"> <div class="settings-item-button-group"> <div class="settings-item-button-group-item"> - <button class="low-emphasis" id="settings-import-button">Import Settings</button> + <button type="button" class="low-emphasis" id="settings-import-button">Import Settings</button> <div hidden><input type="file" id="settings-import-file" accept=".json,application/json"></div> </div> <div class="settings-item-button-group-item"> - <button class="low-emphasis" id="settings-export-button">Export Settings</button> + <button type="button" class="low-emphasis" id="settings-export-button">Export Settings</button> </div> <div class="settings-item-button-group-item"> - <button class="low-emphasis danger" id="settings-reset-button">Reset Settings</button> + <button type="button" class="low-emphasis danger" id="settings-reset-button">Reset Settings</button> </div> </div> </div> @@ -2082,11 +2082,11 @@ <div class="settings-item-right settings-item-button-group-container"> <div class="settings-item-button-group"> <div class="settings-item-button-group-item"> - <button class="low-emphasis" id="settings-import-db-button">Import Dictionary Collection</button> + <button type="button" class="low-emphasis" id="settings-import-db-button">Import Dictionary Collection</button> <div hidden><input type="file" id="settings-import-db" accept=".json,application/json"></div> </div> <div class="settings-item-button-group-item"> - <button class="low-emphasis" id="settings-export-db-button">Export Dictionary Collection</button> + <button type="button" class="low-emphasis" id="settings-export-db-button">Export Dictionary Collection</button> </div> </div> </div> @@ -2224,10 +2224,10 @@ <div class="fab-container-right"> <div class="fab-container-right-inner1"><div class="fab-container-right-inner2"> <div class="fab-container-item fab-container-item-popup-preview"> - <button class="fab-button icon-button" data-action="toggle-preview-sidebar"><span class="icon-button-inner"><span class="fab-button-background"></span><span class="icon" data-icon="popup"></span></span></button> + <button type="button" class="fab-button icon-button" data-action="toggle-preview-sidebar"><span class="icon-button-inner"><span class="fab-button-background"></span><span class="icon" data-icon="popup"></span></span></button> </div> <div class="fab-container-item"> - <button class="fab-button icon-button" data-action="toggle-sidebar"><span class="icon-button-inner"><span class="fab-button-background"></span><span class="icon" data-icon="hamburger-menu"></span></span></button> + <button type="button" class="fab-button icon-button" data-action="toggle-sidebar"><span class="icon-button-inner"><span class="fab-button-background"></span><span class="icon" data-icon="hamburger-menu"></span></span></button> </div> </div></div> </div> @@ -2256,8 +2256,8 @@ <div class="modal-title">Profiles</div> <div class="modal-header-button-container"> <div class="modal-header-button-group"> - <button class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> - <button class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> </div> </div> </div> @@ -2271,11 +2271,11 @@ </div> <div class="profile-entry-list generic-list" id="profile-entry-list"></div> <div class="profile-add-button-container"> - <button class="low-emphasis" id="profile-add-button">Add</button> + <button type="button" class="low-emphasis" id="profile-add-button">Add</button> </div> </div> <div class="modal-footer"> - <button data-modal-action="hide">Close</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -2284,8 +2284,8 @@ <div class="modal-title">Profile Conditions</div> <div class="modal-header-button-container"> <div class="modal-header-button-group"> - <button class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> - <button class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> </div> </div> </div> @@ -2322,11 +2322,11 @@ <div class="profile-condition-group-list-info"> <div class="profile-condition-groups-empty-info"><em>No conditions set up.</em></div> <div class="profile-condition-group-list-info-space"></div> - <button class="low-emphasis" id="profile-add-condition-group">Add Group</button> + <button type="button" class="low-emphasis" id="profile-add-condition-group">Add Group</button> </div> </div> <div class="modal-footer"> - <button data-modal-action="hide">Close</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -2335,8 +2335,8 @@ <div class="modal-title">Copy Profile</div> <div class="modal-header-button-container"> <div class="modal-header-button-group"> - <button class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> - <button class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> </div> </div> </div> @@ -2345,8 +2345,8 @@ <select class="form-control" id="profile-copy-source-select"></select> </div> <div class="modal-footer"> - <button class="low-emphasis" data-modal-action="hide">Cancel</button> - <button id="profile-copy-confirm-button">Copy Profile</button> + <button type="button" class="low-emphasis" data-modal-action="hide">Cancel</button> + <button type="button" id="profile-copy-confirm-button">Copy Profile</button> </div> </div></div> @@ -2358,8 +2358,8 @@ </p> </div> <div class="modal-footer"> - <button class="low-emphasis" data-modal-action="hide">Cancel</button> - <button class="danger" id="profile-remove-confirm-button">Remove Profile</button> + <button type="button" class="low-emphasis" data-modal-action="hide">Cancel</button> + <button type="button" class="danger" id="profile-remove-confirm-button">Remove Profile</button> </div> </div></div> @@ -2370,7 +2370,7 @@ <div class="profile-entry-cell"><label class="radio"><input type="radio" class="profile-entry-is-default-radio" name="profile-entry-default-radio"><span class="radio-body"><span class="radio-border"></span><span class="radio-dot"></span></span></label></div> <div class="profile-entry-cell"><input class="profile-entry-name-input" type="text" autocomplete="off" placeholder="Profile name"></div> <div class="profile-entry-cell"><a tabindex="0" class="profile-entry-condition-count-link"><span class="profile-entry-condition-count">0</span></a></div> - <div class="profile-entry-cell input-height-icon-button-container"><button class="icon-button profile-entry-menu-button" data-menu="profile-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button></div> + <div class="profile-entry-cell input-height-icon-button-container"><button type="button" class="icon-button profile-entry-menu-button" data-menu="profile-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button></div> </div></template> <template id="profile-condition-group-template"><div class="profile-condition-group"> @@ -2378,7 +2378,7 @@ <div class="profile-condition-list-info"> <div class="profile-condition-group-separator-label">or</div> <div class="profile-condition-list-info-space"></div> - <button class="profile-condition-add-button low-emphasis">Add</button> + <button type="button" class="profile-condition-add-button low-emphasis">Add</button> </div> </div></template> @@ -2390,28 +2390,28 @@ <div class="profile-condition-input-container"> <input type="text" class="profile-condition-input" autocomplete="off" spellcheck="false"> <div class="input-height-icon-button-container mouse-button-container" hidden> - <button class="icon-button profile-condition-mouse-button mouse-button"><span class="icon-button-inner"><span class="icon" data-icon="mouse"></span></span></button> + <button type="button" class="icon-button profile-condition-mouse-button mouse-button"><span class="icon-button-inner"><span class="icon" data-icon="mouse"></span></span></button> </div> </div> </div> <div class="profile-condition-menu-button-container input-height-icon-button-container"> - <button class="icon-button profile-condition-menu-button" data-menu="profile-condition-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> + <button type="button" class="icon-button profile-condition-menu-button" data-menu="profile-condition-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> </div> </div></template> <template id="profile-menu-template"><div class="popup-menu-container" tabindex="-1" role="dialog"><div class="popup-menu"><div class="popup-menu-body"> - <button class="popup-menu-item" data-menu-action="moveUp">Move up</button> - <button class="popup-menu-item" data-menu-action="moveDown">Move down</button> - <button class="popup-menu-item" data-menu-action="copyFrom">Copy from…</button> - <button class="popup-menu-item" data-menu-action="editConditions">Edit conditions…</button> - <button class="popup-menu-item" data-menu-action="duplicate">Duplicate</button> - <button class="popup-menu-item" data-menu-action="delete">Delete</button> + <button type="button" class="popup-menu-item" data-menu-action="moveUp">Move up</button> + <button type="button" class="popup-menu-item" data-menu-action="moveDown">Move down</button> + <button type="button" class="popup-menu-item" data-menu-action="copyFrom">Copy from…</button> + <button type="button" class="popup-menu-item" data-menu-action="editConditions">Edit conditions…</button> + <button type="button" class="popup-menu-item" data-menu-action="duplicate">Duplicate</button> + <button type="button" class="popup-menu-item" data-menu-action="delete">Delete</button> </div></div></div></template> <template id="profile-condition-menu-template"><div class="popup-menu-container" tabindex="-1" role="dialog"><div class="popup-menu"><div class="popup-menu-body"> - <button class="popup-menu-item" data-menu-action="resetValue">Reset value</button> - <button class="popup-menu-item" data-menu-action="delete">Delete</button> - <button class="popup-menu-item" data-menu-action="deleteGroup">Delete group</button> + <button type="button" class="popup-menu-item" data-menu-action="resetValue">Reset value</button> + <button type="button" class="popup-menu-item" data-menu-action="delete">Delete</button> + <button type="button" class="popup-menu-item" data-menu-action="deleteGroup">Delete group</button> </div></div></div></template> @@ -2421,8 +2421,8 @@ <div class="modal-title">Dictionaries</div> <div class="modal-header-button-container"> <div class="modal-header-button-group"> - <button class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> - <button class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> </div> </div> </div> @@ -2480,10 +2480,10 @@ <div class="progress-bar-track"><div class="progress-bar"></div></div> </div> <div class="modal-footer"> - <button class="low-emphasis danger dictionary-database-mutating-input" id="dictionary-delete-all-button">Delete All</button> - <button class="low-emphasis dictionary-database-mutating-input" id="dictionary-check-integrity">Check Integrity</button> - <button class="low-emphasis dictionary-database-mutating-input" id="dictionary-import-file-button">Import</button> - <button data-modal-action="hide">Close</button> + <button type="button" class="low-emphasis danger dictionary-database-mutating-input" id="dictionary-delete-all-button">Delete All</button> + <button type="button" class="low-emphasis dictionary-database-mutating-input" id="dictionary-check-integrity">Check Integrity</button> + <button type="button" class="low-emphasis dictionary-database-mutating-input" id="dictionary-import-file-button">Import</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -2495,8 +2495,8 @@ <p class="danger-text">This action cannot be undone.</p> </div> <div class="modal-footer"> - <button class="low-emphasis" data-modal-action="hide">Cancel</button> - <button class="danger" data-modal-action="hide" id="dictionary-confirm-delete-button">Delete</button> + <button type="button" class="low-emphasis" data-modal-action="hide">Cancel</button> + <button type="button" class="danger" data-modal-action="hide" id="dictionary-confirm-delete-button">Delete</button> </div> </div></div> @@ -2507,8 +2507,8 @@ <p class="danger-text">This action cannot be undone.</p> </div> <div class="modal-footer"> - <button class="low-emphasis" data-modal-action="hide">Cancel</button> - <button class="danger" data-modal-action="hide" id="dictionary-confirm-delete-all-button">Delete</button> + <button type="button" class="low-emphasis" data-modal-action="hide">Cancel</button> + <button type="button" class="danger" data-modal-action="hide" id="dictionary-confirm-delete-all-button">Delete</button> </div> </div></div> @@ -2517,8 +2517,8 @@ <div class="modal-title">Secondary Search Dictionaries</div> <div class="modal-header-button-container"> <div class="modal-header-button-group"> - <button class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> - <button class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> </div> </div> </div> @@ -2530,7 +2530,7 @@ <div id="secondary-search-dictionary-list" class="secondary-search-dictionary-list"></div> </div> <div class="modal-footer"> - <button data-modal-action="hide">Close</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -2539,8 +2539,8 @@ <div class="modal-title">Collapsible Dictionaries</div> <div class="modal-header-button-container"> <div class="modal-header-button-group"> - <button class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> - <button class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> </div> </div> </div> @@ -2556,7 +2556,7 @@ <div id="collapsible-dictionary-list" class="collapsible-dictionary-list"></div> </div> <div class="modal-footer"> - <button data-modal-action="hide">Close</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -2565,8 +2565,8 @@ <div class="modal-title">Collapsible Dictionary Info</div> <div class="modal-header-button-container"> <div class="modal-header-button-group"> - <button class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> - <button class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> </div> </div> </div> @@ -2625,7 +2625,7 @@ </div> </div> <div class="modal-footer"> - <button data-modal-action="hide">Close</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -2663,7 +2663,7 @@ </div></div> </div> <div class="modal-footer"> - <button data-modal-action="hide">Close</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -2681,7 +2681,7 @@ <div class="dictionary-counts"></div> </div> <div class="modal-footer"> - <button data-modal-action="hide">Close</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -2694,8 +2694,8 @@ </div> </div> <div class="modal-footer"> - <button class="low-emphasis" data-modal-action="hide">Cancel</button> - <button data-modal-action="hide" id="dictionary-move-button">Move</button> + <button type="button" class="low-emphasis" data-modal-action="hide">Cancel</button> + <button type="button" data-modal-action="hide" id="dictionary-move-button">Move</button> </div> </div></div> @@ -2708,15 +2708,15 @@ <span> <strong class="dictionary-title"></strong> <span class="light dictionary-version"></span> </span> - <button class="dictionary-outdated-button" hidden> + <button type="button" class="dictionary-outdated-button" hidden> <div class="badge warning-badge"><span class="icon" data-icon="exclamation-point-short"></span></div> </button> - <button class="dictionary-integrity-button" hidden> + <button type="button" class="dictionary-integrity-button" hidden> <div class="badge info-badge badge-small-icon"><span class="icon" data-icon="checkmark"></span></div> </button> </div> <input type="number" step="1" class="short-height dictionary-priority"> - <button class="icon-button dictionary-menu-button" data-menu="dictionary-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> + <button type="button" class="icon-button dictionary-menu-button" data-menu="dictionary-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> </template> <template id="dictionary-details-entry-template"><div class="dictionary-details-entry"> @@ -2731,7 +2731,7 @@ <span> <strong class="dictionary-title">Unassociated Data</strong> <span class="light dictionary-total-count"></span> </span> - <button class="dictionary-integrity-button"> + <button type="button" class="dictionary-integrity-button"> <div class="badge warning-badge"><span class="icon" data-icon="exclamation-point-short"></span></div> </button> </div> @@ -2740,11 +2740,11 @@ </template> <template id="dictionary-menu-template"><div class="popup-menu-container" tabindex="-1" role="dialog"><div class="popup-menu"><div class="popup-menu-body"> - <button class="popup-menu-item" data-menu-action="showDetails">Details…</button> - <button class="popup-menu-item" data-menu-action="moveUp">Move up</button> - <button class="popup-menu-item" data-menu-action="moveDown">Move down</button> - <button class="popup-menu-item" data-menu-action="moveTo">Move to…</button> - <button class="popup-menu-item" data-menu-action="delete">Delete</button> + <button type="button" class="popup-menu-item" data-menu-action="showDetails">Details…</button> + <button type="button" class="popup-menu-item" data-menu-action="moveUp">Move up</button> + <button type="button" class="popup-menu-item" data-menu-action="moveDown">Move down</button> + <button type="button" class="popup-menu-item" data-menu-action="moveTo">Move to…</button> + <button type="button" class="popup-menu-item" data-menu-action="delete">Delete</button> </div></div></div></template> <template id="secondary-search-dictionary-template"><div class="secondary-search-dictionary-item horizontal-flex"> @@ -2775,8 +2775,8 @@ <div class="modal-title">Custom CSS</div> <div class="modal-header-button-container"> <div class="modal-header-button-group"> - <button class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> - <button class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> </div> </div> </div> @@ -2787,7 +2787,7 @@ <textarea class="no-wrap" autocomplete="off" spellcheck="false" id="custom-popup-outer-css" data-setting="general.customPopupOuterCss" data-tab-action="indent,4"></textarea> </div> <div class="modal-footer"> - <button data-modal-action="hide">Close</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> <div class="modal-content-container1-fade"></div> @@ -2800,8 +2800,8 @@ <div class="modal-title">Audio Sources</div> <div class="modal-header-button-container"> <div class="modal-header-button-group"> - <button class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> - <button class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> </div> </div> </div> @@ -2825,8 +2825,8 @@ </div> </div> <div class="modal-footer"> - <button id="audio-source-add" class="low-emphasis">Add</button> - <button data-modal-action="hide">Close</button> + <button type="button" id="audio-source-add" class="low-emphasis">Add</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -2846,7 +2846,7 @@ </p> </div> <div class="modal-footer"> - <button data-modal-action="hide">Close</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -2865,7 +2865,7 @@ </p> </div> <div class="modal-footer"> - <button data-modal-action="hide">Close</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -2879,11 +2879,11 @@ </p> <div class="horizontal-flex margin-above"> <input type="text" value="よみちゃん" id="text-to-speech-voice-test-text" autocomplete="off" lang="ja"> - <button id="text-to-speech-voice-test">Test</button> + <button type="button" id="text-to-speech-voice-test">Test</button> </div> </div> <div class="modal-footer"> - <button data-modal-action="hide">Close</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -2910,12 +2910,12 @@ <select class="audio-source-parameter"></select> </div> </div> - <button class="icon-button audio-source-menu-button" data-menu="audio-source-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> + <button type="button" class="icon-button audio-source-menu-button" data-menu="audio-source-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> </div></template> <template id="audio-source-menu-template"><div class="popup-menu-container" tabindex="-1" role="dialog"><div class="popup-menu"><div class="popup-menu-body"> - <button class="popup-menu-item" data-menu-action="help">Help</button> - <button class="popup-menu-item" data-menu-action="remove">Remove</button> + <button type="button" class="popup-menu-item" data-menu-action="help">Help</button> + <button type="button" class="popup-menu-item" data-menu-action="remove">Remove</button> </div></div></div></template> @@ -2925,8 +2925,8 @@ <div class="modal-title">Scanning Inputs</div> <div class="modal-header-button-container"> <div class="modal-header-button-group"> - <button class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> - <button class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> </div> </div> </div> @@ -2971,8 +2971,8 @@ </div> </div> <div class="modal-footer"> - <button class="low-emphasis" id="scan-input-add">Add</button> - <button data-modal-action="hide">Close</button> + <button type="button" class="low-emphasis" id="scan-input-add">Add</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -2983,20 +2983,20 @@ <div class="scan-input-index-cell generic-list-index-prefix"></div> <div class="scan-input-menu-button-cell"> <div class="input-height-icon-button-container"> - <button class="icon-button scanning-input-menu-button" data-menu="scanning-inputs-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> + <button type="button" class="icon-button scanning-input-menu-button" data-menu="scanning-inputs-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> </div> </div> <div class="scan-input-prefix-cell" data-property="include"><span>Required inputs:</span></div> <div class="scan-input-content-cell input-group" data-property="include"> <input type="text" class="scan-input-field" autocomplete="off" spellcheck="false" placeholder="No inputs" data-property="include"> - <button class="input-suffix input-suffix-icon-button light-icon mouse-button" data-property="include"><span class="icon" data-icon="mouse"></span></button> + <button type="button" class="input-suffix input-suffix-icon-button light-icon mouse-button" data-property="include"><span class="icon" data-icon="mouse"></span></button> </div> <div class="scan-input-prefix-cell" data-property="exclude"><span>Excluded inputs:</span></div> <div class="scan-input-content-cell input-group" data-property="exclude"> <input type="text" class="scan-input-field" autocomplete="off" spellcheck="false" placeholder="No inputs" data-property="exclude"> - <button class="input-suffix input-suffix-icon-button light-icon mouse-button" data-property="exclude"><span class="icon" data-icon="mouse"></span></button> + <button type="button" class="input-suffix input-suffix-icon-button light-icon mouse-button" data-property="exclude"><span class="icon" data-icon="mouse"></span></button> </div> <div class="scan-input-prefix-cell scan-input-options-cell" data-property="types"><span>Input types:</span></div> @@ -3078,10 +3078,10 @@ </div></template> <template id="scanning-inputs-menu-template"><div class="popup-menu-container" tabindex="-1" role="dialog"><div class="popup-menu"><div class="popup-menu-body"> - <button class="popup-menu-item" data-menu-action="showAdvanced">Show advanced options</button> - <button class="popup-menu-item" data-menu-action="hideAdvanced">Hide advanced options</button> - <button class="popup-menu-item" data-menu-action="clearInputs">Clear inputs</button> - <button class="popup-menu-item" data-menu-action="remove">Remove</button> + <button type="button" class="popup-menu-item" data-menu-action="showAdvanced">Show advanced options</button> + <button type="button" class="popup-menu-item" data-menu-action="hideAdvanced">Hide advanced options</button> + <button type="button" class="popup-menu-item" data-menu-action="clearInputs">Clear inputs</button> + <button type="button" class="popup-menu-item" data-menu-action="remove">Remove</button> </div></div></div></template> @@ -3123,7 +3123,7 @@ </div> </div> <div class="modal-footer"> - <button data-modal-action="hide">Close</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -3134,8 +3134,8 @@ <div class="modal-title">Anki Cards</div> <div class="modal-header-button-container"> <div class="modal-header-button-group"> - <button class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> - <button class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> </div> </div> </div> @@ -3152,7 +3152,7 @@ </label> </div> <div class="tabs-right" hidden> - <button class="icon-button" data-menu-position="below left" id="anki-card-primary-type-menu-button"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> + <button type="button" class="icon-button" data-menu-position="below left" id="anki-card-primary-type-menu-button"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> </div> </div> <div class="modal-separator-line"></div> @@ -3180,8 +3180,8 @@ </div> </div> <div class="modal-footer"> - <button class="low-emphasis" data-modal-action="show,anki-cards-info">Help</button> - <button data-modal-action="hide">Close</button> + <button type="button" class="low-emphasis" data-modal-action="show,anki-cards-info">Help</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -3190,8 +3190,8 @@ <div class="modal-title">Anki Card Information</div> <div class="modal-header-button-container"> <div class="modal-header-button-group"> - <button class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> - <button class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> </div> </div> </div> @@ -3364,7 +3364,7 @@ </table> </div> <div class="modal-footer"> - <button data-modal-action="hide">Close</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -3373,7 +3373,7 @@ <template id="anki-card-field-template"><div class="anki-card-field-name-container"><span class="anki-card-field-name"></span></div> <div class="anki-card-field-value-container input-group"> <input type="text" class="anki-card-field-value" autocomplete="off"> - <button class="anki-card-field-value-menu-button input-suffix input-suffix-icon-button light-icon" data-menu-position="v-center left"><span class="icon" data-icon="material-down-arrow"></span></button> + <button type="button" class="anki-card-field-value-menu-button input-suffix input-suffix-icon-button light-icon" data-menu-position="v-center left"><span class="icon" data-icon="material-down-arrow"></span></button> </div></template> <template id="anki-card-terms-field-menu-template"><div class="popup-menu-container" tabindex="-1" role="dialog"><div class="popup-menu"><div class="popup-menu-body"></div></div></div></template> @@ -3410,16 +3410,16 @@ <input type="text" id="anki-card-templates-test-text-input" class="form-control" value="読め" placeholder="Preview text" autocomplete="off" lang="ja"> <div class="anki-card-templates-test-input-container input-group"> <input type="text" id="anki-card-templates-test-field-input" value="{expression}" placeholder="{marker}" autocomplete="off" spellcheck="false"> - <button class="input-suffix input-suffix-icon-button light-icon" id="anki-card-templates-test-field-menu-button" data-menu="anki-card-all-field-menu" data-menu-position="below left"><span class="icon" data-icon="material-down-arrow"></span></button> + <button type="button" class="input-suffix input-suffix-icon-button light-icon" id="anki-card-templates-test-field-menu-button" data-menu="anki-card-all-field-menu" data-menu-position="below left"><span class="icon" data-icon="material-down-arrow"></span></button> </div> - <button id="anki-card-templates-test-render-button">Test</button> + <button type="button" id="anki-card-templates-test-render-button">Test</button> </div> </div> <div class="code margin-above" id="anki-card-templates-render-result"><em>Card render result</em></div> </div> <div class="modal-footer"> - <button class="danger" id="anki-card-templates-reset-button">Reset Templates</button> - <button data-modal-action="hide">Close</button> + <button type="button" class="danger" id="anki-card-templates-reset-button">Reset Templates</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -3432,8 +3432,8 @@ </p> </div> <div class="modal-footer"> - <button class="low-emphasis" data-modal-action="hide">Cancel</button> - <button class="danger" id="anki-card-templates-reset-button-confirm">Reset Templates</button> + <button type="button" class="low-emphasis" data-modal-action="hide">Cancel</button> + <button type="button" class="danger" id="anki-card-templates-reset-button-confirm">Reset Templates</button> </div> </div></div> @@ -3447,7 +3447,7 @@ <p>Additional info can be found in the developer console.</p> </div> <div class="modal-footer"> - <button class="low-emphasis" data-modal-action="hide">Close</button> + <button type="button" class="low-emphasis" data-modal-action="hide">Close</button> </div> </div></div> @@ -3461,9 +3461,9 @@ <ul class="danger-text" id="settings-import-warning-message"></ul> </div> <div class="modal-footer"> - <button class="low-emphasis" data-modal-action="hide">Cancel</button> - <button class="danger settings-import-warning-import-button">Import</button> - <button class="settings-import-warning-import-button" data-import-sanitize="true">Sanitize and Import</button> + <button type="button" class="low-emphasis" data-modal-action="hide">Cancel</button> + <button type="button" class="danger settings-import-warning-import-button">Import</button> + <button type="button" class="settings-import-warning-import-button" data-import-sanitize="true">Sanitize and Import</button> </div> </div></div> @@ -3485,8 +3485,8 @@ </p> </div> <div class="modal-footer"> - <button class="low-emphasis" data-modal-action="hide">Cancel</button> - <button class="danger" id="settings-reset-confirm-button">Reset All Settings</button> + <button type="button" class="low-emphasis" data-modal-action="hide">Cancel</button> + <button type="button" class="danger" id="settings-reset-confirm-button">Reset All Settings</button> </div> </div></div> @@ -3497,8 +3497,8 @@ <div class="modal-title">Custom Text Replacement Patterns</div> <div class="modal-header-button-container"> <div class="modal-header-button-group"> - <button class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> - <button class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> </div> </div> </div> @@ -3536,8 +3536,8 @@ </div> </div> <div class="modal-footer"> - <button id="translation-text-replacement-add" class="low-emphasis">Add</button> - <button data-modal-action="hide">Close</button> + <button type="button" id="translation-text-replacement-add" class="low-emphasis">Add</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -3557,7 +3557,7 @@ <div class="translation-text-replacement-replacement-container"> <input type="text" class="translation-text-replacement-replacement code"> </div> - <button class="icon-button translation-text-replacement-button" data-menu="translation-text-replacement-entry-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> + <button type="button" class="icon-button translation-text-replacement-button" data-menu="translation-text-replacement-entry-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> <div class="translation-text-replacement-test-label translation-text-replacement-test-node">Test Input:</div> <div class="translation-text-replacement-test-container translation-text-replacement-test-node"> @@ -3568,9 +3568,9 @@ </div></template> <template id="translation-text-replacement-entry-menu-template"><div class="popup-menu-container" tabindex="-1" role="dialog"><div class="popup-menu"><div class="popup-menu-body"> - <button class="popup-menu-item" data-menu-action="showTest">Test</button> - <button class="popup-menu-item" data-menu-action="hideTest">Hide test</button> - <button class="popup-menu-item" data-menu-action="remove">Remove</button> + <button type="button" class="popup-menu-item" data-menu-action="showTest">Test</button> + <button type="button" class="popup-menu-item" data-menu-action="hideTest">Hide test</button> + <button type="button" class="popup-menu-item" data-menu-action="remove">Remove</button> </div></div></div></template> @@ -3580,8 +3580,8 @@ <div class="modal-title">Sentence Termination Characters</div> <div class="modal-header-button-container"> <div class="modal-header-button-group"> - <button class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> - <button class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> </div> </div> </div> @@ -3606,9 +3606,9 @@ </div> </div> <div class="modal-footer"> - <button class="low-emphasis danger" id="sentence-termination-character-list-reset">Reset</button> - <button class="low-emphasis" id="sentence-termination-character-list-add">Add</button> - <button data-modal-action="hide">Close</button> + <button type="button" class="low-emphasis danger" id="sentence-termination-character-list-reset">Reset</button> + <button type="button" class="low-emphasis" id="sentence-termination-character-list-add">Add</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -3645,12 +3645,12 @@ </div> </td> <td> - <button class="icon-button sentence-termination-character-entry-button" data-menu="sentence-termination-character-entry-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> + <button type="button" class="icon-button sentence-termination-character-entry-button" data-menu="sentence-termination-character-entry-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> </td> </tr></template> <template id="sentence-termination-character-entry-menu-template"><div class="popup-menu-container" tabindex="-1" role="dialog"><div class="popup-menu"><div class="popup-menu-body"> - <button class="popup-menu-item" data-menu-action="delete">Delete</button> + <button type="button" class="popup-menu-item" data-menu-action="delete">Delete</button> </div></div></div></template> @@ -3660,8 +3660,8 @@ <div class="modal-title">Keyboard Shortcuts</div> <div class="modal-header-button-container"> <div class="modal-header-button-group"> - <button class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> - <button class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> </div> </div> </div> @@ -3672,9 +3672,9 @@ </div> </div> <div class="modal-footer"> - <button class="low-emphasis danger" data-modal-action="show,keyboard-shortcuts-reset">Reset</button> - <button class="low-emphasis" id="hotkey-list-add">Add</button> - <button data-modal-action="hide">Close</button> + <button type="button" class="low-emphasis danger" data-modal-action="show,keyboard-shortcuts-reset">Reset</button> + <button type="button" class="low-emphasis" id="hotkey-list-add">Add</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -3683,8 +3683,8 @@ <div class="modal-title">Native Keyboard Shortcuts</div> <div class="modal-header-button-container"> <div class="modal-header-button-group"> - <button class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> - <button class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> </div> </div> </div> @@ -3721,9 +3721,9 @@ <div class="modal-settings-group" id="extension-hotkey-list"></div> </div> <div class="modal-footer"> - <button class="low-emphasis danger" id="extension-hotkey-list-reset-all">Reset All</button> - <button class="low-emphasis danger" id="extension-hotkey-list-clear-all">Clear All</button> - <button data-modal-action="hide">Close</button> + <button type="button" class="low-emphasis danger" id="extension-hotkey-list-reset-all">Reset All</button> + <button type="button" class="low-emphasis danger" id="extension-hotkey-list-clear-all">Clear All</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -3733,8 +3733,8 @@ Are you sure you want to reset all keyboard shortcuts to their defaults? </div> <div class="modal-footer"> - <button class="low-emphasis" data-modal-action="hide">Cancel</button> - <button class="danger" id="hotkey-list-reset" data-modal-action="hide">Reset All</button> + <button type="button" class="low-emphasis" data-modal-action="hide">Cancel</button> + <button type="button" class="danger" id="hotkey-list-reset" data-modal-action="hide">Reset All</button> </div> </div></div> @@ -3743,7 +3743,7 @@ <div class="hotkey-list-item-index-cell generic-list-index-prefix"></div> <div class="hotkey-list-item-button-cell"> <div class="input-height-icon-button-container"> - <button class="icon-button hotkey-list-item-button" data-menu="hotkey-list-item-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> + <button type="button" class="icon-button hotkey-list-item-button" data-menu="hotkey-list-item-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> </div> </div> @@ -3751,13 +3751,13 @@ <div class="hotkey-list-item-input-cell"> <input type="text" class="hotkey-list-item-input" autocomplete="off" spellcheck="false" placeholder="No input" data-property="include"> <div class="hotkey-list-item-enabled-button-container input-group"> - <button class="hotkey-list-item-enabled-button input-button"> + <button type="button" class="hotkey-list-item-enabled-button input-button"> <label class="hotkey-list-item-enabled-button-label button-inner-label"> <span class="checkbox"><input type="checkbox" class="hotkey-list-item-enabled"><span class="checkbox-body"><span class="checkbox-fill"></span><span class="checkbox-border"></span><span class="checkbox-check"></span></span></span> <span>Enabled</span> </label> </button> - <button class="hotkey-list-item-scopes-button input-suffix input-suffix-icon-button light-icon" data-menu="hotkey-list-item-scopes-menu" data-menu-position="below left"><span class="icon" data-icon="material-down-arrow"></span></button> + <button type="button" class="hotkey-list-item-scopes-button input-suffix input-suffix-icon-button light-icon" data-menu="hotkey-list-item-scopes-menu" data-menu-position="below left"><span class="icon" data-icon="material-down-arrow"></span></button> </div> </div> @@ -3797,36 +3797,36 @@ <div class="settings-item-right"> <div class="flex-row-nowrap"> <input type="text"> - <button class="icon-button extension-hotkey-list-item-button" data-menu="extension-hotkey-list-item-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> + <button type="button" class="icon-button extension-hotkey-list-item-button" data-menu="extension-hotkey-list-item-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> </div> </div> </div></div></template> <template id="hotkey-list-item-menu-template"><div class="popup-menu-container" tabindex="-1" role="dialog"><div class="popup-menu"><div class="popup-menu-body"> - <button class="popup-menu-item" data-menu-action="clearInputs">Clear input</button> - <button class="popup-menu-item" data-menu-action="resetInput">Reset input</button> - <button class="popup-menu-item" data-menu-action="resetArgument">Reset argument</button> - <button class="popup-menu-item" data-menu-action="delete">Delete</button> + <button type="button" class="popup-menu-item" data-menu-action="clearInputs">Clear input</button> + <button type="button" class="popup-menu-item" data-menu-action="resetInput">Reset input</button> + <button type="button" class="popup-menu-item" data-menu-action="resetArgument">Reset argument</button> + <button type="button" class="popup-menu-item" data-menu-action="delete">Delete</button> </div></div></div></template> <template id="hotkey-list-item-scopes-menu-template"><div class="popup-menu-container" tabindex="-1" role="dialog"><div class="popup-menu"><div class="popup-menu-body"> - <button class="popup-menu-item hotkey-scope-popup-menu-item" data-menu-action="toggleScope" data-scope="web"><label class="hotkey-scope-popup-menu-item-label button-inner-label"> + <button type="button" class="popup-menu-item hotkey-scope-popup-menu-item" data-menu-action="toggleScope" data-scope="web"><label class="hotkey-scope-popup-menu-item-label button-inner-label"> <label class="checkbox"><input type="checkbox" class="hotkey-scope-checkbox" data-scope="web"><span class="checkbox-body"><span class="checkbox-fill"></span><span class="checkbox-border"></span><span class="checkbox-check"></span></span></label> <span>Web</span> </label></button> - <button class="popup-menu-item hotkey-scope-popup-menu-item" data-menu-action="toggleScope" data-scope="popup"><label class="hotkey-scope-popup-menu-item-label button-inner-label"> + <button type="button" class="popup-menu-item hotkey-scope-popup-menu-item" data-menu-action="toggleScope" data-scope="popup"><label class="hotkey-scope-popup-menu-item-label button-inner-label"> <label class="checkbox"><input type="checkbox" class="hotkey-scope-checkbox" data-scope="popup"><span class="checkbox-body"><span class="checkbox-fill"></span><span class="checkbox-border"></span><span class="checkbox-check"></span></span></label> <span>Popup</span> </label></button> - <button class="popup-menu-item hotkey-scope-popup-menu-item" data-menu-action="toggleScope" data-scope="search"><label class="hotkey-scope-popup-menu-item-label button-inner-label"> + <button type="button" class="popup-menu-item hotkey-scope-popup-menu-item" data-menu-action="toggleScope" data-scope="search"><label class="hotkey-scope-popup-menu-item-label button-inner-label"> <label class="checkbox"><input type="checkbox" class="hotkey-scope-checkbox" data-scope="search"><span class="checkbox-body"><span class="checkbox-fill"></span><span class="checkbox-border"></span><span class="checkbox-check"></span></span></label> <span>Search</span> </label></button> </div></div></div></template> <template id="extension-hotkey-list-item-menu-template"><div class="popup-menu-container" tabindex="-1" role="dialog"><div class="popup-menu"><div class="popup-menu-body"> - <button class="popup-menu-item" data-menu-action="clearInput">Clear input</button> - <button class="popup-menu-item" data-menu-action="resetInput">Reset input</button> + <button type="button" class="popup-menu-item" data-menu-action="clearInput">Clear input</button> + <button type="button" class="popup-menu-item" data-menu-action="resetInput">Reset input</button> </div></div></div></template> <template id="hotkey-argument-move-offset-template"><div class="flex-row-nowrap"> @@ -3855,10 +3855,7 @@ <!-- Scripts --> <script src="/lib/dexie.min.js"></script> -<!-- The linter enforces a lexicographical order for each 'group' of imported scripts as demarked by newline between groups - but this extension to dexie must be loaded after the main dexie library, hence breaking it out into its own group. - Perhaps The linter could be smarter and ignore 3p libaries for import order. --> -<script src="/lib/dexie-export-import.min.js"></script> +<script src="/lib/dexie-export-import.js"></script> <script src="/lib/wanakana.min.js"></script> diff --git a/ext/welcome.html b/ext/welcome.html index 8a01d06f..14e98367 100644 --- a/ext/welcome.html +++ b/ext/welcome.html @@ -60,7 +60,7 @@ <div class="settings-item-label">Install or remove dictionaries…</div> </div> <div class="settings-item-right open-panel-button-container"> - <button class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> + <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> </div> </div></div> </div> @@ -195,7 +195,7 @@ <div class="settings-item-label">More customization options are available on the Settings page</div> </div> <div class="settings-item-right open-panel-button-container"> - <button class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> + <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> </div> </div></a> </div> @@ -231,8 +231,8 @@ <div class="modal-title">Dictionaries</div> <div class="modal-header-button-container"> <div class="modal-header-button-group"> - <button class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> - <button class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="expand"><span class="icon-button-inner"><span class="icon" data-icon="expand"></span></span></button> + <button type="button" class="icon-button modal-header-button" data-modal-action="collapse"><span class="icon-button-inner"><span class="icon" data-icon="collapse"></span></span></button> </div> </div> </div> @@ -290,9 +290,9 @@ <div class="progress-bar-track"><div class="progress-bar"></div></div> </div> <div class="modal-footer"> - <button class="low-emphasis danger dictionary-database-mutating-input" id="dictionary-delete-all-button">Delete All</button> - <button class="low-emphasis dictionary-database-mutating-input" id="dictionary-import-file-button">Import</button> - <button data-modal-action="hide">Close</button> + <button type="button" class="low-emphasis danger dictionary-database-mutating-input" id="dictionary-delete-all-button">Delete All</button> + <button type="button" class="low-emphasis dictionary-database-mutating-input" id="dictionary-import-file-button">Import</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -304,8 +304,8 @@ <p class="danger-text">This action cannot be undone.</p> </div> <div class="modal-footer"> - <button class="low-emphasis" data-modal-action="hide">Cancel</button> - <button class="danger" data-modal-action="hide" id="dictionary-confirm-delete-button">Delete</button> + <button type="button" class="low-emphasis" data-modal-action="hide">Cancel</button> + <button type="button" class="danger" data-modal-action="hide" id="dictionary-confirm-delete-button">Delete</button> </div> </div></div> @@ -316,8 +316,8 @@ <p class="danger-text">This action cannot be undone.</p> </div> <div class="modal-footer"> - <button class="low-emphasis" data-modal-action="hide">Cancel</button> - <button class="danger" data-modal-action="hide" id="dictionary-confirm-delete-all-button">Delete</button> + <button type="button" class="low-emphasis" data-modal-action="hide">Cancel</button> + <button type="button" class="danger" data-modal-action="hide" id="dictionary-confirm-delete-all-button">Delete</button> </div> </div></div> @@ -355,7 +355,7 @@ </div></div> </div> <div class="modal-footer"> - <button data-modal-action="hide">Close</button> + <button type="button" data-modal-action="hide">Close</button> </div> </div></div> @@ -368,8 +368,8 @@ </div> </div> <div class="modal-footer"> - <button class="low-emphasis" data-modal-action="hide">Cancel</button> - <button data-modal-action="hide" id="dictionary-move-button">Move</button> + <button type="button" class="low-emphasis" data-modal-action="hide">Cancel</button> + <button type="button" data-modal-action="hide" id="dictionary-move-button">Move</button> </div> </div></div> @@ -382,15 +382,15 @@ <span> <strong class="dictionary-title"></strong> <span class="light dictionary-version"></span> </span> - <button class="dictionary-outdated-button" hidden> + <button type="button" class="dictionary-outdated-button" hidden> <div class="badge warning-badge"><span class="icon" data-icon="exclamation-point-short"></span></div> </button> - <button class="dictionary-integrity-button" hidden> + <button type="button" class="dictionary-integrity-button" hidden> <div class="badge info-badge badge-small-icon"><span class="icon" data-icon="checkmark"></span></div> </button> </div> <input type="number" step="1" class="short-height dictionary-priority"> - <button class="icon-button dictionary-menu-button" data-menu="dictionary-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> + <button type="button" class="icon-button dictionary-menu-button" data-menu="dictionary-menu" data-menu-position="below left"><span class="icon-button-inner"><span class="icon" data-icon="kebab-menu"></span></span></button> </template> <template id="dictionary-details-entry-template"><div class="dictionary-details-entry"> @@ -399,11 +399,11 @@ </div></template> <template id="dictionary-menu-template"><div class="popup-menu-container" tabindex="-1" role="dialog"><div class="popup-menu"><div class="popup-menu-body"> - <button class="popup-menu-item" data-menu-action="showDetails">Details…</button> - <button class="popup-menu-item" data-menu-action="moveUp">Move up</button> - <button class="popup-menu-item" data-menu-action="moveDown">Move down</button> - <button class="popup-menu-item" data-menu-action="moveTo">Move to…</button> - <button class="popup-menu-item" data-menu-action="delete">Delete</button> + <button type="button" class="popup-menu-item" data-menu-action="showDetails">Details…</button> + <button type="button" class="popup-menu-item" data-menu-action="moveUp">Move up</button> + <button type="button" class="popup-menu-item" data-menu-action="moveDown">Move down</button> + <button type="button" class="popup-menu-item" data-menu-action="moveTo">Move to…</button> + <button type="button" class="popup-menu-item" data-menu-action="delete">Delete</button> </div></div></div></template> |