aboutsummaryrefslogtreecommitdiff
path: root/types
diff options
context:
space:
mode:
Diffstat (limited to 'types')
-rw-r--r--types/dev/dictionary-validate.d.ts31
-rw-r--r--types/dev/manifest.d.ts114
-rw-r--r--types/dev/schema-validate.d.ts24
-rw-r--r--types/dev/vm.d.ts38
-rw-r--r--types/ext/anki-controller.d.ts27
-rw-r--r--types/ext/anki-note-builder.d.ts120
-rw-r--r--types/ext/anki-template-renderer-content-manager.d.ts28
-rw-r--r--types/ext/anki-templates-internal.d.ts60
-rw-r--r--types/ext/anki-templates.d.ts270
-rw-r--r--types/ext/anki.d.ts75
-rw-r--r--types/ext/api.d.ts472
-rw-r--r--types/ext/audio-controller.d.ts24
-rw-r--r--types/ext/audio-downloader.d.ts44
-rw-r--r--types/ext/audio-system.d.ts18
-rw-r--r--types/ext/audio.d.ts20
-rw-r--r--types/ext/backend.d.ts90
-rw-r--r--types/ext/backup-controller.d.ts35
-rw-r--r--types/ext/cache-map.d.ts23
-rw-r--r--types/ext/clipboard-monitor.d.ts26
-rw-r--r--types/ext/core.d.ts104
-rw-r--r--types/ext/cross-frame-api.d.ts54
-rw-r--r--types/ext/css-style-applier.d.ts46
-rw-r--r--types/ext/database.d.ts38
-rw-r--r--types/ext/deinflector.d.ts41
-rw-r--r--types/ext/dictionary-data-util.d.ts94
-rw-r--r--types/ext/dictionary-data.d.ts147
-rw-r--r--types/ext/dictionary-database.d.ts241
-rw-r--r--types/ext/dictionary-importer-media-loader.d.ts36
-rw-r--r--types/ext/dictionary-importer.d.ts120
-rw-r--r--types/ext/dictionary-worker-handler.d.ts62
-rw-r--r--types/ext/dictionary-worker-media-loader.d.ts26
-rw-r--r--types/ext/dictionary-worker.d.ts73
-rw-r--r--types/ext/dictionary.d.ts477
-rw-r--r--types/ext/display-anki.d.ts58
-rw-r--r--types/ext/display-audio.d.ts100
-rw-r--r--types/ext/display-content-manager.d.ts40
-rw-r--r--types/ext/display-history.d.ts37
-rw-r--r--types/ext/display.d.ts206
-rw-r--r--types/ext/document-util.d.ts55
-rw-r--r--types/ext/dom-data-binder.d.ts98
-rw-r--r--types/ext/dynamic-loader.d.ts20
-rw-r--r--types/ext/dynamic-property.d.ts22
-rw-r--r--types/ext/environment.d.ts25
-rw-r--r--types/ext/event-listener-collection.d.ts76
-rw-r--r--types/ext/extension.d.ts74
-rw-r--r--types/ext/frame-ancestry-handler.d.ts26
-rw-r--r--types/ext/frame-client.d.ts35
-rw-r--r--types/ext/frame-offset-forwarder.d.ts23
-rw-r--r--types/ext/frontend.d.ts61
-rw-r--r--types/ext/generic-setting-controller.d.ts101
-rw-r--r--types/ext/hotkey-handler.d.ts30
-rw-r--r--types/ext/input.d.ts21
-rw-r--r--types/ext/japanese-util.d.ts42
-rw-r--r--types/ext/json-schema.d.ts75
-rw-r--r--types/ext/keyboard-mouse-input-field.d.ts25
-rw-r--r--types/ext/keyboard-shortcut-controller.d.ts26
-rw-r--r--types/ext/log.d.ts24
-rw-r--r--types/ext/mecab.d.ts46
-rw-r--r--types/ext/offscreen.d.ts113
-rw-r--r--types/ext/options-util.d.ts35
-rw-r--r--types/ext/panel-element.d.ts39
-rw-r--r--types/ext/popup-factory.d.ts32
-rw-r--r--types/ext/popup-menu.d.ts41
-rw-r--r--types/ext/popup.d.ts136
-rw-r--r--types/ext/profile-conditions-ui.d.ts70
-rw-r--r--types/ext/profile-conditions-util.d.ts38
-rw-r--r--types/ext/request-builder.d.ts18
-rw-r--r--types/ext/script-manager.d.ts56
-rw-r--r--types/ext/selector-observer.d.ts55
-rw-r--r--types/ext/settings-controller.d.ts54
-rw-r--r--types/ext/settings-modifications.d.ts97
-rw-r--r--types/ext/settings.d.ts380
-rw-r--r--types/ext/simple-dom-parser.d.ts37
-rw-r--r--types/ext/structured-content.d.ts205
-rw-r--r--types/ext/task-accumulator.d.ts21
-rw-r--r--types/ext/template-patcher.d.ts24
-rw-r--r--types/ext/template-renderer-frame-api.d.ts24
-rw-r--r--types/ext/template-renderer.d.ts75
-rw-r--r--types/ext/text-scanner.d.ts186
-rw-r--r--types/ext/text-source.d.ts21
-rw-r--r--types/ext/translation-internal.d.ts65
-rw-r--r--types/ext/translation.d.ts171
-rw-r--r--types/ext/translator.d.ts97
-rw-r--r--types/other/globals.d.ts22
-rw-r--r--types/other/rollup-parse-ast.d.ts25
-rw-r--r--types/test/document-types.d.ts18
86 files changed, 6599 insertions, 0 deletions
diff --git a/types/dev/dictionary-validate.d.ts b/types/dev/dictionary-validate.d.ts
new file mode 100644
index 00000000..c39f4335
--- /dev/null
+++ b/types/dev/dictionary-validate.d.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as SchemaValidate from './schema-validate';
+
+export type Schema = SchemaValidate.Schema;
+
+export type Schemas = {
+ index: Schema;
+ kanjiBankV1: Schema;
+ kanjiBankV3: Schema;
+ kanjiMetaBankV3: Schema;
+ tagBankV3: Schema;
+ termBankV1: Schema;
+ termBankV3: Schema;
+ termMetaBankV3: Schema;
+};
diff --git a/types/dev/manifest.d.ts b/types/dev/manifest.d.ts
new file mode 100644
index 00000000..e455208f
--- /dev/null
+++ b/types/dev/manifest.d.ts
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type Manifest = chrome.runtime.Manifest;
+
+export type ManifestConfig = {
+ manifest: Manifest;
+ defaultVariant: string;
+ variants: ManifestVariant[];
+};
+
+export type ManifestVariant = {
+ name: string;
+ buildable?: boolean;
+ inherit?: string;
+ fileName?: string;
+ fileCopies?: string[];
+ excludeFiles?: string[];
+ modifications: Modification[];
+};
+
+export type Modification = (
+ ModificationReplace |
+ ModificationDelete |
+ ModificationSet |
+ ModificationAdd |
+ ModificationRemove |
+ ModificationSplice |
+ ModificationCopy |
+ ModificationMove
+);
+
+export type ModificationReplace = {
+ action: 'replace';
+ path: PropertyPath;
+ pattern: string;
+ patternFlags: string;
+ replacement: string;
+};
+
+export type ModificationDelete = {
+ action: 'delete';
+ path: PropertyPath;
+};
+
+export type ModificationSet = {
+ action: 'set';
+ path: PropertyPath;
+ value: unknown;
+ before?: string;
+ after?: string;
+ index?: number;
+ command?: Command;
+};
+
+export type ModificationAdd = {
+ action: 'add';
+ path: PropertyPath;
+ items: unknown[];
+};
+
+export type ModificationRemove = {
+ action: 'remove';
+ path: PropertyPath;
+ item: unknown;
+};
+
+export type ModificationSplice = {
+ action: 'splice';
+ path: PropertyPath;
+ start: number;
+ deleteCount: number;
+ items: unknown[];
+};
+
+export type ModificationCopy = {
+ action: 'copy';
+ path: PropertyPath;
+ newPath: PropertyPath;
+ before?: string;
+ after?: string;
+ index?: number;
+};
+
+export type ModificationMove = {
+ action: 'move';
+ path: PropertyPath;
+ newPath: PropertyPath;
+ before?: string;
+ after?: string;
+ index?: number;
+};
+
+export type PropertyPath = (string | number)[];
+
+export type Command = {
+ command: string;
+ args: string[];
+ trim: boolean;
+};
diff --git a/types/dev/schema-validate.d.ts b/types/dev/schema-validate.d.ts
new file mode 100644
index 00000000..b30c8a04
--- /dev/null
+++ b/types/dev/schema-validate.d.ts
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as AjvModule from 'ajv';
+
+export type ValidateMode = 'ajv' | null;
+
+export type Schema = unknown;
+
+export type Ajv = typeof AjvModule.default;
diff --git a/types/dev/vm.d.ts b/types/dev/vm.d.ts
new file mode 100644
index 00000000..3eb0949f
--- /dev/null
+++ b/types/dev/vm.d.ts
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Translation from '../ext/translation';
+
+export type PseudoChrome = {
+ runtime: {
+ getURL(path: string): string;
+ };
+};
+
+export type PseudoFetchResponse = {
+ ok: boolean;
+ status: number;
+ statusText: string;
+ text(): Promise<string>;
+ json(): Promise<unknown>;
+};
+
+export type OptionsPresetObject = {
+ [key: string]: OptionsPreset;
+};
+
+export type OptionsPreset = Partial<Translation.FindTermsOptions>;
diff --git a/types/ext/anki-controller.d.ts b/types/ext/anki-controller.d.ts
new file mode 100644
index 00000000..f9a3d646
--- /dev/null
+++ b/types/ext/anki-controller.d.ts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type AnkiData = {
+ deckNames: string[];
+ modelNames: string[];
+};
+
+export type FieldEntry = {
+ fieldName: string;
+ inputField: HTMLInputElement;
+ fieldNameContainerNode: HTMLElement;
+};
diff --git a/types/ext/anki-note-builder.d.ts b/types/ext/anki-note-builder.d.ts
new file mode 100644
index 00000000..fbcb9328
--- /dev/null
+++ b/types/ext/anki-note-builder.d.ts
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Anki from './anki';
+import type * as AnkiTemplates from './anki-templates';
+import type * as AnkiTemplatesInternal from './anki-templates-internal';
+import type * as Audio from './audio';
+import type * as Dictionary from './dictionary';
+import type * as Extension from './extension';
+import type * as Settings from './settings';
+import type * as TemplateRenderer from './template-renderer';
+
+export type CreateNoteDetails = {
+ dictionaryEntry: Dictionary.DictionaryEntry;
+ mode: AnkiTemplatesInternal.CreateMode;
+ context: AnkiTemplatesInternal.Context;
+ template: string;
+ deckName: string;
+ modelName: string;
+ fields: Field[];
+ tags: string[];
+ requirements: Requirement[];
+ checkForDuplicates: boolean;
+ duplicateScope: Settings.AnkiDuplicateScope;
+ duplicateScopeCheckAllModels: boolean;
+ resultOutputMode: Settings.ResultOutputMode;
+ glossaryLayoutMode: Settings.GlossaryLayoutMode;
+ compactTags: boolean;
+ mediaOptions: MediaOptions | null;
+};
+
+export type Field = [
+ name: string,
+ value: string,
+];
+
+export type CreateNoteResult = {
+ note: Anki.Note;
+ errors: Error[];
+ requirements: Requirement[];
+};
+
+export type GetRenderingDataDetails = {
+ dictionaryEntry: Dictionary.DictionaryEntry;
+ mode: AnkiTemplatesInternal.CreateMode;
+ context: AnkiTemplatesInternal.Context;
+ resultOutputMode?: Settings.ResultOutputMode;
+ glossaryLayoutMode?: Settings.GlossaryLayoutMode;
+ compactTags?: boolean;
+ marker: string;
+};
+
+export type CommonData = AnkiTemplatesInternal.CreateDetails;
+
+export type RequirementGeneric = {
+ type: 'audio' | 'screenshot' | 'clipboardImage' | 'clipboardText' | 'selectionText';
+};
+
+export type RequirementTextFurigana = {
+ type: 'textFurigana';
+ text: string;
+ readingMode: AnkiTemplates.TextFuriganaReadingMode;
+};
+
+export type RequirementDictionaryMedia = {
+ type: 'dictionaryMedia';
+ dictionary: string;
+ path: string;
+};
+
+export type Requirement = RequirementGeneric | RequirementTextFurigana | RequirementDictionaryMedia;
+
+export type AudioMediaOptions = {
+ sources: Audio.AudioSourceInfo[];
+ preferredAudioIndex: number | null;
+ idleTimeout: number | null;
+};
+
+export type MediaOptions = {
+ audio: AudioMediaOptions | null;
+ screenshot: {
+ format: Settings.AnkiScreenshotFormat;
+ quality: number;
+ contentOrigin: Extension.ContentOrigin;
+ };
+ textParsing: {
+ optionsContext: Settings.OptionsContext;
+ scanLength: number;
+ };
+};
+
+export type TextFuriganaDetails = {
+ text: string;
+ readingMode: AnkiTemplates.TextFuriganaReadingMode;
+};
+
+export type BatchedRequestGroup = {
+ template: string;
+ commonDataRequestsMap: Map<CommonData, BatchedRequestData[]>;
+};
+
+export type BatchedRequestData = {
+ resolve: (result: TemplateRenderer.RenderResult) => void;
+ reject: (reason?: unknown) => void;
+ marker: string;
+};
diff --git a/types/ext/anki-template-renderer-content-manager.d.ts b/types/ext/anki-template-renderer-content-manager.d.ts
new file mode 100644
index 00000000..d7667ae2
--- /dev/null
+++ b/types/ext/anki-template-renderer-content-manager.d.ts
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/** A callback used when a media file has been loaded. */
+export type OnLoadCallback = (
+ /** The URL of the media that was loaded. */
+ url: string,
+) => void;
+
+/** A callback used when a media file should be unloaded. */
+export type OnUnloadCallback = (
+ /** Whether or not the media was fully loaded. */
+ fullyLoaded: boolean,
+) => void;
diff --git a/types/ext/anki-templates-internal.d.ts b/types/ext/anki-templates-internal.d.ts
new file mode 100644
index 00000000..4cb50050
--- /dev/null
+++ b/types/ext/anki-templates-internal.d.ts
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as AnkiTemplates from './anki-templates';
+import type * as Dictionary from './dictionary';
+import type * as Settings from './settings';
+
+export type Context = {
+ url: string;
+ documentTitle: string;
+ query: string;
+ fullQuery: string;
+ sentence: ContextSentence;
+};
+
+export type ContextSentence = {
+ text?: string;
+ offset?: number;
+};
+
+export type CreateModeNoTest = 'kanji' | 'term-kanji' | 'term-kana';
+
+export type CreateMode = CreateModeNoTest | 'test';
+
+export type CreateDetails = {
+ /** The dictionary entry. */
+ dictionaryEntry: Dictionary.DictionaryEntry;
+ /** The result output mode. */
+ resultOutputMode: Settings.ResultOutputMode;
+ /** The mode being used to generate the Anki data. */
+ mode: CreateMode;
+ /** The glossary layout mode. */
+ glossaryLayoutMode: Settings.GlossaryLayoutMode;
+ /** Whether or not compact tags mode is enabled. */
+ compactTags: boolean;
+ /** Contextual information about the source of the dictionary entry. */
+ context: Context;
+ /** Media data. */
+ media?: AnkiTemplates.Media;
+};
+
+export type CachedValue<T> = {
+ getter: () => T;
+ hasValue: boolean;
+ value: T | undefined;
+};
diff --git a/types/ext/anki-templates.d.ts b/types/ext/anki-templates.d.ts
new file mode 100644
index 00000000..5c40f406
--- /dev/null
+++ b/types/ext/anki-templates.d.ts
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Dictionary from './dictionary';
+import type * as DictionaryData from './dictionary-data';
+import type * as DictionaryDataUtil from './dictionary-data-util';
+
+export type RenderMode = 'ankiNote';
+
+export type Context = {
+ query: string;
+ fullQuery: string;
+ document: {title: string};
+};
+
+export type Media = {
+ audio?: MediaObject;
+ screenshot?: MediaObject;
+ clipboardImage?: MediaObject;
+ clipboardText?: MediaObject;
+ selectionText?: MediaObject;
+ textFurigana?: TextFuriganaSegment[];
+ dictionaryMedia?: DictionaryMedia;
+};
+
+export type MediaObject = {value: string};
+
+export type MediaSimpleType = (
+ 'audio' |
+ 'screenshot' |
+ 'clipboardImage' |
+ 'clipboardText' |
+ 'selectionText'
+);
+
+export type TextFuriganaSegment = {
+ text: string;
+ readingMode: TextFuriganaReadingMode;
+ details: MediaObject;
+};
+
+export type TextFuriganaReadingMode = 'hiragana' | 'katakana' | null;
+
+export type DictionaryMedia = {
+ [dictionary: string]: {
+ [path: string]: MediaObject;
+ };
+};
+
+export type NoteData = {
+ marker: string;
+ readonly definition: DictionaryEntry;
+ glossaryLayoutMode: string;
+ compactTags: boolean;
+ group: boolean;
+ merge: boolean;
+ modeTermKanji: boolean;
+ modeTermKana: boolean;
+ modeKanji: boolean;
+ compactGlossaries: boolean;
+ readonly uniqueExpressions: string[];
+ readonly uniqueReadings: string[];
+ readonly pitches: PitchGroup[];
+ readonly pitchCount: number;
+ readonly context: Context;
+ media: Media;
+ readonly dictionaryEntry: Dictionary.DictionaryEntry;
+};
+
+export type PitchGroup = {
+ dictionary: string;
+ pitches: Pitch[];
+};
+
+export type Pitch = {
+ expressions: string[];
+ reading: string;
+ position: number;
+ nasalPositions: number[];
+ devoicePositions: number[];
+ tags: PitchTag[];
+ exclusiveExpressions: string[];
+ exclusiveReadings: string[];
+};
+
+/**
+ * For legacy reasons, {@link Pitch} has a custom tag type that resembles {@link Dictionary.Tag}.
+ */
+export type PitchTag = {
+ name: string;
+ category: string;
+ order: number;
+ score: number;
+ content: string[];
+ dictionaries: string[];
+ redundant: boolean;
+};
+
+export type KanjiDictionaryEntry = {
+ type: 'kanji';
+ character: string;
+ dictionary: string;
+ onyomi: string[];
+ kunyomi: string[];
+ glossary: string[];
+ readonly tags: Tag[];
+ readonly stats: KanjiStatGroups;
+ readonly frequencies: KanjiFrequency[];
+ url: string;
+ readonly cloze: Cloze;
+};
+
+export type KanjiStatGroups = {
+ [propName: string]: KanjiStat[];
+};
+
+export type KanjiStat = {
+ name: string;
+ category: string;
+ notes: string;
+ order: number;
+ score: number;
+ dictionary: string;
+ value: number | string;
+};
+
+export type KanjiFrequency = {
+ index: number;
+ dictionary: string;
+ dictionaryOrder: {
+ index: number;
+ priority: number;
+ };
+ character: string;
+ frequency: number | string;
+};
+
+export type TermDictionaryEntryType = 'term' | 'termGrouped' | 'termMerged';
+
+export type TermDictionaryEntry = {
+ type: TermDictionaryEntryType;
+ id?: number;
+ source: string | null;
+ rawSource: string | null;
+ sourceTerm?: string | null;
+ reasons: string[];
+ score: number;
+ isPrimary?: boolean;
+ readonly sequence: number;
+ readonly dictionary: string;
+ dictionaryOrder: {
+ index: number;
+ priority: number;
+ };
+ readonly dictionaryNames: string[];
+ readonly expression: string | string[];
+ readonly reading: string | string[];
+ readonly expressions: TermHeadword[];
+ readonly glossary?: DictionaryData.TermGlossary[];
+ readonly definitionTags?: Tag[];
+ readonly termTags?: Tag[];
+ readonly definitions?: TermDefinition[];
+ readonly frequencies: TermFrequency[];
+ readonly pitches: TermPronunciation[];
+ sourceTermExactMatchCount: number;
+ url: string;
+ readonly cloze: Cloze;
+ readonly furiganaSegments?: FuriganaSegment[];
+};
+
+export type TermDictionaryEntryCommonInfo = {
+ uniqueTerms: string[];
+ uniqueReadings: string[];
+ definitionTags: Tag[];
+ definitions?: TermDefinition[];
+};
+
+export type UnknownDictionaryEntry = Record<string, never>;
+
+export type DictionaryEntry = KanjiDictionaryEntry | TermDictionaryEntry | UnknownDictionaryEntry;
+
+export type Tag = {
+ name: string;
+ category: string;
+ order: number;
+ score: number;
+ notes: string;
+ dictionary: string;
+ redundant: boolean;
+};
+
+export type TermDefinition = {
+ sequence: number;
+ dictionary: string;
+ glossary: DictionaryData.TermGlossary[];
+ definitionTags: Tag[];
+ only?: string[];
+};
+
+export type TermFrequency = {
+ index: number;
+ expressionIndex: number;
+ dictionary: string;
+ dictionaryOrder: {
+ index: number;
+ priority: number;
+ };
+ expression: string;
+ reading: string;
+ hasReading: boolean;
+ frequency: number | string;
+};
+
+export type TermPronunciation = {
+ index: number;
+ expressionIndex: number;
+ dictionary: string;
+ dictionaryOrder: {
+ index: number;
+ priority: number;
+ };
+ expression: string;
+ reading: string;
+ readonly pitches: TermPitch[];
+};
+
+export type TermPitch = {
+ position: number;
+ tags: Tag[];
+};
+
+export type TermFrequencyType = DictionaryDataUtil.TermFrequencyType;
+
+export type TermHeadword = {
+ sourceTerm: string;
+ expression: string;
+ reading: string;
+ readonly termTags: Tag[];
+ readonly frequencies: TermFrequency[];
+ readonly pitches: TermPronunciation[];
+ readonly furiganaSegments: FuriganaSegment[];
+ readonly termFrequency: TermFrequencyType;
+ wordClasses: string[];
+};
+
+export type FuriganaSegment = {
+ text: string;
+ furigana: string;
+};
+
+export type Cloze = {
+ sentence: string;
+ prefix: string;
+ body: string;
+ suffix: string;
+};
diff --git a/types/ext/anki.d.ts b/types/ext/anki.d.ts
new file mode 100644
index 00000000..051cd3e9
--- /dev/null
+++ b/types/ext/anki.d.ts
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Core from './core';
+import type * as Settings from './settings';
+
+export type NoteId = number;
+
+export type CardId = number;
+
+export type Note = {
+ fields: NoteFields;
+ tags: string[];
+ deckName: string;
+ modelName: string;
+ options: {
+ allowDuplicate: boolean;
+ duplicateScope: Settings.AnkiDuplicateScope;
+ duplicateScopeOptions: {
+ deckName: string | null;
+ checkChildren: boolean;
+ checkAllModels: boolean;
+ };
+ };
+};
+
+export type NoteFields = {
+ [field: string]: string;
+};
+
+export type NoteInfoWrapper = {
+ canAdd: boolean;
+ valid: boolean;
+ noteIds: NoteId[] | null;
+ noteInfos?: (NoteInfo | null)[];
+};
+
+export type NoteInfo = {
+ noteId: NoteId;
+ tags: string[];
+ fields: {[key: string]: NoteFieldInfo};
+ modelName: string;
+ cards: CardId[];
+};
+
+export type NoteFieldInfo = {
+ value: string;
+ order: number;
+};
+
+export type ApiReflectResult = {
+ scopes: string[];
+ actions: string[];
+};
+
+export type MessageBody = {
+ action: string;
+ params: Core.SerializableObject;
+ version: number;
+ key?: string;
+};
diff --git a/types/ext/api.d.ts b/types/ext/api.d.ts
new file mode 100644
index 00000000..6b7b4b19
--- /dev/null
+++ b/types/ext/api.d.ts
@@ -0,0 +1,472 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Anki from './anki';
+import type * as AnkiNoteBuilder from './anki-note-builder';
+import type * as Audio from './audio';
+import type * as AudioDownloader from './audio-downloader';
+import type * as Backend from './backend';
+import type * as Core from './core';
+import type * as Dictionary from './dictionary';
+import type * as DictionaryDatabase from './dictionary-database';
+import type * as DictionaryImporter from './dictionary-importer';
+import type * as Environment from './environment';
+import type * as Extension from './extension';
+import type * as Log from './log';
+import type * as Settings from './settings';
+import type * as SettingsModifications from './settings-modifications';
+import type * as Translation from './translation';
+import type * as Translator from './translator';
+
+// Generic
+
+export type Handler<TDetails, TResult, THasSender extends boolean = false> = (
+ details: TDetails,
+ sender: (THasSender extends true ? chrome.runtime.MessageSender : void)
+) => (TResult | Promise<TResult>);
+
+// optionsGet
+
+export type OptionsGetDetails = {
+ optionsContext: Settings.OptionsContext;
+};
+
+export type OptionsGetResult = Settings.ProfileOptions;
+
+// optionsGetFull
+
+export type OptionsGetFullDetails = Record<string, never>;
+
+export type OptionsGetFullResult = Settings.Options;
+
+// termsFind
+
+export type FindTermsDetails = {
+ matchType?: Translation.FindTermsMatchType;
+ deinflect?: boolean;
+};
+
+export type TermsFindDetails = {
+ text: string;
+ details: FindTermsDetails;
+ optionsContext: Settings.OptionsContext;
+};
+
+export type TermsFindResult = {
+ dictionaryEntries: Dictionary.TermDictionaryEntry[];
+ originalTextLength: number;
+};
+
+// parseText
+
+export type ParseTextDetails = {
+ text: string;
+ optionsContext: Settings.OptionsContext;
+ scanLength: number;
+ useInternalParser: boolean;
+ useMecabParser: boolean;
+};
+
+export type ParseTextResult = ParseTextResultItem[];
+
+export type ParseTextResultItem = {
+ id: string;
+ source: 'scanning-parser' | 'mecab';
+ dictionary: null | string;
+ content: ParseTextLine[];
+};
+
+export type ParseTextSegment = {
+ text: string;
+ reading: string;
+};
+
+export type ParseTextLine = ParseTextSegment[];
+
+// kanjiFind
+
+export type KanjiFindDetails = {
+ text: string;
+ optionsContext: Settings.OptionsContext;
+};
+
+export type KanjiFindResult = Dictionary.KanjiDictionaryEntry[];
+
+// isAnkiConnected
+
+export type IsAnkiConnectedDetails = Record<string, never>;
+
+export type IsAnkiConnectedResult = boolean;
+
+// getAnkiConnectVersion
+
+export type GetAnkiConnectVersionDetails = Record<string, never>;
+
+export type GetAnkiConnectVersionResult = number | null;
+
+// addAnkiNote
+
+export type AddAnkiNoteDetails = {
+ note: Anki.Note;
+};
+
+export type AddAnkiNoteResult = Anki.NoteId | null;
+
+// getAnkiNoteInfo
+
+export type GetAnkiNoteInfoDetails = {
+ notes: Anki.Note[];
+ fetchAdditionalInfo: boolean;
+};
+
+export type GetAnkiNoteInfoResult = Anki.NoteInfoWrapper[];
+
+// injectAnkiNoteMedia
+
+export type InjectAnkiNoteMediaDetails = {
+ timestamp: number;
+ definitionDetails: InjectAnkiNoteMediaDefinitionDetails;
+ audioDetails: InjectAnkiNoteMediaAudioDetails | null;
+ screenshotDetails: InjectAnkiNoteMediaScreenshotDetails | null;
+ clipboardDetails: InjectAnkiNoteMediaClipboardDetails | null;
+ dictionaryMediaDetails: InjectAnkiNoteMediaDictionaryMediaDetails[];
+};
+
+export type InjectAnkiNoteMediaTermDefinitionDetails = {
+ type: 'term';
+ term: string;
+ reading: string;
+};
+
+export type InjectAnkiNoteMediaKanjiDefinitionDetails = {
+ type: 'kanji';
+ character: string;
+};
+
+export type InjectAnkiNoteMediaDefinitionDetails = InjectAnkiNoteMediaTermDefinitionDetails | InjectAnkiNoteMediaKanjiDefinitionDetails;
+
+export type InjectAnkiNoteMediaAudioDetails = AnkiNoteBuilder.AudioMediaOptions;
+
+export type InjectAnkiNoteMediaScreenshotDetails = {
+ tabId: number;
+ frameId: number;
+ format: Settings.AnkiScreenshotFormat;
+ quality: number;
+};
+
+export type InjectAnkiNoteMediaClipboardDetails = {
+ image: boolean;
+ text: boolean;
+};
+
+export type InjectAnkiNoteMediaDictionaryMediaDetails = {
+ dictionary: string;
+ path: string;
+};
+
+export type InjectAnkiNoteMediaResult = {
+ screenshotFileName: string | null;
+ clipboardImageFileName: string | null;
+ clipboardText: string | null;
+ audioFileName: string | null;
+ dictionaryMedia: InjectAnkiNoteDictionaryMediaResult[];
+ errors: Core.SerializedError[];
+};
+
+export type InjectAnkiNoteDictionaryMediaResult = {
+ dictionary: string;
+ path: string;
+ fileName: string | null;
+};
+
+// noteView
+
+export type NoteViewDetails = {
+ noteId: Anki.NoteId;
+ mode: Settings.AnkiNoteGuiMode;
+ allowFallback: boolean;
+};
+
+export type NoteViewResult = Settings.AnkiNoteGuiMode;
+
+// suspendAnkiCardsForNote
+
+export type SuspendAnkiCardsForNoteDetails = {
+ noteId: Anki.NoteId;
+};
+
+export type SuspendAnkiCardsForNoteResult = number;
+
+// getTermAudioInfoList
+
+export type GetTermAudioInfoListDetails = {
+ source: Audio.AudioSourceInfo;
+ term: string;
+ reading: string;
+};
+
+export type GetTermAudioInfoListResult = AudioDownloader.Info[];
+
+// commandExec
+
+export type CommandExecDetails = {
+ command: string;
+ params?: Core.SerializableObject;
+};
+
+export type CommandExecResult = boolean;
+
+// sendMessageToFrame
+
+export type SendMessageToFrameDetails = {
+ frameId: number;
+ action: string;
+ params?: Core.SerializableObject;
+};
+
+export type SendMessageToFrameResult = boolean;
+
+// broadcastTab
+
+export type BroadcastTabDetails = {
+ action: string;
+ params?: Core.SerializableObject;
+};
+
+export type BroadcastTabResult = boolean;
+
+// frameInformationGet
+
+export type FrameInformationGetDetails = Record<string, never>;
+
+export type FrameInformationGetResult = Extension.ContentOrigin;
+
+// injectStylesheet
+
+export type InjectStylesheetDetails = {
+ type: 'file' | 'code';
+ value: string;
+};
+
+export type InjectStylesheetResult = void;
+
+// getStylesheetContent
+
+export type GetStylesheetContentDetails = {
+ url: string;
+};
+
+export type GetStylesheetContentResult = string;
+
+// getEnvironmentInfo
+
+export type GetEnvironmentInfoDetails = Record<string, never>;
+
+export type GetEnvironmentInfoResult = Environment.Info;
+
+// clipboardGet
+
+export type ClipboardGetDetails = Record<string, never>;
+
+export type ClipboardGetResult = string;
+
+// getDisplayTemplatesHtml
+
+export type GetDisplayTemplatesHtmlDetails = Record<string, never>;
+
+export type GetDisplayTemplatesHtmlResult = string;
+
+// getZoom
+
+export type GetZoomDetails = Record<string, never>;
+
+export type GetZoomResult = {
+ zoomFactor: number;
+};
+
+// getDefaultAnkiFieldTemplates
+
+export type GetDefaultAnkiFieldTemplatesDetails = Record<string, never>;
+
+export type GetDefaultAnkiFieldTemplatesResult = string;
+
+// getDictionaryInfo
+
+export type GetDictionaryInfoDetails = Record<string, never>;
+
+export type GetDictionaryInfoResult = DictionaryImporter.Summary[];
+
+// purgeDatabase
+
+export type PurgeDatabaseDetails = Record<string, never>;
+
+export type PurgeDatabaseResult = void;
+
+// getMedia
+
+export type GetMediaDetails = {
+ targets: GetMediaDetailsTarget[];
+};
+
+export type GetMediaDetailsTarget = {
+ path: string;
+ dictionary: string;
+};
+
+export type GetMediaResult = DictionaryDatabase.MediaDataStringContent[];
+
+// log
+
+export type LogDetails = {
+ error: Core.SerializedError;
+ level: Log.LogLevel;
+ context: Log.LogContext | undefined;
+};
+
+export type LogResult = void;
+
+// logIndicatorClear
+
+export type LogIndicatorClearDetails = Record<string, never>;
+
+export type LogIndicatorClearResult = void;
+
+// modifySettings
+
+export type ModifySettingsDetails = {
+ targets: SettingsModifications.ScopedModification[];
+ source: string;
+};
+
+export type ModifySettingsResult = Core.Response<SettingsModifications.ModificationResult>[];
+
+// getSettings
+
+export type GetSettingsDetails = {
+ targets: SettingsModifications.ScopedRead[];
+};
+
+export type GetSettingsResult = Core.Response<SettingsModifications.ModificationResult>[];
+
+// setAllSettings
+
+export type SetAllSettingsDetails = {
+ value: Settings.Options;
+ source: string;
+};
+
+export type SetAllSettingsResult = void;
+
+// getOrCreateSearchPopup
+
+export type GetOrCreateSearchPopupDetails = {
+ focus?: boolean | 'ifCreated';
+ text?: string;
+};
+
+export type GetOrCreateSearchPopupResult = {
+ tabId: number | null;
+ windowId: number;
+};
+
+// isTabSearchPopup
+
+export type IsTabSearchPopupDetails = {
+ tabId: number;
+};
+
+export type IsTabSearchPopupResult = boolean;
+
+// triggerDatabaseUpdated
+
+export type TriggerDatabaseUpdatedDetails = {
+ type: Backend.DatabaseUpdateType;
+ cause: Backend.DatabaseUpdateCause;
+};
+
+export type TriggerDatabaseUpdatedResult = void;
+
+// testMecab
+
+export type TestMecabDetails = Record<string, never>;
+
+export type TestMecabResult = true;
+
+// textHasJapaneseCharacters
+
+export type TextHasJapaneseCharactersDetails = {
+ text: string;
+};
+
+export type TextHasJapaneseCharactersResult = boolean;
+
+// getTermFrequencies
+
+export type GetTermFrequenciesDetails = {
+ termReadingList: GetTermFrequenciesDetailsTermReadingListItem[];
+ dictionaries: string[];
+};
+
+export type GetTermFrequenciesDetailsTermReadingListItem = {
+ term: string;
+ reading: string | null;
+};
+
+export type GetTermFrequenciesResult = Translator.TermFrequencySimple[];
+
+// findAnkiNotes
+
+export type FindAnkiNotesDetails = {
+ query: string;
+};
+
+export type FindAnkiNotesResult = Anki.NoteId[];
+
+// loadExtensionScripts
+
+export type LoadExtensionScriptsDetails = {
+ files: string[];
+};
+
+export type LoadExtensionScriptsResult = void;
+
+// openCrossFramePort
+
+export type OpenCrossFramePortDetails = {
+ targetTabId: number;
+ targetFrameId: number;
+};
+
+export type OpenCrossFramePortResult = {
+ targetTabId: number;
+ targetFrameId: number;
+};
+
+// requestBackendReadySignal
+
+export type RequestBackendReadySignalDetails = Record<string, never>;
+
+export type RequestBackendReadySignalResult = boolean;
+
+// createActionPort
+
+export type CreateActionPortDetails = Record<string, never>;
+
+export type CreateActionPortResult = {
+ name: string;
+ id: string;
+};
diff --git a/types/ext/audio-controller.d.ts b/types/ext/audio-controller.d.ts
new file mode 100644
index 00000000..e8317aaf
--- /dev/null
+++ b/types/ext/audio-controller.d.ts
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type EventType = 'voicesUpdated';
+
+export type VoiceInfo = {
+ voice: SpeechSynthesisVoice;
+ isJapanese: boolean;
+ index: number;
+};
diff --git a/types/ext/audio-downloader.d.ts b/types/ext/audio-downloader.d.ts
new file mode 100644
index 00000000..b8e812f8
--- /dev/null
+++ b/types/ext/audio-downloader.d.ts
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Audio from './audio';
+
+export type GetInfoHandler = (
+ term: string,
+ reading: string,
+ details?: Audio.AudioSourceInfo,
+) => Promise<Info[]>;
+
+export type Info = Info1 | Info2;
+
+export type Info1 = {
+ type: 'url';
+ url: string;
+ name?: string;
+};
+
+export type Info2 = {
+ type: 'tts';
+ text: string;
+ voice: string;
+ name?: undefined;
+};
+
+export type AudioBinaryBase64 = {
+ data: string;
+ contentType: string | null;
+};
diff --git a/types/ext/audio-system.d.ts b/types/ext/audio-system.d.ts
new file mode 100644
index 00000000..e9766ed1
--- /dev/null
+++ b/types/ext/audio-system.d.ts
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type EventType = 'voiceschanged';
diff --git a/types/ext/audio.d.ts b/types/ext/audio.d.ts
new file mode 100644
index 00000000..4bf952c6
--- /dev/null
+++ b/types/ext/audio.d.ts
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as DisplayAudio from './display-audio';
+
+export type AudioSourceInfo = DisplayAudio.AudioSourceShort;
diff --git a/types/ext/backend.d.ts b/types/ext/backend.d.ts
new file mode 100644
index 00000000..08cbf4b0
--- /dev/null
+++ b/types/ext/backend.d.ts
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Api from './api';
+import type * as Core from './core';
+
+export type MessageHandlerDetails = {
+ async: boolean;
+ contentScript: boolean;
+ handler: (params: Core.SerializableObject | undefined, sender: chrome.runtime.MessageSender) => unknown;
+};
+export type MessageHandlerMap = Map<string, MessageHandlerDetails>;
+export type MessageHandlerMapInit = [key: string, handlerDetails: MessageHandlerDetails][];
+
+export type MessageHandlerWithProgressDetails = {
+ async: boolean;
+ contentScript: boolean;
+ handler: (params: Core.SerializableObject | undefined, sender: chrome.runtime.MessageSender, onProgress: (...data: unknown[]) => void) => (Promise<unknown> | unknown);
+};
+export type MessageHandlerWithProgressMap = Map<string, MessageHandlerWithProgressDetails>;
+export type MessageHandlerWithProgressMapInit = [key: string, handlerDetails: MessageHandlerWithProgressDetails][];
+
+export type DatabaseUpdateType = 'dictionary';
+export type DatabaseUpdateCause = 'purge' | 'delete' | 'import';
+
+export type MecabParseResults = [
+ dictionary: string,
+ content: Api.ParseTextLine[],
+][];
+
+export type TabInfo = {
+ tab: chrome.tabs.Tab;
+ url: string | null;
+};
+
+export type FindTabsPredicate = (tabInfo: TabInfo) => boolean | Promise<boolean>;
+
+export type InvokeWithProgressRequestMessage = (
+ InvokeWithProgressRequestFragmentMessage |
+ InvokeWithProgressRequestInvokeMessage
+);
+
+export type InvokeWithProgressRequestFragmentMessage = {
+ action: 'fragment';
+ data: string;
+};
+
+export type InvokeWithProgressRequestInvokeMessage = {
+ action: 'invoke';
+};
+
+export type InvokeWithProgressResponseMessage<TReturn = unknown> = (
+ InvokeWithProgressResponseProgressMessage |
+ InvokeWithProgressResponseCompleteMessage<TReturn> |
+ InvokeWithProgressResponseErrorMessage |
+ InvokeWithProgressResponseAcknowledgeMessage
+);
+
+export type InvokeWithProgressResponseProgressMessage = {
+ type: 'progress';
+ data: unknown[];
+};
+
+export type InvokeWithProgressResponseCompleteMessage<TReturn = unknown> = {
+ type: 'complete';
+ data: TReturn;
+};
+
+export type InvokeWithProgressResponseErrorMessage = {
+ type: 'error';
+ data: Core.SerializedError;
+};
+
+export type InvokeWithProgressResponseAcknowledgeMessage = {
+ type: 'ack';
+};
diff --git a/types/ext/backup-controller.d.ts b/types/ext/backup-controller.d.ts
new file mode 100644
index 00000000..d494ceb9
--- /dev/null
+++ b/types/ext/backup-controller.d.ts
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Environment from './environment';
+import type * as Settings from './settings';
+
+export type BackupData = {
+ version: number;
+ date: string;
+ url: string;
+ manifest: chrome.runtime.Manifest;
+ environment: Environment.Info;
+ userAgent: string;
+ permissions: chrome.permissions.Permissions;
+ options: Settings.Options;
+};
+
+export type ShowSettingsImportWarningsResult = {
+ result: boolean;
+ sanitize?: boolean;
+};
diff --git a/types/ext/cache-map.d.ts b/types/ext/cache-map.d.ts
new file mode 100644
index 00000000..0af7109a
--- /dev/null
+++ b/types/ext/cache-map.d.ts
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type Node<K, V> = {
+ key: K | null;
+ value: V | null;
+ previous: Node<K, V> | null;
+ next: Node<K, V> | null;
+};
diff --git a/types/ext/clipboard-monitor.d.ts b/types/ext/clipboard-monitor.d.ts
new file mode 100644
index 00000000..f8cf7d02
--- /dev/null
+++ b/types/ext/clipboard-monitor.d.ts
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type EventType = 'change';
+
+export type ChangeEvent = {
+ text: string;
+};
+
+export type ClipboardReaderLike = {
+ getText: (useRichText: boolean) => Promise<string>;
+};
diff --git a/types/ext/core.d.ts b/types/ext/core.d.ts
new file mode 100644
index 00000000..b83e6a74
--- /dev/null
+++ b/types/ext/core.d.ts
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type TypeofResult = 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undefined' | 'object' | 'function';
+
+/** This type is used as an explicit way of permitting the `any` type. */
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export type SafeAny = any;
+
+/** This type is used as an explicit way of permitting the `Function` type. */
+// eslint-disable-next-line @typescript-eslint/ban-types
+export type SafeFunction = Function;
+
+/** This type is used as an explicit way of permitting the `any` type. */
+export type RejectionReason = SafeAny;
+
+/** This type is used as an explicit way of permitting the `object` type. */
+export type SerializableObject = {[key: string]: unknown};
+
+/** This type is used as an explicit way of permitting the `object` type. */
+export type SerializableObjectAny = {[key: string]: SafeAny};
+
+/** This type is used as an explicit way of permitting the `object` type. */
+export type UnknownObject = {[key: string | symbol]: unknown};
+
+export type TokenString = string;
+
+export type TokenObject = Record<string, never>;
+
+export type DeferredPromiseDetails<T> = {
+ promise: Promise<T>;
+ resolve: (value: T) => void;
+ reject: (reason?: RejectionReason) => void;
+};
+
+export type SerializedError1 = {
+ name: string;
+ message: string;
+ stack: string;
+ data?: unknown;
+ hasValue?: undefined;
+};
+
+export type SerializedError2 = {
+ value: unknown;
+ hasValue: true;
+};
+
+export type SerializedError = SerializedError1 | SerializedError2;
+
+export type ResponseSuccess<T = unknown> = {
+ result: T;
+ error?: undefined;
+};
+
+export type ResponseError = {
+ error: SerializedError;
+ result?: undefined;
+};
+
+export type Response<T = unknown> = ResponseSuccess<T> | ResponseError;
+
+export type MessageHandler = (params: SafeAny, ...extraArgs: SafeAny[]) => (
+ SafeAny |
+ Promise<SafeAny> |
+ MessageHandlerAsyncResult
+);
+
+export type MessageHandlerAsyncResult = {
+ async: boolean;
+ result: SafeAny | Promise<SafeAny>;
+};
+
+export type MessageHandlerDetails = {
+ /**
+ * Whether or not the handler is async or not. Values include `false`, `true`, or `'dynamic'`.
+ * When the value is `'dynamic'`, the handler should return an object of the format `{async: boolean, result: any}`.
+ */
+ async: boolean | 'dynamic';
+ /**
+ * A handler function which is passed `params` and `...extraArgs` as arguments.
+ */
+ handler: MessageHandler;
+};
+
+export type MessageHandlerMap = Map<string, MessageHandlerDetails>;
+
+export type MessageHandlerArray = [key: string, handlerDetails: MessageHandlerDetails][];
+
+export type Timeout = number | NodeJS.Timeout;
diff --git a/types/ext/cross-frame-api.d.ts b/types/ext/cross-frame-api.d.ts
new file mode 100644
index 00000000..88ce59a7
--- /dev/null
+++ b/types/ext/cross-frame-api.d.ts
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Core from './core';
+
+export type CrossFrameAPIPortEventType = 'disconnect';
+
+export type AcknowledgeMessage = {
+ type: 'ack';
+ id: number;
+};
+
+export type ResultMessage = {
+ type: 'result';
+ id: number;
+ data: Core.Response<unknown>;
+};
+
+export type InvokeMessage = {
+ type: 'invoke';
+ id: number;
+ data: InvocationData;
+};
+
+export type InvocationData = {
+ action: string;
+ params: Core.SerializableObject;
+};
+
+export type Message = AcknowledgeMessage | ResultMessage | InvokeMessage;
+
+export type Invocation = {
+ id: number;
+ resolve: (value: Core.SafeAny) => void;
+ reject: (reason?: unknown) => void;
+ responseTimeout: number;
+ action: string;
+ ack: boolean;
+ timer: Core.Timeout | null;
+};
diff --git a/types/ext/css-style-applier.d.ts b/types/ext/css-style-applier.d.ts
new file mode 100644
index 00000000..d4db2da6
--- /dev/null
+++ b/types/ext/css-style-applier.d.ts
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type RawStyleData = {
+ selectors: string[];
+ styles: RawStyleDataStyleArray;
+}[];
+
+export type RawStyleDataStyleArray = [
+ property: string,
+ value: string,
+][];
+
+/**
+ * A CSS rule.
+ */
+export type CssRule = {
+ /** A CSS selector string representing one or more selectors. */
+ selectors: string;
+ /** A list of CSS property and value pairs. */
+ styles: CssDeclaration[];
+};
+
+/**
+ * A single CSS property declaration.
+ */
+export type CssDeclaration = {
+ /** A CSS property's name, using kebab-case. */
+ property: string;
+ /** The property's value. */
+ value: string;
+};
diff --git a/types/ext/database.d.ts b/types/ext/database.d.ts
new file mode 100644
index 00000000..e4a58e60
--- /dev/null
+++ b/types/ext/database.d.ts
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type StructureDefinition<TObjectStoreName extends string> = {
+ version: number;
+ stores: {[name in TObjectStoreName]: StoreDefinition};
+};
+
+export type StoreDefinition = {
+ primaryKey: IDBObjectStoreParameters;
+ indices: string[];
+};
+
+export type UpdateFunction = (
+ db: IDBDatabase,
+ transaction: IDBTransaction,
+ oldVersion: number,
+ newVersion: number | null,
+) => void;
+
+export type CountTarget = [
+ objectStoreOrIndex: IDBObjectStore | IDBIndex,
+ query: IDBValidKey | IDBKeyRange | undefined,
+];
diff --git a/types/ext/deinflector.d.ts b/types/ext/deinflector.d.ts
new file mode 100644
index 00000000..e6fc203e
--- /dev/null
+++ b/types/ext/deinflector.d.ts
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as TranslationInternal from './translation-internal';
+
+export type ReasonTypeRaw = 'v1' | 'v5' | 'vs' | 'vk' | 'vz' | 'adj-i' | 'iru';
+
+export type ReasonsRaw = {
+ [reason: string]: {
+ kanaIn: string;
+ kanaOut: string;
+ rulesIn: ReasonTypeRaw[];
+ rulesOut: ReasonTypeRaw[];
+ }[];
+};
+
+export type ReasonVariant = [
+ kanaIn: string,
+ kanaOut: string,
+ rulesIn: TranslationInternal.DeinflectionRuleFlags,
+ rulesOut: TranslationInternal.DeinflectionRuleFlags,
+];
+
+export type Reason = [
+ reason: string,
+ variants: ReasonVariant[],
+];
diff --git a/types/ext/dictionary-data-util.d.ts b/types/ext/dictionary-data-util.d.ts
new file mode 100644
index 00000000..75128368
--- /dev/null
+++ b/types/ext/dictionary-data-util.d.ts
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Dictionary from './dictionary';
+
+export type FrequencyData = {
+ frequency: number;
+ displayValue: string | null;
+};
+
+export type KanjiFrequenciesMap3 = Map<string, FrequencyData>;
+
+export type TermFrequenciesMap1 = Map<string, TermFrequenciesMap2>;
+
+export type TermFrequenciesMap2 = Map<string, TermFrequenciesMap2Data>;
+
+export type TermFrequenciesMap2Data = {
+ term: string;
+ reading: string | null;
+ values: TermFrequenciesMap3;
+};
+
+export type KanjiFrequenciesMap1 = Map<string, KanjiFrequenciesMap2>;
+
+export type KanjiFrequenciesMap2 = Map<string, KanjiFrequenciesMap2Data>;
+
+export type KanjiFrequenciesMap2Data = {
+ character: string;
+ values: KanjiFrequenciesMap3;
+};
+
+export type TermFrequenciesMap3 = Map<string, FrequencyData>;
+
+export type DictionaryFrequency<T> = {
+ dictionary: string;
+ frequencies: T[];
+};
+
+export type TermFrequency = {
+ term: string;
+ reading: string | null;
+ values: FrequencyData[];
+};
+
+export type KanjiFrequency = {
+ character: string;
+ values: FrequencyData[];
+};
+
+export type TermFrequencyType = 'popular' | 'rare' | 'normal';
+
+export type GroupedPronunciationInternal = {
+ terms: Set<string>;
+ reading: string;
+ position: number;
+ nasalPositions: number[];
+ devoicePositions: number[];
+ tags: Dictionary.Tag[];
+};
+
+export type GroupedPronunciation = {
+ terms: string[];
+ reading: string;
+ position: number;
+ nasalPositions: number[];
+ devoicePositions: number[];
+ tags: Dictionary.Tag[];
+ exclusiveTerms: string[];
+ exclusiveReadings: string[];
+};
+
+export type DictionaryGroupedPronunciations = {
+ dictionary: string;
+ pronunciations: GroupedPronunciation[];
+};
+
+export type TagGroup = {
+ tag: Dictionary.Tag;
+ headwordIndices: number[];
+};
diff --git a/types/ext/dictionary-data.d.ts b/types/ext/dictionary-data.d.ts
new file mode 100644
index 00000000..f594f913
--- /dev/null
+++ b/types/ext/dictionary-data.d.ts
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as StructuredContent from './structured-content';
+
+export type IndexVersion = 1 | 2 | 3;
+
+export type Index = {
+ format?: IndexVersion;
+ version?: IndexVersion;
+ title: string;
+ revision: string;
+ sequenced?: boolean;
+ author?: string;
+ url?: string;
+ description?: string;
+ attribution?: string;
+ frequencyMode?: 'occurrence-based' | 'rank-based';
+ tagMeta?: IndexTagMeta;
+};
+
+export type IndexTagMeta = {
+ [name: string]: IndexTag;
+};
+
+export type IndexTag = {
+ category: string;
+ order: number;
+ notes: string;
+ score: number;
+};
+
+export type TermV1 = [
+ expression: string,
+ reading: string,
+ definitionTags: string | null,
+ rules: string,
+ score: number,
+ ...glossary: string[],
+];
+
+export type TermV3 = [
+ expression: string,
+ reading: string,
+ definitionTags: string | null,
+ rules: string,
+ score: number,
+ glossary: TermGlossary[],
+ sequence: number,
+ termTags: string,
+];
+
+export type KanjiV1 = [
+ character: string,
+ onyomi: string,
+ kunyomi: string,
+ tags: string,
+ ...meanings: string[],
+];
+
+export type KanjiV3 = [
+ character: string,
+ onyomi: string,
+ kunyomi: string,
+ tags: string,
+ meanings: string[],
+ stats: {[name: string]: string},
+];
+
+export type TermGlossary = (
+ TermGlossaryString |
+ TermGlossaryText |
+ TermGlossaryImage |
+ TermGlossaryStructuredContent
+);
+
+export type TermGlossaryString = string;
+export type TermGlossaryText = {type: 'text', text: string};
+export type TermGlossaryImage = {type: 'image'} & TermImage;
+export type TermGlossaryStructuredContent = {type: 'structured-content', content: StructuredContent.Content};
+
+export type TermImage = StructuredContent.ImageElementBase;
+
+export type Tag = [
+ name: string,
+ category: string,
+ order: number,
+ notes: string,
+ score: number,
+];
+
+export type GenericFrequencyData = string | number | {
+ value: number;
+ displayValue?: string;
+ reading?: undefined; // Used for type disambiguation, field does not actually exist
+};
+
+export type TermMeta = TermMetaFrequency | TermMetaPitch;
+
+export type TermMetaFrequencyDataWithReading = {
+ reading: string;
+ frequency: GenericFrequencyData;
+};
+
+export type TermMetaFrequency = [
+ expression: string,
+ mode: 'freq',
+ data: GenericFrequencyData | TermMetaFrequencyDataWithReading,
+];
+
+export type TermMetaPitchData = {
+ reading: string;
+ pitches: {
+ position: number;
+ nasal?: number | number[];
+ devoice?: number | number[];
+ tags?: string[];
+ }[];
+};
+
+export type TermMetaPitch = [
+ expression: string,
+ mode: 'pitch',
+ data: TermMetaPitchData,
+];
+
+export type KanjiMeta = KanjiMetaFrequency;
+
+export type KanjiMetaFrequency = [
+ character: string,
+ mode: 'freq',
+ data: GenericFrequencyData,
+];
diff --git a/types/ext/dictionary-database.d.ts b/types/ext/dictionary-database.d.ts
new file mode 100644
index 00000000..6569f76b
--- /dev/null
+++ b/types/ext/dictionary-database.d.ts
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Dictionary from './dictionary';
+import type * as DictionaryData from './dictionary-data';
+import type * as DictionaryImporter from './dictionary-importer';
+
+export type DatabaseId = {
+ id: number; // Automatic database primary key
+};
+
+export type MediaDataBase<TContentType = unknown> = {
+ dictionary: string;
+ path: string;
+ mediaType: string;
+ width: number;
+ height: number;
+ content: TContentType;
+};
+
+export type MediaDataArrayBufferContent = MediaDataBase<ArrayBuffer>;
+
+export type MediaDataStringContent = MediaDataBase<string>;
+
+export type Media<T extends (ArrayBuffer | string) = ArrayBuffer> = {index: number} & MediaDataBase<T>;
+
+export type DatabaseTermEntry = {
+ expression: string;
+ reading: string;
+ expressionReverse?: string;
+ readingReverse?: string;
+ definitionTags: string | null;
+ /** Legacy alias for the `definitionTags` field. */
+ tags?: string;
+ rules: string;
+ score: number;
+ glossary: DictionaryData.TermGlossary[];
+ sequence?: number;
+ termTags?: string;
+ dictionary: string;
+};
+
+export type DatabaseTermEntryWithId = DatabaseTermEntry & DatabaseId;
+
+export type TermEntry = {
+ index: number;
+ matchType: MatchType;
+ matchSource: MatchSource;
+ term: string;
+ reading: string;
+ definitionTags: string[];
+ termTags: string[];
+ rules: string[];
+ definitions: DictionaryData.TermGlossary[];
+ score: number;
+ dictionary: string;
+ id: number;
+ sequence: number;
+};
+
+export type DatabaseKanjiEntry = {
+ character: string;
+ onyomi: string;
+ kunyomi: string;
+ tags: string;
+ meanings: string[];
+ dictionary: string;
+ stats?: {[name: string]: string};
+};
+
+export type KanjiEntry = {
+ index: number;
+ character: string;
+ onyomi: string[];
+ kunyomi: string[];
+ tags: string[];
+ definitions: string[];
+ stats: {[name: string]: string};
+ dictionary: string;
+};
+
+export type Tag = {
+ name: string;
+ category: string;
+ order: number;
+ notes: string;
+ score: number;
+ dictionary: string;
+};
+
+export type DatabaseTermMeta = DatabaseTermMetaFrequency | DatabaseTermMetaPitch;
+
+export type DatabaseTermMetaFrequency = {
+ expression: string;
+ mode: 'freq';
+ data: DictionaryData.GenericFrequencyData | DictionaryData.TermMetaFrequencyDataWithReading;
+ dictionary: string;
+};
+
+export type DatabaseTermMetaPitch = {
+ expression: string;
+ mode: 'pitch';
+ data: DictionaryData.TermMetaPitchData;
+ dictionary: string;
+};
+
+export type TermMetaFrequencyDataWithReading = {
+ reading: string;
+ frequency: DictionaryData.GenericFrequencyData;
+};
+
+export type TermMeta = TermMetaFrequency | TermMetaPitch;
+
+export type TermMetaType = TermMeta['mode'];
+
+export type TermMetaFrequency = {
+ index: number;
+ term: string;
+ mode: 'freq';
+ data: DictionaryData.GenericFrequencyData | DictionaryData.TermMetaFrequencyDataWithReading;
+ dictionary: string;
+};
+
+export type TermMetaPitch = {
+ index: number;
+ term: string;
+ mode: 'pitch';
+ data: DictionaryData.TermMetaPitchData;
+ dictionary: string;
+};
+
+export type DatabaseKanjiMeta = DatabaseKanjiMetaFrequency;
+
+export type DatabaseKanjiMetaFrequency = {
+ character: string;
+ mode: 'freq';
+ data: DictionaryData.GenericFrequencyData;
+ dictionary: string;
+};
+
+export type KanjiMeta = KanjiMetaFrequency;
+
+export type KanjiMetaType = KanjiMeta['mode'];
+
+export type KanjiMetaFrequency = {
+ index: number;
+ character: string;
+ mode: 'freq';
+ data: DictionaryData.GenericFrequencyData;
+ dictionary: string;
+};
+
+export type DictionaryCounts = {
+ total: DictionaryCountGroup | null;
+ counts: DictionaryCountGroup[];
+};
+
+export type DictionaryCountGroup = {
+ [key: string]: number;
+};
+
+export type ObjectStoreName = (
+ 'dictionaries' |
+ 'terms' |
+ 'termMeta' |
+ 'kanji' |
+ 'kanjiMeta' |
+ 'tagMeta' |
+ 'media'
+);
+
+/* eslint-disable @stylistic/ts/indent */
+export type ObjectStoreData<T extends ObjectStoreName> = (
+ T extends 'dictionaries' ? DictionaryImporter.Summary :
+ T extends 'terms' ? DatabaseTermEntry :
+ T extends 'termMeta' ? DatabaseTermMeta :
+ T extends 'kanji' ? DatabaseKanjiEntry :
+ T extends 'kanjiMeta' ? DatabaseKanjiMeta :
+ T extends 'tagMeta' ? Tag :
+ T extends 'media' ? MediaDataArrayBufferContent :
+ never
+);
+/* eslint-enable @stylistic/ts/indent */
+
+export type DeleteDictionaryProgressData = {
+ count: number;
+ processed: number;
+ storeCount: number;
+ storesProcesed: number;
+};
+
+export type DeleteDictionaryProgressCallback = (data: DeleteDictionaryProgressData) => void;
+
+export type MatchType = Dictionary.TermSourceMatchType;
+
+export type MatchSource = Dictionary.TermSourceMatchSource;
+
+export type DictionaryAndQueryRequest = {
+ query: string | number;
+ dictionary: string;
+};
+
+export type TermExactRequest = {
+ term: string;
+ reading: string;
+};
+
+export type MediaRequest = {
+ path: string;
+ dictionary: string;
+};
+
+export type FindMultiBulkData<TItem = unknown> = {
+ item: TItem;
+ itemIndex: number;
+ indexIndex: number;
+};
+
+export type CreateQuery<TItem> = (item: TItem) => (IDBValidKey | IDBKeyRange | null);
+
+export type FindPredicate<TItem, TRow> = (row: TRow, item: TItem) => boolean;
+
+export type CreateResult<TItem, TRow, TResult> = (row: TRow, data: FindMultiBulkData<TItem>) => TResult;
+
+export type DictionarySet = {
+ has(value: string): boolean;
+};
diff --git a/types/ext/dictionary-importer-media-loader.d.ts b/types/ext/dictionary-importer-media-loader.d.ts
new file mode 100644
index 00000000..afbb1902
--- /dev/null
+++ b/types/ext/dictionary-importer-media-loader.d.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * Attempts to load an image using an ArrayBuffer and a media type to return details about it.
+ * @param content The binary content for the image, encoded as an ArrayBuffer.
+ * @param mediaType The media type for the image content.
+ * @param transfer An optional array of data that should be transferred in `postMessage` calls.
+ * When the resulting promise resolves, this array will contain the `content` object.
+ * @returns Details about the requested image content.
+ * @throws {Error} An error can be thrown if the image fails to load.
+ */
+export type GetImageDetailsFunction = (
+ content: ArrayBuffer,
+ mediaType: string,
+ transfer?: Transferable[]
+) => Promise<{content: ArrayBuffer, width: number, height: number}>;
+
+
+export type GenericMediaLoader = {
+ getImageDetails: GetImageDetailsFunction;
+};
diff --git a/types/ext/dictionary-importer.d.ts b/types/ext/dictionary-importer.d.ts
new file mode 100644
index 00000000..5ae20dd1
--- /dev/null
+++ b/types/ext/dictionary-importer.d.ts
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as ZipJS from '@zip.js/zip.js';
+import type * as Ajv from 'ajv';
+import type * as DictionaryData from './dictionary-data';
+import type * as DictionaryDatabase from './dictionary-database';
+import type * as StructuredContent from './structured-content';
+
+export type OnProgressCallback = (data: ProgressData) => void;
+
+export type ProgressData = {
+ stepIndex: number;
+ stepCount: number;
+ index: number;
+ count: number;
+};
+
+export type ImportResult = {
+ result: Summary;
+ errors: Error[];
+};
+
+export type ImportDetails = {
+ prefixWildcardsSupported: boolean;
+};
+
+export type Summary = {
+ title: string;
+ revision: string;
+ sequenced: boolean;
+ version: number;
+ importDate: number;
+ prefixWildcardsSupported: boolean;
+ counts: SummaryCounts;
+ author?: string;
+ url?: string;
+ description?: string;
+ attribution?: string;
+ frequencyMode?: 'occurrence-based' | 'rank-based';
+};
+
+export type SummaryCounts = {
+ terms: SummaryItemCount;
+ termMeta: SummaryMetaCount;
+ kanji: SummaryItemCount;
+ kanjiMeta: SummaryMetaCount;
+ tagMeta: SummaryItemCount;
+ media: SummaryItemCount;
+};
+
+export type SummaryItemCount = {
+ total: number;
+};
+
+export type SummaryMetaCount = {
+ total: number;
+ [key: string]: number;
+};
+
+export type ImportRequirement = (
+ ImageImportRequirement |
+ StructuredContentImageImportRequirement
+);
+
+export type ImageImportRequirement = {
+ type: 'image';
+ target: DictionaryData.TermGlossaryImage;
+ source: DictionaryData.TermGlossaryImage;
+ entry: DictionaryDatabase.DatabaseTermEntry;
+};
+
+export type StructuredContentImageImportRequirement = {
+ type: 'structured-content-image';
+ target: StructuredContent.ImageElement;
+ source: StructuredContent.ImageElement;
+ entry: DictionaryDatabase.DatabaseTermEntry;
+};
+
+export type ImportRequirementContext = {
+ fileMap: ArchiveFileMap;
+ media: Map<string, DictionaryDatabase.MediaDataArrayBufferContent>;
+};
+
+export type ArchiveFileMap = Map<string, ZipJS.Entry>;
+
+export type CompiledSchemaNameArray = [
+ termBank: CompiledSchemaName,
+ termMetaBank: CompiledSchemaName,
+ kanjiBank: CompiledSchemaName,
+ kanjiMetaBank: CompiledSchemaName,
+ tagBank: CompiledSchemaName,
+];
+
+export type CompiledSchemaValidators = {
+ dictionaryIndex: Ajv.ValidateFunction<unknown>;
+ dictionaryTermBankV1: Ajv.ValidateFunction<unknown>;
+ dictionaryTermBankV3: Ajv.ValidateFunction<unknown>;
+ dictionaryTermMetaBankV3: Ajv.ValidateFunction<unknown>;
+ dictionaryKanjiBankV1: Ajv.ValidateFunction<unknown>;
+ dictionaryKanjiBankV3: Ajv.ValidateFunction<unknown>;
+ dictionaryKanjiMetaBankV3: Ajv.ValidateFunction<unknown>;
+ dictionaryTagBankV3: Ajv.ValidateFunction<unknown>;
+};
+
+export type CompiledSchemaName = keyof CompiledSchemaValidators;
diff --git a/types/ext/dictionary-worker-handler.d.ts b/types/ext/dictionary-worker-handler.d.ts
new file mode 100644
index 00000000..ddd6134c
--- /dev/null
+++ b/types/ext/dictionary-worker-handler.d.ts
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as DictionaryImporter from './dictionary-importer';
+import type * as DictionaryWorkerMediaLoader from './dictionary-worker-media-loader';
+
+export type OnProgressCallback = (...args: unknown[]) => void;
+
+export type Message = (
+ ImportDictionaryMessage |
+ DeleteDictionaryMessage |
+ GetDictionaryCountsMessage |
+ GetImageDetailsResponseMessage
+);
+
+export type ImportDictionaryMessage = {
+ action: 'importDictionary';
+ params: ImportDictionaryMessageParams;
+};
+
+export type ImportDictionaryMessageParams = {
+ details: DictionaryImporter.ImportDetails;
+ archiveContent: ArrayBuffer;
+};
+
+export type DeleteDictionaryMessage = {
+ action: 'deleteDictionary';
+ params: DeleteDictionaryMessageParams;
+};
+
+export type DeleteDictionaryMessageParams = {
+ dictionaryTitle: string;
+};
+
+export type GetDictionaryCountsMessage = {
+ action: 'getDictionaryCounts';
+ params: GetDictionaryCountsMessageParams;
+};
+
+export type GetDictionaryCountsMessageParams = {
+ dictionaryNames: string[];
+ getTotal: boolean;
+};
+
+export type GetImageDetailsResponseMessage = {
+ action: 'getImageDetails.response';
+ params: DictionaryWorkerMediaLoader.HandleMessageParams;
+};
diff --git a/types/ext/dictionary-worker-media-loader.d.ts b/types/ext/dictionary-worker-media-loader.d.ts
new file mode 100644
index 00000000..fab01283
--- /dev/null
+++ b/types/ext/dictionary-worker-media-loader.d.ts
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Core from './core';
+
+export type ImageDetails = {
+ content: ArrayBuffer;
+ width: number;
+ height: number;
+};
+
+export type HandleMessageParams = {id: string} & Core.Response<ImageDetails>;
diff --git a/types/ext/dictionary-worker.d.ts b/types/ext/dictionary-worker.d.ts
new file mode 100644
index 00000000..17030691
--- /dev/null
+++ b/types/ext/dictionary-worker.d.ts
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Core from './core';
+import type * as DictionaryDatabase from './dictionary-database';
+import type * as DictionaryImporter from './dictionary-importer';
+
+export type InvokeDetails<TResponseRaw = unknown, TResponse = unknown> = {
+ complete: boolean;
+ worker: Worker | null;
+ resolve: ((result: TResponse) => void) | null;
+ reject: ((reason?: Core.RejectionReason) => void) | null;
+ onMessage: ((event: MessageEvent<MessageData<TResponseRaw>>) => void) | null;
+ onProgress: ((...args: unknown[]) => void) | null;
+ formatResult: ((result: TResponseRaw) => TResponse) | null;
+};
+
+export type MessageCompleteData<TResponseRaw> = {
+ action: 'complete';
+ params: MessageCompleteParams<TResponseRaw>;
+};
+
+export type MessageProgressData = {
+ action: 'progress';
+ params: MessageProgressParams;
+};
+
+export type MessageGetImageDetailsData = {
+ action: 'getImageDetails';
+ params: MessageGetImageDetailsParams;
+};
+
+export type MessageCompleteParams<TResponseRaw> = Core.Response<TResponseRaw>;
+
+export type MessageProgressParams = {
+ args: unknown[];
+};
+
+export type MessageGetImageDetailsParams = {
+ id: string;
+ content: ArrayBuffer;
+ mediaType: string;
+};
+
+export type MessageData<TResponseRaw> = MessageCompleteData<TResponseRaw> | MessageProgressData | MessageGetImageDetailsData;
+
+export type MessageCompleteResultSerialized = {
+ result: DictionaryImporter.Summary;
+ errors: Core.SerializedError[];
+};
+
+export type MessageCompleteResult = {
+ result: DictionaryImporter.Summary;
+ errors: Error[];
+};
+
+export type ImportProgressCallback = (details: DictionaryImporter.ProgressData) => void;
+
+export type DeleteProgressCallback = (details: DictionaryDatabase.DeleteDictionaryProgressData) => void;
diff --git a/types/ext/dictionary.d.ts b/types/ext/dictionary.d.ts
new file mode 100644
index 00000000..3e90dec0
--- /dev/null
+++ b/types/ext/dictionary.d.ts
@@ -0,0 +1,477 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ * Copyright (C) 2021-2022 Yomichan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as DictionaryData from './dictionary-data';
+
+// Common
+
+/**
+ * A generic dictionary entry which is used as the base interface.
+ */
+export type DictionaryEntry = KanjiDictionaryEntry | TermDictionaryEntry;
+
+export type DictionaryEntryType = DictionaryEntry['type'];
+
+/**
+ * A tag represents some brief information about part of a dictionary entry.
+ */
+export type Tag = {
+ /**
+ * The name of the tag.
+ */
+ name: string;
+ /**
+ * The category of the tag.
+ */
+ category: string;
+ /**
+ * A number indicating the sorting order of the tag.
+ */
+ order: number;
+ /**
+ * A score value for the tag.
+ */
+ score: number;
+ /**
+ * An array of descriptions for the tag. * If there are multiple entries,
+ * the values will typically have originated from different dictionaries.
+ * However, there is no correlation between the length of this array and
+ * the length of the `dictionaries` field, as duplicates are removed.
+ */
+ content: string[];
+ /**
+ * An array of dictionary names that contained a tag with this name and category.
+ */
+ dictionaries: string[];
+ /**
+ * Whether or not this tag is redundant with previous tags.
+ */
+ redundant: boolean;
+};
+
+// Kanji
+
+/**
+ * A dictionary entry for a kanji character.
+ */
+export type KanjiDictionaryEntry = {
+ /**
+ * The type of the entry.
+ */
+ type: 'kanji';
+ /**
+ * The kanji character that was looked up.
+ */
+ character: string;
+ /**
+ * The name of the dictionary that the information originated from.
+ */
+ dictionary: string;
+ /**
+ * Onyomi readings for the kanji character.
+ */
+ onyomi: string[];
+ /**
+ * Kunyomi readings for the kanji character.
+ */
+ kunyomi: string[];
+ /**
+ * Tags for the kanji character.
+ */
+ tags: Tag[];
+ /**
+ * An object containing stats about the kanji character.
+ */
+ stats: KanjiStatGroups;
+ /**
+ * Definitions for the kanji character.
+ */
+ definitions: string[];
+ /**
+ * Frequency information for the kanji character.
+ */
+ frequencies: KanjiFrequency[];
+};
+
+/**
+ * An object with groups of stats about a kanji character.
+ */
+export type KanjiStatGroups = {
+ /**
+ * A group of stats.
+ * @param propName The name of the group.
+ */
+ [propName: string]: KanjiStat[];
+};
+
+/**
+ * A stat represents a generic piece of information about a kanji character.
+ */
+export type KanjiStat = {
+ /**
+ * The name of the stat.
+ */
+ name: string;
+ /**
+ * The category of the stat.
+ */
+ category: string;
+ /**
+ * A description of the stat.
+ */
+ content: string;
+ /**
+ * A number indicating the sorting order of the stat.
+ */
+ order: number;
+ /**
+ * A score value for the stat.
+ */
+ score: number;
+ /**
+ * The name of the dictionary that the stat originated from.
+ */
+ dictionary: string;
+ /**
+ * A value for the stat.
+ */
+ value: number | string;
+};
+
+/**
+ * Frequency information corresponds to how frequently a character appears in a corpus,
+ * which can be a number of occurrences or an overall rank.
+ */
+export type KanjiFrequency = {
+ /**
+ * The original order of the frequency, which is usually used for sorting.
+ */
+ index: number;
+ /**
+ * The name of the dictionary that the frequency information originated from.
+ */
+ dictionary: string;
+ /**
+ * The index of the dictionary in the original list of dictionaries used for the lookup.
+ */
+ dictionaryIndex: number;
+ /**
+ * The priority of the dictionary.
+ */
+ dictionaryPriority: number;
+ /**
+ * The kanji character for the frequency.
+ */
+ character: string;
+ /**
+ * The frequency for the character, as a number of occurrences or an overall rank.
+ */
+ frequency: number;
+ /**
+ * A display value to show to the user.
+ */
+ displayValue: string | null;
+ /**
+ * Whether or not the displayValue string was parsed to determine the frequency value.
+ */
+ displayValueParsed: boolean;
+};
+
+// Terms
+
+/**
+ * A dictionary entry for a term or group of terms.
+ */
+export type TermDictionaryEntry = {
+ /**
+ * The type of the entry.
+ */
+ type: 'term';
+ /**
+ * Whether or not any of the sources is a primary source. Primary sources are derived from the
+ * original search text, while non-primary sources originate from related terms.
+ */
+ isPrimary: boolean;
+ /**
+ * A list of inflections that was applied to get the term.
+ */
+ inflections: string[];
+ /**
+ * A score for the dictionary entry.
+ */
+ score: number;
+ /**
+ * The sorting value based on the determined term frequency.
+ */
+ frequencyOrder: number;
+ /**
+ * The index of the dictionary in the original list of dictionaries used for the lookup.
+ */
+ dictionaryIndex: number;
+ /**
+ * The priority of the dictionary.
+ */
+ dictionaryPriority: number;
+ /**
+ * The number of primary sources that had an exact text match for the term.
+ */
+ sourceTermExactMatchCount: number;
+ /**
+ * The maximum length of the transformed text for all primary sources.
+ */
+ maxTransformedTextLength: number;
+ /**
+ * Headwords for the entry.
+ */
+ headwords: TermHeadword[];
+ /**
+ * Definitions for the entry.
+ */
+ definitions: TermDefinition[];
+ /**
+ * Pronunciations for the entry.
+ */
+ pronunciations: TermPronunciation[];
+ /**
+ * Frequencies for the entry.
+ */
+ frequencies: TermFrequency[];
+};
+
+/**
+ * A term headword is a combination of a term, reading, and auxiliary information.
+ */
+export type TermHeadword = {
+ /**
+ * The original order of the headword, which is usually used for sorting.
+ */
+ index: number;
+ /**
+ * The text for the term.
+ */
+ term: string;
+ /**
+ * The reading of the term.
+ */
+ reading: string;
+ /**
+ * The sources of the term.
+ */
+ sources: TermSource[];
+ /**
+ * Tags for the headword.
+ */
+ tags: Tag[];
+ /**
+ * List of word classes (part of speech) for the headword.
+ */
+ wordClasses: string[];
+};
+
+/**
+ * A definition contains a list of entries and information about what what terms it corresponds to.
+ */
+export type TermDefinition = {
+ /**
+ * The original order of the definition, which is usually used for sorting.
+ */
+ index: number;
+ /**
+ * A list of headwords that this definition corresponds to.
+ */
+ headwordIndices: number[];
+ /**
+ * The name of the dictionary that the definition information originated from.
+ */
+ dictionary: string;
+ /**
+ * The index of the dictionary in the original list of dictionaries used for the lookup.
+ */
+ dictionaryIndex: number;
+ /**
+ * The priority of the dictionary.
+ */
+ dictionaryPriority: number;
+ /**
+ * Database ID for the definition.
+ */
+ id: number;
+ /**
+ * A score for the definition.
+ */
+ score: number;
+ /**
+ * The sorting value based on the determined term frequency.
+ */
+ frequencyOrder: number;
+ /**
+ * A list of database sequence numbers for the term. A value of `-1` corresponds to no sequence.
+ * The list can have multiple values if multiple definitions with different sequences have been merged.
+ * The list should always have at least one item.
+ */
+ sequences: number[];
+ /**
+ * Whether or not any of the sources is a primary source. Primary sources are derived from the
+ * original search text, while non-primary sources originate from related terms.
+ */
+ isPrimary: boolean;
+ /**
+ * Tags for the definition.
+ */
+ tags: Tag[];
+ /**
+ * The definition entries.
+ */
+ entries: DictionaryData.TermGlossary[];
+};
+
+/**
+ * A term pronunciation represents different ways to pronounce one of the headwords.
+ */
+export type TermPronunciation = {
+ /**
+ * The original order of the pronunciation, which is usually used for sorting.
+ */
+ index: number;
+ /**
+ * Which headword this pronunciation corresponds to.
+ */
+ headwordIndex: number;
+ /**
+ * The name of the dictionary that the proununciation information originated from.
+ */
+ dictionary: string;
+ /**
+ * The index of the dictionary in the original list of dictionaries used for the lookup.
+ */
+ dictionaryIndex: number;
+ /**
+ * The priority of the dictionary.
+ */
+ dictionaryPriority: number;
+ /**
+ * The pitch accent representations for the term.
+ */
+ pitches: TermPitch[];
+};
+
+/**
+ * Pitch accent information for a term, represented as the position of the downstep.
+ */
+export type TermPitch = {
+ /**
+ * Position of the downstep, as a number of mora.
+ */
+ position: number;
+ /**
+ * Positions of morae with a nasal sound.
+ */
+ nasalPositions: number[];
+ /**
+ * Positions of morae with a devoiced sound.
+ */
+ devoicePositions: number[];
+ /**
+ * Tags for the pitch accent.
+ */
+ tags: Tag[];
+};
+
+/**
+ * Frequency information corresponds to how frequently a term appears in a corpus,
+ * which can be a number of occurrences or an overall rank.
+ */
+export type TermFrequency = {
+ /**
+ * The original order of the frequency, which is usually used for sorting.
+ */
+ index: number;
+ /**
+ * Which headword this frequency corresponds to.
+ */
+ headwordIndex: number;
+ /**
+ * The name of the dictionary that the frequency information originated from.
+ */
+ dictionary: string;
+ /**
+ * The index of the dictionary in the original list of dictionaries used for the lookup.
+ */
+ dictionaryIndex: number;
+ /**
+ * The priority of the dictionary.
+ */
+ dictionaryPriority: number;
+ /**
+ * Whether or not the frequency had an explicit reading specified.
+ */
+ hasReading: boolean;
+ /**
+ * The frequency for the term, as a number of occurrences or an overall rank.
+ */
+ frequency: number;
+ /**
+ * A display value to show to the user.
+ */
+ displayValue: string | null;
+ /**
+ * Whether or not the displayValue string was parsed to determine the frequency value.
+ */
+ displayValueParsed: boolean;
+};
+
+/**
+ * Enum representing how the search term relates to the final term.
+ */
+export type TermSourceMatchType = 'exact' | 'prefix' | 'suffix';
+
+/**
+ * Enum representing what database field was used to match the source term.
+ */
+export type TermSourceMatchSource = 'term' | 'reading' | 'sequence';
+
+/**
+ * Source information represents how the original text was transformed to get to the final term.
+ */
+export type TermSource = {
+ /**
+ * The original text that was searched.
+ */
+ originalText: string;
+ /**
+ * The original text after being transformed, but before applying deinflections.
+ */
+ transformedText: string;
+ /**
+ * The final text after applying deinflections.
+ */
+ deinflectedText: string;
+ /**
+ * How the deinflected text matches the value from the database.
+ */
+ matchType: TermSourceMatchType;
+ /**
+ * Which field was used to match the database entry.
+ */
+ matchSource: TermSourceMatchSource;
+ /**
+ * Whether or not this source is a primary source. Primary sources are derived from the
+ * original search text, while non-primary sources originate from related terms.
+ */
+ isPrimary: boolean;
+};
diff --git a/types/ext/display-anki.d.ts b/types/ext/display-anki.d.ts
new file mode 100644
index 00000000..cc59a5c3
--- /dev/null
+++ b/types/ext/display-anki.d.ts
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Anki from './anki';
+import type * as AnkiNoteBuilder from './anki-note-builder';
+import type * as AnkiTemplates from './anki-templates';
+import type * as AnkiTemplatesInternal from './anki-templates-internal';
+
+export type CreateMode = AnkiTemplatesInternal.CreateModeNoTest;
+
+export type LogData = {
+ ankiNoteData: AnkiTemplates.NoteData | undefined;
+ ankiNoteDataException: Error | undefined;
+ ankiNotes: AnkiNoteLogData[];
+};
+
+export type AnkiNoteLogData = {
+ mode: CreateMode;
+ note: Anki.Note | undefined;
+ errors?: Error[];
+ requirements?: AnkiNoteBuilder.Requirement[];
+};
+
+export type DictionaryEntryDetails = {
+ modeMap: Map<CreateMode, DictionaryEntryModeDetails>;
+};
+
+export type DictionaryEntryModeDetails = {
+ mode: CreateMode;
+ note: Anki.Note;
+ errors: Error[];
+ requirements: AnkiNoteBuilder.Requirement[];
+ canAdd: boolean;
+ valid: boolean;
+ noteIds: Anki.NoteId[] | null;
+ noteInfos?: (Anki.NoteInfo | null)[];
+ ankiError: Error | null;
+};
+
+export type CreateNoteResult = {
+ note: Anki.Note;
+ errors: Error[];
+ requirements: AnkiNoteBuilder.Requirement[];
+};
diff --git a/types/ext/display-audio.d.ts b/types/ext/display-audio.d.ts
new file mode 100644
index 00000000..c9590cf2
--- /dev/null
+++ b/types/ext/display-audio.d.ts
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type {TextToSpeechAudio} from '../../ext/js/media/text-to-speech-audio';
+import type * as Audio from './audio';
+import type * as AudioDownloader from './audio-downloader';
+import type * as Settings from './settings';
+
+export type CacheItem = {
+ sourceMap: Map<number, CachedInfoList>;
+ primaryCardAudio: PrimaryCardAudio | null;
+};
+
+export type CachedInfoList = {
+ infoListPromise: Promise<AudioInfoList>;
+ infoList: AudioInfoList | null;
+};
+
+export type AudioInfoList = AudioInfoListItem[];
+
+export type AudioInfoListItem = {
+ info: AudioDownloader.Info;
+ audioPromise: Promise<GenericAudio> | null;
+ audioResolved: boolean;
+ audio: GenericAudio | null;
+};
+
+export type PrimaryCardAudio = {
+ index: number;
+ subIndex: number | null;
+};
+
+export type SourceInfo = {
+ source: AudioSource | null;
+ subIndex: number | null;
+};
+
+export type AudioSource = {
+ index: number;
+ type: Settings.AudioSourceType;
+ url: string;
+ voice: string;
+ isInOptions: boolean;
+ downloadable: boolean;
+ name: string;
+ nameIndex: number;
+ nameUnique: boolean;
+};
+
+export type AudioSourceShort = {
+ type: Settings.AudioSourceType;
+ url: string;
+ voice: string;
+};
+
+export type AudioMediaOptions = {
+ sources: Audio.AudioSourceInfo[];
+ preferredAudioIndex: number | null;
+};
+
+export type PlayAudioResult = {
+ audio: GenericAudio | null;
+ source: AudioSource | null;
+ subIndex: number;
+ valid: boolean;
+};
+
+export type TermAudio = {
+ audio: GenericAudio;
+ source: AudioSource;
+ subIndex: number;
+};
+
+export type CreateAudioResult = {
+ audio: GenericAudio | null;
+ index: number;
+ cacheUpdated: boolean;
+};
+
+export type GenericAudio = HTMLAudioElement | TextToSpeechAudio;
+
+export type MenuItemEntry = {
+ valid: boolean | null;
+ index: number | null;
+ name: string | null;
+};
diff --git a/types/ext/display-content-manager.d.ts b/types/ext/display-content-manager.d.ts
new file mode 100644
index 00000000..dc2269cf
--- /dev/null
+++ b/types/ext/display-content-manager.d.ts
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as DictionaryDatabase from './dictionary-database';
+
+/** A callback used when a media file has been loaded. */
+export type OnLoadCallback = (
+ /** The URL of the media that was loaded. */
+ url: string,
+) => void;
+
+/** A callback used when a media file should be unloaded. */
+export type OnUnloadCallback = (
+ /** Whether or not the media was fully loaded. */
+ fullyLoaded: boolean,
+) => void;
+
+export type CachedMediaDataLoaded = {
+ data: DictionaryDatabase.MediaDataStringContent;
+ url: string;
+};
+
+export type LoadMediaDataInfo = {
+ onUnload: OnUnloadCallback;
+ loaded: boolean;
+}; \ No newline at end of file
diff --git a/types/ext/display-history.d.ts b/types/ext/display-history.d.ts
new file mode 100644
index 00000000..2ba5006b
--- /dev/null
+++ b/types/ext/display-history.d.ts
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Display from './display';
+
+export type Entry = {
+ id: string;
+ url: string;
+ next: Entry | null;
+ previous: Entry | null;
+ state: EntryState | null;
+ content: EntryContent | null;
+};
+
+export type EntryState = Display.HistoryState;
+
+export type EntryContent = Display.HistoryContent;
+
+export type EventType = 'stateChanged';
+
+export type StateChangedEvent = {
+ synthetic: boolean;
+};
diff --git a/types/ext/display.d.ts b/types/ext/display.d.ts
new file mode 100644
index 00000000..aa0f0353
--- /dev/null
+++ b/types/ext/display.d.ts
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type {DisplayContentManager} from '../../ext/js/display/display-content-manager';
+import type {HotkeyHelpController} from '../../ext/js/input/hotkey-help-controller';
+import type {JapaneseUtil} from '../../ext/js/language/sandbox/japanese-util';
+import type {TextScanner} from '../../ext/js/language/text-scanner';
+import type * as Core from './core';
+import type * as Dictionary from './dictionary';
+import type * as Extension from './extension';
+import type * as Settings from './settings';
+import type * as TextScannerTypes from './text-scanner';
+import type * as TextSource from './text-source';
+
+export type HistoryMode = 'clear' | 'overwrite' | 'new';
+
+export type DisplayPageType = 'search' | 'popup';
+
+export type PageType = 'terms' | 'kanji' | 'unloaded' | 'clear';
+
+/**
+ * Information about how popup content should be shown, specifically related to the inner popup content.
+ */
+export type ContentDetails = {
+ /** Whether or not the frame should be `focus()`'d. */
+ focus: boolean;
+ /** An object containing key-value pairs representing the URL search params. */
+ params: HistoryParams;
+ /** The semi-persistent state assigned to the navigation entry. */
+ state: HistoryState | null;
+ /** The non-persistent content assigned to the navigation entry. */
+ content: HistoryContent | null;
+ /** How the navigation history should be modified. */
+ historyMode: HistoryMode;
+};
+
+/**
+ * An object containing key-value pairs representing the URL search params.
+ */
+export type HistoryParams = {
+ /** The type of content that is being shown. */
+ type?: PageType;
+ /** The search query. */
+ query?: string;
+ /** Whether or not wildcards can be used for the search query. */
+ wildcards?: 'on' | 'off';
+ /** The start position of the `query` string as an index into the `full` query string. */
+ offset?: string;
+ /** The full search text. If absent, `query` is the full search text. */
+ full?: string;
+ /** Whether or not the full search query should be forced to be visible. */
+ ['full-visible']?: 'true' | 'false';
+ /** Whether or not the query should be looked up. If it is not looked up, the content should be provided. */
+ lookup?: 'true' | 'false';
+ /** Other values; only used for assignment. */
+ [otherKey: string]: unknown;
+};
+
+/**
+ * The semi-persistent state assigned to the navigation entry.
+ */
+export type HistoryState = {
+ /** What was the cause of the navigation. */
+ cause?: 'queryParser';
+ /** The sentence context. */
+ sentence?: HistoryStateSentence;
+ /** The index of the dictionary entry to focus. */
+ focusEntry?: number;
+ /** The horizontal scroll position. */
+ scrollX?: number;
+ /** The vertical scroll position. */
+ scrollY?: number;
+ /** The options context which should be used for lookups. */
+ optionsContext?: Settings.OptionsContext;
+ /** The originating URL of the content. */
+ url?: string;
+ /** The originating document title of the content. */
+ documentTitle?: string;
+};
+
+/**
+ * The sentence context.
+ */
+export type HistoryStateSentence = {
+ /** The full string. */
+ text: string;
+ /** The offset from the start of `text` to the full search query. */
+ offset: number;
+};
+
+/**
+ * The non-persistent content assigned to the navigation entry.
+ */
+export type HistoryContent = {
+ /** Whether or not any CSS animations should occur. */
+ animate?: boolean;
+ /** An array of dictionary entries to display as content. */
+ dictionaryEntries?: Dictionary.DictionaryEntry[];
+ /** The identifying information for the frame the content originated from. */
+ contentOrigin?: Extension.ContentOrigin;
+};
+
+export type SearchPersistentStateControllerEventType = 'modeChange';
+
+export type SearchMode = null | 'popup' | 'action-popup';
+
+export type GetSearchContextCallback = TextScannerTypes.GetSearchContextCallbackSync;
+
+export type QueryParserConstructorDetails = {
+ getSearchContext: GetSearchContextCallback;
+ japaneseUtil: JapaneseUtil;
+};
+
+export type QueryParserOptions = {
+ selectedParser: string | null;
+ termSpacing: boolean;
+ readingMode: Settings.ParsingReadingMode;
+ useInternalParser: boolean;
+ useMecabParser: boolean;
+ scanning: TextScannerTypes.Options;
+};
+
+export type QueryParserEventType = 'searched';
+
+export type QueryParserSearchedEvent = {
+ textScanner: TextScanner;
+ type: PageType;
+ dictionaryEntries: Dictionary.DictionaryEntry[];
+ sentence: HistoryStateSentence;
+ inputInfo: TextScannerTypes.InputInfo;
+ textSource: TextSource.TextSource;
+ optionsContext: Settings.OptionsContext;
+ sentenceOffset: number | null;
+};
+
+export type DisplayEventType = (
+ 'optionsUpdated' |
+ 'frameVisibilityChange' |
+ 'logDictionaryEntryData' |
+ 'contentClear' |
+ 'contentUpdateStart' |
+ 'contentUpdateEntry' |
+ 'contentUpdateComplete'
+);
+
+export type OptionsUpdatedEvent = {
+ options: Settings.ProfileOptions;
+};
+
+export type FrameVisibilityChangeEvent = {
+ value: boolean;
+};
+
+export type LogDictionaryEntryDataEvent = {
+ dictionaryEntry: Dictionary.DictionaryEntry;
+ promises: Promise<unknown>[];
+};
+
+export type ContentUpdateStartEvent = {
+ type: PageType;
+ query: string;
+};
+
+export type ContentUpdateEntryEvent = {
+ dictionaryEntry: Dictionary.DictionaryEntry;
+ element: Element;
+ index: number;
+};
+
+export type ContentUpdateCompleteEvent = {
+ type: PageType;
+};
+
+export type ConfigureMessageDetails = {
+ depth: number;
+ parentPopupId: string;
+ parentFrameId: number;
+ childrenSupported: boolean;
+ scale: number;
+ optionsContext: Settings.OptionsContext;
+};
+
+export type MessageDetails = {
+ action: string;
+ params: Core.SerializableObject;
+};
+
+export type DisplayGeneratorConstructorDetails = {
+ japaneseUtil: JapaneseUtil;
+ contentManager: DisplayContentManager;
+ hotkeyHelpController?: HotkeyHelpController | null;
+};
diff --git a/types/ext/document-util.d.ts b/types/ext/document-util.d.ts
new file mode 100644
index 00000000..aa655a67
--- /dev/null
+++ b/types/ext/document-util.d.ts
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as TextSource from './text-source';
+
+export type NormalizedWritingMode = 'horizontal-tb' | 'vertical-rl' | 'vertical-lr' | 'sideways-rl' | 'sideways-lr';
+
+/**
+ * Options to configure how element detection is performed.
+ */
+export type GetRangeFromPointOptions = {
+ /**
+ * Whether or deep content scanning should be performed. When deep content scanning is enabled,
+ * some transparent overlay elements will be ignored when looking for the element at the input position.
+ */
+ deepContentScan: boolean;
+ /**
+ * Whether or not zoom coordinates should be normalized.
+ */
+ normalizeCssZoom: boolean;
+};
+
+/**
+ * Scans the document for text or elements with text information at the given coordinate.
+ * Coordinates are provided in [client space](https://developer.mozilla.org/en-US/docs/Web/CSS/CSSOM_View/Coordinate_systems).
+ * @returns A range for the hovered text or element, or `null` if no applicable content was found.
+ */
+export type GetRangeFromPointHandler = (
+ /** The x coordinate to search at. */
+ x: number,
+ /** The y coordinate to search at. */
+ y: number,
+ /** Options to configure how element detection is performed. */
+ options: GetRangeFromPointOptions,
+) => (TextSource.TextSource | null);
+
+export type ToNumberConstraints = {
+ min?: string | number;
+ max?: string | number;
+ step?: string | number;
+};
diff --git a/types/ext/dom-data-binder.d.ts b/types/ext/dom-data-binder.d.ts
new file mode 100644
index 00000000..ca0036c3
--- /dev/null
+++ b/types/ext/dom-data-binder.d.ts
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as TaskAccumulator from './task-accumulator';
+
+export type CreateElementMetadataCallback<T> = (element: Element) => T | undefined;
+
+export type CompareElementMetadataCallback<T> = (metadata1: T, metadata2: T) => boolean;
+
+export type GetValuesCallback<T> = (args: GetValuesDetails<T>[]) => Promise<TaskResult[]>;
+
+export type SetValuesCallback<T> = (args: SetValuesDetails<T>[]) => Promise<TaskResult[]>;
+
+export type GetValuesDetails<T> = {
+ element: Element;
+ metadata: T;
+};
+
+export type SetValuesDetails<T> = {
+ element: Element;
+ metadata: T;
+ value: ValueType;
+};
+
+export type OnErrorCallback<T> = (error: Error, stale: boolean, element: Element, metadata: T) => void;
+
+export type ConstructorDetails<T> = {
+ selector: string;
+ createElementMetadata: CreateElementMetadataCallback<T>;
+ compareElementMetadata: CompareElementMetadataCallback<T>;
+ getValues: GetValuesCallback<T>;
+ setValues: SetValuesCallback<T>;
+ onError?: OnErrorCallback<T> | null;
+};
+
+export type ElementObserver<T> = {
+ element: Element;
+ type: NormalizedElementType;
+ value: unknown;
+ hasValue: boolean;
+ onChange: null | (() => void);
+ metadata: T;
+};
+
+export type SettingChangedEventData = {
+ value: boolean | string | number;
+};
+
+export type SettingChangedEvent = CustomEvent<SettingChangedEventData>;
+
+export type NormalizedElementType = 'textarea' | 'select' | 'text' | 'checkbox' | 'number' | null;
+
+export type UpdateTaskValue = {all: boolean};
+
+export type AssignTaskValue = {value: ValueType};
+
+export type ValueType = boolean | string | number | null;
+
+export type UpdateTask<T> = [
+ key: ElementObserver<T> | null,
+ task: TaskAccumulator.Task<UpdateTaskValue>,
+];
+
+export type AssignTask<T> = [
+ key: ElementObserver<T> | null,
+ task: TaskAccumulator.Task<AssignTaskValue>,
+];
+
+export type ApplyTarget<T> = [
+ observer: ElementObserver<T>,
+ task: TaskAccumulator.Task<UpdateTaskValue> | TaskAccumulator.Task<AssignTaskValue> | null,
+];
+
+export type TaskResultError = {
+ error: Error;
+ result?: undefined;
+};
+
+export type TaskResultSuccess<T = unknown> = {
+ error?: undefined;
+ result: T;
+};
+
+export type TaskResult<T = unknown> = TaskResultError | TaskResultSuccess<T>;
diff --git a/types/ext/dynamic-loader.d.ts b/types/ext/dynamic-loader.d.ts
new file mode 100644
index 00000000..49011db0
--- /dev/null
+++ b/types/ext/dynamic-loader.d.ts
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type DynamicLoaderSentinelDetails = {
+ scriptUrl: string;
+};
diff --git a/types/ext/dynamic-property.d.ts b/types/ext/dynamic-property.d.ts
new file mode 100644
index 00000000..5ec886d2
--- /dev/null
+++ b/types/ext/dynamic-property.d.ts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type EventType = 'change';
+
+export type ChangeEventDetails<T> = {
+ value: T;
+};
diff --git a/types/ext/environment.d.ts b/types/ext/environment.d.ts
new file mode 100644
index 00000000..9c0f5bf6
--- /dev/null
+++ b/types/ext/environment.d.ts
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type Info = {
+ browser: Browser;
+ platform: {os: OperatingSystem};
+};
+
+export type Browser = 'chrome' | 'firefox' | 'firefox-mobile' | 'edge' | 'edge-legacy' | 'safari';
+
+export type OperatingSystem = chrome.runtime.PlatformOs | 'unknown';
diff --git a/types/ext/event-listener-collection.d.ts b/types/ext/event-listener-collection.d.ts
new file mode 100644
index 00000000..988baa76
--- /dev/null
+++ b/types/ext/event-listener-collection.d.ts
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type {EventDispatcher} from '../../ext/js/core';
+import type * as Core from './core';
+
+export type EventListenerFunction = (...args: Core.SafeAny[]) => unknown;
+
+export type EventTarget = {
+ addEventListener(
+ type: string,
+ listener: EventListener | EventListenerObject | EventListenerFunction,
+ options?: AddEventListenerOptions | boolean,
+ ): void;
+ removeEventListener(
+ type: string,
+ listener: EventListener | EventListenerObject | EventListenerFunction,
+ options?: EventListenerOptions | boolean,
+ ): void;
+};
+
+export type ExtensionEvent<TCallback = EventListenerFunction, TArgs = unknown> = {
+ addListener(callback: TCallback, ...args: TArgs[]): void;
+ removeListener(callback: TCallback, ...args: TArgs[]): void;
+};
+
+export type EventTargetDetails = {
+ type: 'removeEventListener';
+ target: EventTarget;
+ eventName: string;
+ listener: EventListener | EventListenerObject | EventListenerFunction;
+ options: EventListenerOptions | boolean | undefined;
+};
+
+export type ExtensionEventDetails = {
+ type: 'removeListener';
+ target: ExtensionEvent;
+ callback: EventListenerFunction;
+ args: unknown[];
+};
+
+export type EventDispatcherDetails = {
+ type: 'off';
+ target: EventDispatcher<string>;
+ eventName: string;
+ callback: EventListenerFunction;
+};
+
+export type EventListenerDetails = EventTargetDetails | ExtensionEventDetails | EventDispatcherDetails;
+
+export type AddEventListenerArgs = [
+ target: EventTarget,
+ type: string,
+ listener: EventListener | EventListenerObject | EventListenerFunction,
+ options?: AddEventListenerOptions | boolean,
+];
+
+export type OnArgs = [
+ target: EventDispatcher<string>,
+ eventName: string,
+ callback: (details: Core.SafeAny) => void,
+];
diff --git a/types/ext/extension.d.ts b/types/ext/extension.d.ts
new file mode 100644
index 00000000..1c86a4ca
--- /dev/null
+++ b/types/ext/extension.d.ts
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Core from './core';
+
+export type ChromeRuntimeSendMessageArgs1 = [
+ message: Core.SafeAny,
+];
+
+export type ChromeRuntimeSendMessageArgs2 = [
+ message: Core.SafeAny,
+ responseCallback: (response: Core.SafeAny) => void,
+];
+
+export type ChromeRuntimeSendMessageArgs3 = [
+ message: Core.SafeAny,
+ options: chrome.runtime.MessageOptions,
+ responseCallback: (response: Core.SafeAny) => void,
+];
+
+export type ChromeRuntimeSendMessageArgs4 = [
+ extensionId: string | undefined | null,
+ message: Core.SafeAny,
+ responseCallback: (response: Core.SafeAny) => void,
+];
+
+export type ChromeRuntimeSendMessageArgs5 = [
+ extensionId: string | undefined | null,
+ message: Core.SafeAny,
+ options: chrome.runtime.MessageOptions,
+ responseCallback: (response: Core.SafeAny) => void,
+];
+
+export type ChromeRuntimeSendMessageArgs = ChromeRuntimeSendMessageArgs1 | ChromeRuntimeSendMessageArgs2 | ChromeRuntimeSendMessageArgs3 | ChromeRuntimeSendMessageArgs4 | ChromeRuntimeSendMessageArgs5;
+
+export type ExtensionEventType = 'extensionUnloaded' | 'optionsUpdated' | 'databaseUpdated' | 'zoomChanged' | 'closePopups' | 'dynamicLoaderSentinel' | 'storageChanged';
+
+export type HtmlElementWithContentWindow = HTMLIFrameElement | HTMLFrameElement | HTMLObjectElement;
+
+export type ContentOrigin = {
+ tabId?: number;
+ frameId?: number;
+};
+
+export type ChromeRuntimeMessage = {
+ action: string;
+ params?: Core.SerializableObject;
+};
+
+export type ChromeRuntimeMessageWithFrameId = ChromeRuntimeMessage & {
+ frameId?: number;
+};
+
+export type ChromeRuntimeOnMessageCallback<TMessage = ChromeRuntimeMessage> = (
+ message: TMessage,
+ sender: chrome.runtime.MessageSender,
+ sendResponse: ChromeRuntimeMessageSendResponseFunction,
+) => boolean | void;
+
+export type ChromeRuntimeMessageSendResponseFunction = (response?: unknown) => void;
diff --git a/types/ext/frame-ancestry-handler.d.ts b/types/ext/frame-ancestry-handler.d.ts
new file mode 100644
index 00000000..3c9e32bf
--- /dev/null
+++ b/types/ext/frame-ancestry-handler.d.ts
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type RequestFrameInfoResponseParams = {
+ frameId: number;
+ nonce: string;
+ more: boolean;
+};
+
+export type RequestFrameInfoResponseReturn = {
+ nonce: string;
+};
diff --git a/types/ext/frame-client.d.ts b/types/ext/frame-client.d.ts
new file mode 100644
index 00000000..54d0d880
--- /dev/null
+++ b/types/ext/frame-client.d.ts
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Extension from './extension';
+
+export type Message<T = unknown> = {
+ token: string;
+ secret: string;
+ data: T;
+};
+
+export type SetupFrameFunction = (frame: Extension.HtmlElementWithContentWindow) => void;
+
+export type FrameEndpointReadyDetails = {
+ secret: string;
+};
+
+export type FrameEndpointConnectedDetails = {
+ secret: string;
+ token: string;
+};
diff --git a/types/ext/frame-offset-forwarder.d.ts b/types/ext/frame-offset-forwarder.d.ts
new file mode 100644
index 00000000..6cc0aef2
--- /dev/null
+++ b/types/ext/frame-offset-forwarder.d.ts
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type ChildFrameRect = {
+ x: number;
+ y: number;
+ width: number;
+ height: number;
+};
diff --git a/types/ext/frontend.d.ts b/types/ext/frontend.d.ts
new file mode 100644
index 00000000..73b24dc3
--- /dev/null
+++ b/types/ext/frontend.d.ts
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type {PopupFactory} from '../../ext/js/app/popup-factory';
+import type {HotkeyHandler} from '../../ext/js/input/hotkey-handler';
+
+/** Details about how to set up the instance. */
+export type ConstructorDetails = {
+ /** The type of page, one of 'web', 'popup', or 'search'. */
+ pageType: PageType;
+ /** A PopupFactory instance to use for generating popups. */
+ popupFactory: PopupFactory;
+ /** The nesting depth value of the popup. */
+ depth: number;
+ /** The tab ID of the host tab. */
+ tabId: number | undefined;
+ /** The frame ID of the host frame. */
+ frameId: number;
+ /** The popup ID of the parent popup if one exists, otherwise null. */
+ parentPopupId: string | null;
+ /** The frame ID of the parent popup if one exists, otherwise null. */
+ parentFrameId: number | null;
+ /** Whether or not proxy popups should be used. */
+ useProxyPopup: boolean;
+ /** Whether or not window popups can be used. */
+ canUseWindowPopup?: boolean;
+ /** Whether or not popups can be hosted in the root frame. */
+ allowRootFramePopupProxy: boolean;
+ /** Whether popups can create child popups or not. */
+ childrenSupported?: boolean;
+ /** A HotkeyHandler instance. */
+ hotkeyHandler: HotkeyHandler;
+};
+
+export type PageType = 'web' | 'popup' | 'search';
+
+export type FrontendRequestReadyBroadcastParams = {
+ frameId: number;
+};
+
+export type GetPopupInfoResult = {
+ popupId: string | null;
+};
+
+export type FrontendReadyDetails = {
+ frameId: number;
+};
diff --git a/types/ext/generic-setting-controller.d.ts b/types/ext/generic-setting-controller.d.ts
new file mode 100644
index 00000000..f7a2be5f
--- /dev/null
+++ b/types/ext/generic-setting-controller.d.ts
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as DocumentUtil from './document-util';
+import type * as SettingsModifications from './settings-modifications';
+
+export type TransformType = TransformData['type'];
+
+export type ElementMetadata = {
+ path: string;
+ scope: SettingsModifications.OptionsScopeType | undefined;
+ transforms: TransformData[];
+ transformRaw: string | undefined;
+};
+
+export type TransformFunction = (
+ value: unknown,
+ data: TransformData,
+ element: Element,
+) => unknown;
+
+export type TransformStep = 'pre' | 'post';
+
+export type TransformData = (
+ SetAttributeTransformData |
+ SetVisibilityTransformData |
+ SplitTagsTransformData |
+ JoinTagsTransformData |
+ ToNumberConstraintsTransformData |
+ ToBooleanTransformData |
+ ToStringTransformData |
+ ConditionalConvertTransformData
+);
+
+export type TransformDataBase = {
+ step?: TransformStep;
+};
+
+export type SetAttributeTransformData = TransformDataBase & {
+ type: 'setAttribute';
+ ancestorDistance?: number;
+ selector?: string;
+ attribute: string;
+};
+
+export type SetVisibilityTransformData = TransformDataBase & {
+ type: 'setVisibility';
+ ancestorDistance?: number;
+ selector?: string;
+ condition: OperationData;
+};
+
+export type SplitTagsTransformData = TransformDataBase & {
+ type: 'splitTags';
+};
+
+export type JoinTagsTransformData = TransformDataBase & {
+ type: 'joinTags';
+};
+
+export type ToNumberConstraintsTransformData = TransformDataBase & {
+ type: 'toNumber';
+ constraints?: DocumentUtil.ToNumberConstraints;
+};
+
+export type ToBooleanTransformData = TransformDataBase & {
+ type: 'toBoolean';
+};
+
+export type ToStringTransformData = TransformDataBase & {
+ type: 'toString';
+};
+
+export type ConditionalConvertTransformData = TransformDataBase & {
+ type: 'conditionalConvert';
+ cases?: ConditionalConvertCase[];
+};
+
+export type ConditionalConvertCase = {
+ default?: boolean;
+ result: unknown;
+} & OperationData;
+
+export type OperationData = {
+ op: string;
+ value: unknown;
+};
diff --git a/types/ext/hotkey-handler.d.ts b/types/ext/hotkey-handler.d.ts
new file mode 100644
index 00000000..7b2b4cb3
--- /dev/null
+++ b/types/ext/hotkey-handler.d.ts
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Input from './input';
+
+export type EventType = 'keydownNonHotkey';
+
+export type HotkeyInfo = {
+ modifiers: Set<Input.ModifierKey>;
+ action: string;
+ argument: unknown;
+};
+
+export type HotkeyHandlers = {
+ handlers: HotkeyInfo[];
+};
diff --git a/types/ext/input.d.ts b/types/ext/input.d.ts
new file mode 100644
index 00000000..fbcb4df3
--- /dev/null
+++ b/types/ext/input.d.ts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type ModifierKey = 'alt' | 'ctrl' | 'meta' | 'shift';
+export type ModifierMouseButton = 'mouse0' | 'mouse1' | 'mouse2' | 'mouse3' | 'mouse4' | 'mouse5';
+export type Modifier = ModifierKey | ModifierMouseButton;
+export type ModifierType = 'key' | 'mouse';
diff --git a/types/ext/japanese-util.d.ts b/types/ext/japanese-util.d.ts
new file mode 100644
index 00000000..c2d2c411
--- /dev/null
+++ b/types/ext/japanese-util.d.ts
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type CodepointRange = [
+ minInclusive: number,
+ maxInclusive: number,
+];
+
+export type FuriganaGroup = {
+ isKana: boolean;
+ text: string;
+ textNormalized: string | null;
+};
+
+export type FuriganaSegment = {
+ text: string;
+ reading: string;
+};
+
+export type PitchCategory = (
+ 'heiban' |
+ 'kifuku' |
+ 'atamadaka' |
+ 'odaka' |
+ 'nakadaka'
+);
+
+export type DiacriticType = 'dakuten' | 'handakuten';
diff --git a/types/ext/json-schema.d.ts b/types/ext/json-schema.d.ts
new file mode 100644
index 00000000..c959628b
--- /dev/null
+++ b/types/ext/json-schema.d.ts
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type ValueObject = {[key: string]: Value};
+
+export type Value = string | number | boolean | null | Value[] | ValueObject;
+
+export type ValueObjectOrArray = ValueObject | Value[];
+
+export type Type = 'string' | 'number' | 'integer' | 'object' | 'array' | 'boolean' | 'null';
+
+export type SchemaObject = {
+ type?: Type | Type[];
+ required?: string[];
+
+ default?: Value;
+ enum?: Value[];
+ const?: Value;
+ minimum?: number;
+ maximum?: number;
+ exclusiveMinimum?: number;
+ exclusiveMaximum?: number;
+ multipleOf?: number;
+ minLength?: number;
+ maxLength?: number;
+ pattern?: string;
+ patternFlags?: string;
+ minItems?: number;
+ maxItems?: number;
+ minProperties?: number;
+ maxProperties?: number;
+ definitions?: {[key: string]: Schema};
+
+ $ref?: string;
+
+ properties?: {[key: string]: Schema};
+ additionalProperties?: Schema;
+ not?: Schema;
+ oneOf?: Schema[];
+ allOf?: Schema[];
+ anyOf?: Schema[];
+ contains?: Schema;
+ prefixItems?: Schema[];
+ items?: Schema | Schema[]; // Legacy schema format for the array
+ additionalItems?: Schema;
+ if?: Schema;
+ then?: Schema;
+ else?: Schema;
+};
+
+export type Schema = SchemaObject | true | false;
+
+export type SchemaStackItem = {
+ schema: Schema | Schema[];
+ path: string | number | null;
+};
+
+export type ValueStackItem = {
+ value: unknown;
+ path: string | number | null;
+};
diff --git a/types/ext/keyboard-mouse-input-field.d.ts b/types/ext/keyboard-mouse-input-field.d.ts
new file mode 100644
index 00000000..321e49cc
--- /dev/null
+++ b/types/ext/keyboard-mouse-input-field.d.ts
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Input from './input';
+
+export type EventType = 'change';
+
+export type ChangeEvent = {
+ key: string | null;
+ modifiers: Input.Modifier[];
+};
diff --git a/types/ext/keyboard-shortcut-controller.d.ts b/types/ext/keyboard-shortcut-controller.d.ts
new file mode 100644
index 00000000..0f276ce9
--- /dev/null
+++ b/types/ext/keyboard-shortcut-controller.d.ts
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Settings from './settings';
+
+export type ActionDetails = {
+ scopes: Set<Settings.InputsHotkeyScope>;
+ argument?: {
+ template: string;
+ default: string;
+ };
+};
diff --git a/types/ext/log.d.ts b/types/ext/log.d.ts
new file mode 100644
index 00000000..ac2f606b
--- /dev/null
+++ b/types/ext/log.d.ts
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type LogLevel = 'log' | 'info' | 'debug' | 'warn' | 'error';
+
+export type LoggerEventType = 'log';
+
+export type LogContext = {
+ url: string;
+};
diff --git a/types/ext/mecab.d.ts b/types/ext/mecab.d.ts
new file mode 100644
index 00000000..bcbd476f
--- /dev/null
+++ b/types/ext/mecab.d.ts
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type ParseResultRaw = {
+ [key: string]: ParseResultLineRaw[];
+};
+
+export type ParseResultLineRaw = ParseResultTermRaw[];
+
+export type ParseResultTermRaw = {
+ expression?: string;
+ reading?: string;
+ source?: string;
+};
+
+/** The resulting data from an invocation of `parseText`. */
+export type ParseResult = {
+ /** The dictionary name for the parsed result. */
+ name: string;
+ /** The resulting parsed terms. */
+ lines: ParseFragment[][];
+};
+
+/** A fragment of the parsed text. */
+export type ParseFragment = {
+ /** The term. */
+ term: string;
+ /** The reading of the term. */
+ reading: string;
+ /** The source text. */
+ source: string;
+};
diff --git a/types/ext/offscreen.d.ts b/types/ext/offscreen.d.ts
new file mode 100644
index 00000000..85bce1ff
--- /dev/null
+++ b/types/ext/offscreen.d.ts
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Core from './core';
+import type * as Deinflector from './deinflector';
+import type * as Dictionary from './dictionary';
+import type * as DictionaryDatabase from './dictionary-database';
+import type * as DictionaryImporter from './dictionary-importer';
+import type * as Environment from './environment';
+import type * as Translation from './translation';
+import type * as Translator from './translator';
+
+export type Message<T extends MessageType> = (
+ MessageDetailsMap[T] extends undefined ?
+ {action: T} :
+ {action: T, params: MessageDetailsMap[T]}
+);
+
+export type MessageReturn<T extends MessageType> = MessageReturnMap[T];
+
+type MessageDetailsMap = {
+ databasePrepareOffscreen: undefined;
+ getDictionaryInfoOffscreen: undefined;
+ databasePurgeOffscreen: undefined;
+ databaseGetMediaOffscreen: {
+ targets: DictionaryDatabase.MediaRequest[];
+ };
+ translatorPrepareOffscreen: {
+ deinflectionReasons: Deinflector.ReasonsRaw;
+ };
+ findKanjiOffscreen: {
+ text: string;
+ options: FindKanjiOptionsOffscreen;
+ };
+ findTermsOffscreen: {
+ mode: Translator.FindTermsMode;
+ text: string;
+ options: FindTermsOptionsOffscreen;
+ };
+ getTermFrequenciesOffscreen: {
+ termReadingList: Translator.TermReadingList;
+ dictionaries: string[];
+ };
+ clearDatabaseCachesOffscreen: undefined;
+ clipboardSetBrowserOffscreen: {
+ value: Environment.Browser | null;
+ };
+ clipboardGetTextOffscreen: {
+ useRichText: boolean;
+ };
+ clipboardGetImageOffscreen: undefined;
+};
+
+type MessageReturnMap = {
+ databasePrepareOffscreen: void;
+ getDictionaryInfoOffscreen: DictionaryImporter.Summary[];
+ databasePurgeOffscreen: boolean;
+ databaseGetMediaOffscreen: DictionaryDatabase.Media<string>[];
+ translatorPrepareOffscreen: void;
+ findKanjiOffscreen: Dictionary.KanjiDictionaryEntry[];
+ findTermsOffscreen: Translator.FindTermsResult;
+ getTermFrequenciesOffscreen: Translator.TermFrequencySimple[];
+ clearDatabaseCachesOffscreen: void;
+ clipboardSetBrowserOffscreen: void;
+ clipboardGetTextOffscreen: string;
+ clipboardGetImageOffscreen: string | null;
+};
+
+export type MessageType = keyof MessageDetailsMap;
+
+export type FindKanjiOptionsOffscreen = Omit<Translation.FindKanjiOptions, 'enabledDictionaryMap'> & {
+ enabledDictionaryMap: [
+ key: string,
+ options: Translation.FindKanjiDictionary,
+ ][];
+};
+
+
+export type FindTermsOptionsOffscreen = Omit<Translation.FindTermsOptions, 'enabledDictionaryMap' | 'excludeDictionaryDefinitions' | 'textReplacements'> & {
+ enabledDictionaryMap: [
+ key: string,
+ options: Translation.FindTermDictionary,
+ ][];
+ excludeDictionaryDefinitions: string[] | null;
+ textReplacements: (FindTermsTextReplacementOffscreen[] | null)[];
+};
+
+export type FindTermsTextReplacementOffscreen = Omit<Translation.FindTermsTextReplacement, 'pattern'> & {
+ pattern: string;
+};
+
+export type MessageHandler<
+ TMessage extends MessageType,
+ TIsAsync extends boolean,
+> = (
+ details: MessageDetailsMap[TMessage],
+) => (TIsAsync extends true ? Promise<MessageReturn<TMessage>> : MessageReturn<TMessage>);
+
+export type MessageHandlerMap<T = MessageType> = Map<T, Core.MessageHandlerDetails>;
diff --git a/types/ext/options-util.d.ts b/types/ext/options-util.d.ts
new file mode 100644
index 00000000..e03e4be2
--- /dev/null
+++ b/types/ext/options-util.d.ts
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Core from './core';
+
+export type LegacyOptions = Core.SafeAny;
+
+export type IntermediateOptions = Core.SafeAny;
+
+export type LegacyUpdateFunction = (options: LegacyOptions) => void;
+
+export type ModernUpdateFunction = ModernUpdateFunctionSync | ModernUpdateFunctionAsync;
+
+export type ModernUpdateFunctionSync = (options: IntermediateOptions) => IntermediateOptions;
+
+export type ModernUpdateFunctionAsync = (options: IntermediateOptions) => Promise<IntermediateOptions>;
+
+export type ModernUpdate = {
+ async: boolean;
+ update: ModernUpdateFunction;
+};
diff --git a/types/ext/panel-element.d.ts b/types/ext/panel-element.d.ts
new file mode 100644
index 00000000..d267b836
--- /dev/null
+++ b/types/ext/panel-element.d.ts
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type EventType = 'visibilityChanged' | 'closeCompleted';
+
+export type VisibilityChangedEvent = {
+ visible: boolean;
+};
+
+export type CloseCompletedEvent = {
+ reopening: boolean;
+};
+
+/* eslint-disable @stylistic/ts/indent */
+export type Event<T extends EventType> = (
+ T extends 'visibilityChanged' ? VisibilityChangedEvent :
+ T extends 'closeCompleted' ? CloseCompletedEvent :
+ never
+);
+/* eslint-enable @stylistic/ts/indent */
+
+export type ConstructorDetails = {
+ node: HTMLElement;
+ closingAnimationDuration: number;
+};
diff --git a/types/ext/popup-factory.d.ts b/types/ext/popup-factory.d.ts
new file mode 100644
index 00000000..a167a6f7
--- /dev/null
+++ b/types/ext/popup-factory.d.ts
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/** Details about how to acquire the popup. */
+export type GetOrCreatePopupDetails = {
+ /** The ID of the frame that should host the popup. */
+ frameId?: number | null;
+ /** A specific ID used to find an existing popup, or to assign to the new popup. */
+ id?: string | null;
+ /** The ID of the parent popup. */
+ parentPopupId?: string | null;
+ /** A specific depth value to assign to the popup. */
+ depth?: number | null;
+ /** Whether or not a separate popup window should be used, rather than an iframe. */
+ popupWindow?: boolean;
+ /** Whether or not the popup is able to show child popups. */
+ childrenSupported?: boolean;
+};
diff --git a/types/ext/popup-menu.d.ts b/types/ext/popup-menu.d.ts
new file mode 100644
index 00000000..b6e37316
--- /dev/null
+++ b/types/ext/popup-menu.d.ts
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type {PopupMenu} from '../../ext/js/dom/popup-menu';
+
+export type EventType = 'close';
+
+export type CloseReason = 'close' | 'outside' | 'item' | 'resize';
+
+export type MenuOpenEventDetails = {
+ menu: PopupMenu;
+};
+
+export type MenuCloseEventDetails = {
+ menu: PopupMenu;
+ item: HTMLElement | null;
+ action: string | null;
+ cause: CloseReason;
+ altKey: boolean;
+ ctrlKey: boolean;
+ metaKey: boolean;
+ shiftKey: boolean;
+};
+
+export type MenuOpenEvent = CustomEvent<MenuOpenEventDetails>;
+
+export type MenuCloseEvent = CustomEvent<MenuCloseEventDetails>;
diff --git a/types/ext/popup.d.ts b/types/ext/popup.d.ts
new file mode 100644
index 00000000..65725f96
--- /dev/null
+++ b/types/ext/popup.d.ts
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type {Popup} from '../../ext/js/app/popup';
+import type {PopupProxy} from '../../ext/js/app/popup-proxy';
+import type {PopupWindow} from '../../ext/js/app/popup-window';
+import type {FrameOffsetForwarder} from '../../ext/js/comm/frame-offset-forwarder';
+import type * as DocumentUtil from './document-util';
+import type * as Settings from './settings';
+
+export type PopupAny = Popup | PopupWindow | PopupProxy;
+
+/**
+ * Information about how popup content should be shown, specifically related to the outer popup frame.
+ */
+export type ContentDetails = {
+ /** The options context for the content to show. */
+ optionsContext: Settings.OptionsContext | null;
+ /** The rectangles of the source content. */
+ sourceRects: Rect[];
+ /** The normalized CSS writing-mode value of the source content. */
+ writingMode: DocumentUtil.NormalizedWritingMode;
+};
+
+/**
+ * A rectangle representing a DOM region, similar to DOMRect.
+ */
+export type Rect = {
+ /** The left position of the rectangle. */
+ left: number;
+ /** The top position of the rectangle. */
+ top: number;
+ /** The right position of the rectangle. */
+ right: number;
+ /** The bottom position of the rectangle. */
+ bottom: number;
+};
+
+/**
+ * A rectangle representing a DOM region, similar to DOMRect but with a `valid` property.
+ */
+export type ValidRect = {
+ /** The left position of the rectangle. */
+ left: number;
+ /** The top position of the rectangle. */
+ top: number;
+ /** The right position of the rectangle. */
+ right: number;
+ /** The bottom position of the rectangle. */
+ bottom: number;
+ /** Whether or not the rectangle is valid. */
+ valid: boolean;
+};
+
+/**
+ * A rectangle representing a DOM region for placing the popup frame.
+ */
+export type SizeRect = {
+ /** The left position of the rectangle. */
+ left: number;
+ /** The top position of the rectangle. */
+ top: number;
+ /** The width of the rectangle. */
+ width: number;
+ /** The height of the rectangle. */
+ height: number;
+ /** Whether or not the rectangle is positioned to the right of the source rectangle. */
+ after: boolean;
+ /** Whether or not the rectangle is positioned below the source rectangle. */
+ below: boolean;
+};
+
+export type ValidSize = {
+ width: number;
+ height: number;
+ valid: boolean;
+};
+
+export type CustomOuterCssChangedEvent = {
+ node: HTMLStyleElement | HTMLLinkElement | null;
+ useWebExtensionApi: boolean;
+ inShadow: boolean;
+};
+
+export type PopupAnyEventType = PopupEventType | PopupProxyEventType | PopupWindowEventType;
+
+export type PopupEventType = 'customOuterCssChanged' | 'framePointerOver' | 'framePointerOut' | 'offsetNotFound';
+
+export type PopupProxyEventType = 'offsetNotFound';
+
+export type PopupWindowEventType = never;
+
+export type PopupConstructorDetails = {
+ /** The ID of the popup. */
+ id: string;
+ /** The depth of the popup. */
+ depth: number;
+ /** The ID of the host frame. */
+ frameId: number;
+ /** Whether or not the popup is able to show child popups. */
+ childrenSupported: boolean;
+};
+
+export type PopupWindowConstructorDetails = {
+ /** The ID of the popup. */
+ id: string;
+ /** The depth of the popup. */
+ depth: number;
+ /** The ID of the host frame. */
+ frameId: number;
+};
+
+export type PopupProxyConstructorDetails = {
+ /** The ID of the popup. */
+ id: string;
+ /** The depth of the popup. */
+ depth: number;
+ /** The ID of the host frame. */
+ frameId: number;
+ /** A `FrameOffsetForwarder` instance which is used to determine frame positioning. */
+ frameOffsetForwarder: FrameOffsetForwarder | null;
+};
diff --git a/types/ext/profile-conditions-ui.d.ts b/types/ext/profile-conditions-ui.d.ts
new file mode 100644
index 00000000..7aa22e93
--- /dev/null
+++ b/types/ext/profile-conditions-ui.d.ts
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Settings from './settings';
+
+export type EventType = 'conditionGroupCountChanged';
+
+export type DescriptorType = Settings.ProfileConditionType;
+
+export type Descriptor = {
+ displayName: string;
+ defaultOperator: string;
+ operators: Map<string, OperatorInternal>;
+};
+
+export type ValidateFunction = (value: string) => boolean;
+
+export type NormalizeFunction = (value: unknown) => string;
+
+export type OperatorInternal = {
+ displayName: string;
+ type: string;
+ defaultValue: string;
+ resetDefaultOnChange?: boolean;
+ validate?: ValidateFunction;
+ normalize?: NormalizeFunction;
+};
+
+export type Operator = {
+ displayName: string;
+ type: string;
+ defaultValue: string;
+ resetDefaultOnChange: boolean | null;
+ validate: ValidateFunction | null;
+ normalize: NormalizeFunction | null;
+};
+
+export type ConditionGroupCountChangedEvent = {
+ count: number;
+ profileIndex: number;
+};
+
+export type DescriptorInfo = {
+ name: DescriptorType;
+ displayName: string;
+};
+
+export type OperatorInfo = {
+ name: string;
+ displayName: string;
+};
+
+export type InputData = {
+ validate: ValidateFunction | null;
+ normalize: NormalizeFunction | null;
+};
diff --git a/types/ext/profile-conditions-util.d.ts b/types/ext/profile-conditions-util.d.ts
new file mode 100644
index 00000000..15904410
--- /dev/null
+++ b/types/ext/profile-conditions-util.d.ts
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as JsonSchema from './json-schema';
+import type * as Settings from './settings';
+
+export type OperatorMapArray = [
+ key: string,
+ function: CreateSchemaFunction,
+][];
+
+export type CreateSchemaFunction = (
+ value: unknown,
+) => JsonSchema.Schema;
+
+export type NormalizedOptionsContext1 = Settings.OptionsContext1 & {
+ domain?: string;
+};
+
+export type NormalizedOptionsContext2 = Settings.OptionsContext2;
+
+export type NormalizedOptionsContext3 = Settings.OptionsContext2;
+
+export type NormalizedOptionsContext = NormalizedOptionsContext1 | NormalizedOptionsContext2 | NormalizedOptionsContext3;
diff --git a/types/ext/request-builder.d.ts b/types/ext/request-builder.d.ts
new file mode 100644
index 00000000..b231bcd7
--- /dev/null
+++ b/types/ext/request-builder.d.ts
@@ -0,0 +1,18 @@
+/*
+* Copyright (C) 2023 Yomitan Authors
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+export type ProgressCallback = (complete: boolean) => void;
diff --git a/types/ext/script-manager.d.ts b/types/ext/script-manager.d.ts
new file mode 100644
index 00000000..89337152
--- /dev/null
+++ b/types/ext/script-manager.d.ts
@@ -0,0 +1,56 @@
+/*
+* Copyright (C) 2023 Yomitan Authors
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+export type RunAt = 'document_start' | 'document_end' | 'document_idle';
+
+/** The script registration details. */
+export type RegistrationDetails = {
+ /** Same as `matches` in the `content_scripts` manifest key. */
+ matches: string[];
+
+ /** Regex match pattern to use as a fallback when native content script registration isn't supported. */
+ /** Should be equivalent to `matches`. */
+ urlMatches: string;
+
+ /** Same as `run_at` in the `content_scripts` manifest key. */
+ runAt: RunAt;
+
+ /** Same as `exclude_matches` in the `content_scripts` manifest key. */
+ excludeMatches?: string[];
+
+ /** Same as `match_about_blank` in the `content_scripts` manifest key. */
+ matchAboutBlank: boolean;
+
+ /** Same as `all_frames` in the `content_scripts` manifest key. */
+ allFrames: boolean;
+
+ /** List of CSS paths. */
+ css?: string[];
+
+ /** List of script paths. */
+ js?: string[];
+};
+
+export type ContentScriptInjectionDetails = {
+ allFrames: boolean;
+ matchAboutBlank: boolean;
+ runAt: RunAt;
+ css?: string[];
+ js?: string[];
+ urlRegex: RegExp | null;
+};
+
diff --git a/types/ext/selector-observer.d.ts b/types/ext/selector-observer.d.ts
new file mode 100644
index 00000000..a84b2add
--- /dev/null
+++ b/types/ext/selector-observer.d.ts
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type OnAddedCallback<T> = (element: Element) => T | undefined;
+
+export type OnRemovedCallback<T> = (element: Element, data: T) => void;
+
+export type OnChildrenUpdatedCallback<T> = (element: Element, data: T) => void;
+
+export type IsStaleCallback<T> = (element: Element, data: T) => boolean;
+
+export type ConstructorDetails<T> = {
+ /** A string CSS selector used to find elements. */
+ selector: string;
+ /** A string CSS selector used to filter elements, or `null` for no filtering. */
+ ignoreSelector?: string | null;
+ /** A function which is invoked for each element that is added that matches the selector. */
+ onAdded?: OnAddedCallback<T> | null;
+ /** A function which is invoked for each element that is removed, or `null`. */
+ onRemoved?: OnRemovedCallback<T> | null;
+ /** A function which is invoked for each element which has its children updated, or `null`. */
+ onChildrenUpdated?: OnChildrenUpdatedCallback<T> | null;
+ /**
+ * A function which checks if the data is stale for a given element, or `null`.
+ * If the element is stale, it will be removed and potentially re-added.
+ */
+ isStale?: IsStaleCallback<T> | null;
+};
+
+export type MutationRecordLike = {
+ type: string;
+ addedNodes: Node[];
+ removedNodes: Node[];
+ target: Node;
+};
+
+export type Observer<T> = {
+ element: Element;
+ ancestors: Node[];
+ data: T;
+};
diff --git a/types/ext/settings-controller.d.ts b/types/ext/settings-controller.d.ts
new file mode 100644
index 00000000..697de878
--- /dev/null
+++ b/types/ext/settings-controller.d.ts
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type {DictionaryController} from '../../ext/js/pages/settings/dictionary-controller';
+import type {ScanInputsController} from '../../ext/js/pages/settings/scan-inputs-controller';
+import type {ScanInputsSimpleController} from '../../ext/js/pages/settings/scan-inputs-simple-controller';
+import type * as Core from './core';
+import type * as Settings from './settings';
+import type * as SettingsModifications from './settings-modifications';
+
+export type PageExitPrevention = {
+ end: () => void;
+};
+
+export type EventType = 'optionsChanged' | 'optionsContextChanged' | 'permissionsChanged' | 'dictionarySettingsReordered' | 'scanInputsChanged';
+
+export type OptionsChangedEvent = {
+ options: Settings.ProfileOptions;
+ optionsContext: Settings.OptionsContext;
+};
+
+export type PermissionsChangedEvent = {
+ permissions: chrome.permissions.Permissions;
+};
+
+export type DictionarySettingsReorderedEvent = {
+ source: DictionaryController;
+};
+
+export type ScanInputsChangedEvent = {
+ source: ScanInputsController | ScanInputsSimpleController;
+};
+
+export type SettingsRead<THasScope extends boolean> = THasScope extends true ? SettingsModifications.ScopedRead : SettingsModifications.Read;
+
+export type SettingsModification<THasScope extends boolean> = THasScope extends true ? SettingsModifications.ScopedModification : SettingsModifications.Modification;
+
+export type SettingsExtraFields<THasScope extends boolean> = THasScope extends true ? null : SettingsModifications.OptionsScope;
+
+export type ModifyResult = Core.Response<SettingsModifications.ModificationResult>;
diff --git a/types/ext/settings-modifications.d.ts b/types/ext/settings-modifications.d.ts
new file mode 100644
index 00000000..5541383a
--- /dev/null
+++ b/types/ext/settings-modifications.d.ts
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Settings from './settings';
+
+export type OptionsScope = {
+ scope: OptionsScopeType;
+ optionsContext: Settings.OptionsContext | null;
+};
+
+export type OptionsScopeType = 'profile' | 'global';
+
+export type Read = {
+ path: string;
+};
+
+export type ModificationSet = {
+ action: 'set';
+ path: string;
+ value: unknown;
+};
+
+export type ModificationDelete = {
+ action: 'delete';
+ path: string;
+};
+
+export type ModificationSwap = {
+ action: 'swap';
+ path1: string;
+ path2: string;
+};
+
+export type ModificationSplice = {
+ action: 'splice';
+ path: string;
+ start: number;
+ deleteCount: number;
+ items: unknown[];
+};
+
+export type ModificationPush = {
+ action: 'push';
+ path: string;
+ items: unknown[];
+};
+
+export type Modification = (
+ ModificationSet |
+ ModificationDelete |
+ ModificationSwap |
+ ModificationSplice |
+ ModificationPush
+);
+
+export type ScopedRead = Read & OptionsScope;
+export type ScopedModificationSet = ModificationSet & OptionsScope;
+export type ScopedModificationDelete = ModificationDelete & OptionsScope;
+export type ScopedModificationSwap = ModificationSwap & OptionsScope;
+export type ScopedModificationSplice = ModificationSplice & OptionsScope;
+export type ScopedModificationPush = ModificationPush & OptionsScope;
+
+export type ScopedModification = (
+ ScopedModificationSet |
+ ScopedModificationDelete |
+ ScopedModificationSwap |
+ ScopedModificationSplice |
+ ScopedModificationPush
+);
+
+export type ModificationSetResult = unknown;
+export type ModificationDeleteResult = true;
+export type ModificationSwapResult = true;
+export type ModificationSpliceResult = unknown[];
+export type ModificationPushResult = number;
+
+export type ModificationResult = (
+ ModificationSetResult |
+ ModificationDeleteResult |
+ ModificationSwapResult |
+ ModificationSpliceResult |
+ ModificationPushResult
+);
diff --git a/types/ext/settings.d.ts b/types/ext/settings.d.ts
new file mode 100644
index 00000000..8ce82b28
--- /dev/null
+++ b/types/ext/settings.d.ts
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Input from './input';
+
+export type OptionsContextFlag = 'clipboard';
+
+export type OptionsContext1 = {
+ url: string;
+ depth: number;
+ index?: undefined;
+ current?: undefined;
+ flags?: OptionsContextFlag[];
+ modifiers?: Input.Modifier[];
+ modifierKeys?: Input.ModifierKey[];
+};
+
+export type OptionsContext2 = {
+ index: number;
+ url?: undefined;
+ depth?: undefined;
+ current?: undefined;
+ flags?: OptionsContextFlag[];
+ modifiers?: Input.Modifier[];
+ modifierKeys?: Input.ModifierKey[];
+};
+
+export type OptionsContext3 = {
+ current: true;
+ url?: undefined;
+ depth?: undefined;
+ index?: undefined;
+ flags?: OptionsContextFlag[];
+ modifiers?: Input.Modifier[];
+ modifierKeys?: Input.ModifierKey[];
+};
+
+export type OptionsContext = OptionsContext1 | OptionsContext2 | OptionsContext3;
+
+export type Options = {
+ version: number;
+ profiles: Profile[];
+ profileCurrent: number;
+ global: GlobalOptions;
+};
+
+export type GlobalOptions = {
+ database: GlobalDatabaseOptions;
+};
+
+export type GlobalDatabaseOptions = {
+ prefixWildcardsSupported: boolean;
+};
+
+export type Profile = {
+ name: string;
+ conditionGroups: ProfileConditionGroup[];
+ options: ProfileOptions;
+};
+
+export type ProfileConditionGroup = {
+ conditions: ProfileCondition[];
+};
+
+export type ProfileConditionType = 'popupLevel' | 'url' | 'modifierKeys' | 'flags';
+
+export type ProfileCondition = {
+ type: ProfileConditionType;
+ operator: string;
+ value: string;
+};
+
+export type ProfileOptions = {
+ general: GeneralOptions;
+ popupWindow: PopupWindowOptions;
+ audio: AudioOptions;
+ scanning: ScanningOptions;
+ translation: TranslationOptions;
+ dictionaries: DictionariesOptions;
+ parsing: ParsingOptions;
+ anki: AnkiOptions;
+ sentenceParsing: SentenceParsingOptions;
+ inputs: InputsOptions;
+ clipboard: ClipboardOptions;
+ accessibility: AccessibilityOptions;
+};
+
+export type GeneralOptions = {
+ enable: boolean;
+ resultOutputMode: ResultOutputMode;
+ debugInfo: boolean;
+ maxResults: number;
+ showAdvanced: boolean;
+ popupDisplayMode: PopupDisplayMode;
+ popupWidth: number;
+ popupHeight: number;
+ popupHorizontalOffset: number;
+ popupVerticalOffset: number;
+ popupHorizontalOffset2: number;
+ popupVerticalOffset2: number;
+ popupHorizontalTextPosition: PopupHorizontalTextPosition;
+ popupVerticalTextPosition: PopupVerticalTextPosition;
+ popupScalingFactor: number;
+ popupScaleRelativeToPageZoom: boolean;
+ popupScaleRelativeToVisualViewport: boolean;
+ showGuide: boolean;
+ compactTags: boolean;
+ glossaryLayoutMode: GlossaryLayoutMode;
+ mainDictionary: string;
+ popupTheme: PopupTheme;
+ popupOuterTheme: PopupOuterTheme;
+ customPopupCss: string;
+ customPopupOuterCss: string;
+ enableWanakana: boolean;
+ showPitchAccentDownstepNotation: boolean;
+ showPitchAccentPositionNotation: boolean;
+ showPitchAccentGraph: boolean;
+ showIframePopupsInRootFrame: boolean;
+ useSecurePopupFrameUrl: boolean;
+ usePopupShadowDom: boolean;
+ usePopupWindow: boolean;
+ popupCurrentIndicatorMode: PopupCurrentIndicatorMode;
+ popupActionBarVisibility: PopupActionBarVisibility;
+ popupActionBarLocation: PopupActionBarLocation;
+ frequencyDisplayMode: FrequencyDisplayMode;
+ termDisplayMode: TermDisplayMode;
+ sortFrequencyDictionary: string | null;
+ sortFrequencyDictionaryOrder: SortFrequencyDictionaryOrder;
+};
+
+export type PopupWindowOptions = {
+ width: number;
+ height: number;
+ left: number;
+ top: number;
+ useLeft: boolean;
+ useTop: boolean;
+ windowType: PopupWindowType;
+ windowState: PopupWindowState;
+};
+
+export type AudioOptions = {
+ enabled: boolean;
+ volume: number;
+ autoPlay: boolean;
+ sources: AudioSourceOptions[];
+};
+
+export type AudioSourceOptions = {
+ type: AudioSourceType;
+ url: string;
+ voice: string;
+};
+
+export type ScanningOptions = {
+ inputs: ScanningInput[];
+ preventMiddleMouse: ScanningPreventMiddleMouseOptions;
+ touchInputEnabled: boolean;
+ pointerEventsEnabled: boolean;
+ selectText: boolean;
+ alphanumeric: boolean;
+ autoHideResults: boolean;
+ delay: number;
+ hideDelay: number;
+ length: number;
+ deepDomScan: boolean;
+ popupNestingMaxDepth: number;
+ enablePopupSearch: boolean;
+ enableOnPopupExpressions: boolean;
+ enableOnSearchPage: boolean;
+ enableSearchTags: boolean;
+ layoutAwareScan: boolean;
+ matchTypePrefix: boolean;
+ hidePopupOnCursorExit: boolean;
+ hidePopupOnCursorExitDelay: number;
+ normalizeCssZoom: boolean;
+};
+
+export type ScanningInput = {
+ include: string;
+ exclude: string;
+ types: ScanningInputTypes;
+ options: ScanningInputOptions;
+};
+
+export type ScanningInputTypes = {
+ mouse: boolean;
+ touch: boolean;
+ pen: boolean;
+};
+
+export type ScanningInputOptions = {
+ showAdvanced: boolean;
+ searchTerms: boolean;
+ searchKanji: boolean;
+ scanOnTouchMove: boolean;
+ scanOnTouchPress: boolean;
+ scanOnTouchRelease: boolean;
+ scanOnPenMove: boolean;
+ scanOnPenHover: boolean;
+ scanOnPenReleaseHover: boolean;
+ scanOnPenPress: boolean;
+ scanOnPenRelease: boolean;
+ preventTouchScrolling: boolean;
+ preventPenScrolling: boolean;
+};
+
+export type ScanningPreventMiddleMouseOptions = {
+ onWebPages: boolean;
+ onPopupPages: boolean;
+ onSearchPages: boolean;
+ onSearchQuery: boolean;
+};
+
+export type TranslationOptions = {
+ convertHalfWidthCharacters: TranslationConvertType;
+ convertNumericCharacters: TranslationConvertType;
+ convertAlphabeticCharacters: TranslationConvertType;
+ convertHiraganaToKatakana: TranslationConvertType;
+ convertKatakanaToHiragana: TranslationConvertType;
+ collapseEmphaticSequences: TranslationCollapseEmphaticSequences;
+ textReplacements: TranslationTextReplacementOptions;
+};
+
+export type TranslationTextReplacementOptions = {
+ searchOriginal: boolean;
+ groups: TranslationTextReplacementGroup[][];
+};
+
+export type TranslationTextReplacementGroup = {
+ pattern: string;
+ ignoreCase: boolean;
+ replacement: string;
+};
+
+export type DictionariesOptions = DictionaryOptions[];
+
+export type DictionaryOptions = {
+ name: string;
+ priority: number;
+ enabled: boolean;
+ allowSecondarySearches: boolean;
+ definitionsCollapsible: DictionaryDefinitionsCollapsible;
+};
+
+export type ParsingOptions = {
+ enableScanningParser: boolean;
+ enableMecabParser: boolean;
+ selectedParser: string | null;
+ termSpacing: boolean;
+ readingMode: ParsingReadingMode;
+};
+
+export type AnkiOptions = {
+ enable: boolean;
+ server: string;
+ tags: string[];
+ screenshot: AnkiScreenshotOptions;
+ terms: AnkiNoteOptions;
+ kanji: AnkiNoteOptions;
+ duplicateScope: AnkiDuplicateScope;
+ duplicateScopeCheckAllModels: boolean;
+ checkForDuplicates: boolean;
+ fieldTemplates: string | null;
+ suspendNewCards: boolean;
+ displayTags: AnkiDisplayTags;
+ noteGuiMode: AnkiNoteGuiMode;
+ apiKey: string;
+ downloadTimeout: number;
+};
+
+export type AnkiScreenshotOptions = {
+ format: AnkiScreenshotFormat;
+ quality: number;
+};
+
+export type AnkiNoteOptions = {
+ deck: string;
+ model: string;
+ fields: AnkiNoteFields;
+};
+
+export type AnkiNoteFields = {
+ [key: string]: string;
+};
+
+export type SentenceParsingOptions = {
+ scanExtent: number;
+ terminationCharacterMode: SentenceTerminationCharacterMode;
+ terminationCharacters: SentenceParsingTerminationCharacterOption[];
+};
+
+export type SentenceParsingTerminationCharacterOption = {
+ enabled: boolean;
+ character1: string;
+ character2: string | null;
+ includeCharacterAtStart: boolean;
+ includeCharacterAtEnd: boolean;
+};
+
+export type InputsOptions = {
+ hotkeys: InputsHotkeyOptions[];
+};
+
+export type InputsHotkeyOptions = {
+ action: string;
+ argument: string;
+ key: string | null;
+ modifiers: InputsHotkeyModifier[];
+ scopes: InputsHotkeyScope[];
+ enabled: boolean;
+};
+
+export type ClipboardOptions = {
+ enableBackgroundMonitor: boolean;
+ enableSearchPageMonitor: boolean;
+ autoSearchContent: boolean;
+ maximumSearchLength: number;
+};
+
+export type AccessibilityOptions = {
+ forceGoogleDocsHtmlRendering: boolean;
+};
+
+export type PreventMiddleMouseOptions = {
+ onWebPages: boolean;
+ onPopupPages: boolean;
+ onSearchPages: boolean;
+ onSearchQuery: boolean;
+};
+
+export type ResultOutputMode = 'group' | 'merge' | 'split';
+export type PopupDisplayMode = 'default' | 'full-width';
+export type PopupHorizontalTextPosition = 'below' | 'above';
+export type PopupVerticalTextPosition = 'default' | 'before' | 'after' | 'left' | 'right';
+export type GlossaryLayoutMode = 'default' | 'compact';
+export type PopupTheme = 'light' | 'dark' | 'browser';
+export type PopupOuterTheme = 'light' | 'dark' | 'browser' | 'site';
+export type PopupCurrentIndicatorMode = 'none' | 'asterisk' | 'triangle' | 'bar-left' | 'bar-right' | 'dot-left' | 'dot-right';
+export type PopupActionBarVisibility = 'auto' | 'always';
+export type PopupActionBarLocation = 'left' | 'right' | 'top' | 'bottom';
+export type FrequencyDisplayMode = 'tags' | 'tags-grouped' | 'split-tags' | 'split-tags-grouped' | 'inline-list' | 'list';
+export type TermDisplayMode = 'ruby' | 'ruby-and-reading' | 'term-and-reading';
+export type SortFrequencyDictionaryOrder = 'ascending' | 'descending';
+
+export type PopupWindowType = 'normal' | 'popup';
+export type PopupWindowState = 'normal' | 'maximized' | 'fullscreen';
+
+export type AudioSourceType = 'jpod101' | 'jpod101-alternate' | 'jisho' | 'text-to-speech' | 'text-to-speech-reading' | 'custom' | 'custom-json';
+
+export type TranslationConvertType = 'false' | 'true' | 'variant';
+export type TranslationCollapseEmphaticSequences = 'false' | 'true' | 'full';
+
+export type DictionaryDefinitionsCollapsible = 'not-collapsible' | 'expanded' | 'collapsed' | 'force-collapsed' | 'force-expanded';
+
+export type ParsingReadingMode = 'hiragana' | 'katakana' | 'romaji' | 'dictionary-reading' | 'none';
+
+export type AnkiScreenshotFormat = 'png' | 'jpeg';
+export type AnkiDuplicateScope = 'collection' | 'deck' | 'deck-root';
+export type AnkiDisplayTags = 'never' | 'always' | 'non-standard';
+export type AnkiNoteGuiMode = 'browse' | 'edit';
+
+export type SentenceTerminationCharacterMode = 'custom' | 'custom-no-newlines' | 'newlines' | 'none';
+
+export type InputsHotkeyModifier = 'alt' | 'ctrl' | 'shift' | 'meta';
+export type InputsHotkeyScope = 'popup' | 'search' | 'web';
diff --git a/types/ext/simple-dom-parser.d.ts b/types/ext/simple-dom-parser.d.ts
new file mode 100644
index 00000000..971871a2
--- /dev/null
+++ b/types/ext/simple-dom-parser.d.ts
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type {
+ ChildNode as Parse5ChildNode,
+ Document as Parse5Document,
+ Element as Parse5Element,
+} from 'parse5/dist/tree-adapters/default';
+
+/**
+ * This type is used as a generic reference to an element object from a generic DOM API.
+ */
+// eslint-disable-next-line @typescript-eslint/ban-types
+export type Element = object;
+
+export type ISimpleDomParser = {
+ getElementById(id: string, root?: Element): Element | null;
+ getElementByTagName(tagName: string, root?: Element): Element | null;
+ getElementsByTagName(tagName: string, root?: Element): Element[];
+ getElementsByClassName(className: string, root?: Element): Element[];
+ getAttribute(element: Element, attribute: string): string | null;
+ getTextContent(element: Element): string;
+};
diff --git a/types/ext/structured-content.d.ts b/types/ext/structured-content.d.ts
new file mode 100644
index 00000000..09755c88
--- /dev/null
+++ b/types/ext/structured-content.d.ts
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as DictionaryData from './dictionary-data';
+
+export type VerticalAlign = 'baseline' | 'sub' | 'super' | 'text-top' | 'text-bottom' | 'middle' | 'top' | 'bottom';
+
+export type TextDecorationLine = 'underline' | 'overline' | 'line-through';
+
+export type TextDecorationLineOrNone = 'none' | TextDecorationLine;
+
+export type FontStyle = 'normal' | 'italic';
+
+export type FontWeight = 'normal' | 'bold';
+
+export type TextAlign = 'start' | 'end' | 'left' | 'right' | 'center' | 'justify' | 'justify-all' | 'match-parent';
+
+export type SizeUnits = 'px' | 'em';
+
+export type ImageRendering = 'auto' | 'pixelated' | 'crisp-edges';
+
+export type ImageAppearance = 'auto' | 'monochrome';
+
+export type Image = DictionaryData.TermImage & {
+ verticalAlign: VerticalAlign;
+ sizeUnits: SizeUnits;
+};
+
+export type Data = {
+ [key: string]: string;
+};
+
+export type StructuredContentStyle = {
+ fontStyle?: FontStyle;
+ fontWeight?: FontWeight;
+ fontSize?: string;
+ textDecorationLine?: TextDecorationLineOrNone | TextDecorationLine[];
+ verticalAlign?: VerticalAlign;
+ textAlign?: TextAlign;
+ marginTop?: number;
+ marginLeft?: number;
+ marginRight?: number;
+ marginBottom?: number;
+ listStyleType?: string;
+};
+
+export type LineBreak = {
+ tag: 'br';
+ data?: Data;
+ /**
+ * This element doesn't support children.
+ */
+ content?: undefined;
+ /**
+ * This element doesn't support language.
+ */
+ lang?: undefined;
+};
+
+export type UnstyledElement = {
+ tag: 'ruby' | 'rt' | 'rp' | 'table' | 'thead' | 'tbody' | 'tfoot' | 'tr';
+ content?: Content;
+ data?: Data;
+ /**
+ * Defines the language of an element in the format defined by RFC 5646.
+ */
+ lang?: string;
+};
+
+export type TableElement = {
+ tag: 'td' | 'th';
+ content?: Content;
+ data?: Data;
+ colSpan?: number;
+ rowSpan?: number;
+ style?: StructuredContentStyle;
+ /**
+ * Defines the language of an element in the format defined by RFC 5646.
+ */
+ lang?: string;
+};
+
+export type StyledElement = {
+ tag: 'span' | 'div' | 'ol' | 'ul' | 'li';
+ content?: Content;
+ data?: Data;
+ style?: StructuredContentStyle;
+ /**
+ * Defines the language of an element in the format defined by RFC 5646.
+ */
+ lang?: string;
+};
+
+export type ImageElementBase = {
+ data?: Data;
+ /**
+ * Path to the image file in the archive.
+ */
+ path: string;
+ /**
+ * Preferred width of the image.
+ */
+ width?: number;
+ /**
+ * Preferred width of the image.
+ */
+ height?: number;
+ /**
+ * Preferred width of the image.
+ * This is only used in the internal database.
+ */
+ preferredWidth?: number;
+ /**
+ * Preferred width of the image.
+ * This is only used in the internal database.
+ */
+ preferredHeight?: number;
+ /**
+ * Hover text for the image.
+ */
+ title?: string;
+ /**
+ * Description of the image.
+ */
+ description?: string;
+ /**
+ * Whether or not the image should appear pixelated at sizes larger than the image's native resolution.
+ */
+ pixelated?: boolean;
+ /**
+ * Controls how the image is rendered. The value of this field supersedes the pixelated field.
+ */
+ imageRendering?: ImageRendering;
+ /**
+ * Controls the appearance of the image. The 'monochrome' value will mask the opaque parts of the image using the current text color.
+ */
+ appearance?: ImageAppearance;
+ /**
+ * Whether or not a background color is displayed behind the image.
+ */
+ background?: boolean;
+ /**
+ * Whether or not the image is collapsed by default.
+ */
+ collapsed?: boolean;
+ /**
+ * Whether or not the image can be collapsed.
+ */
+ collapsible?: boolean;
+ /**
+ * This property is not defined on the base class.
+ */
+ verticalAlign?: undefined;
+ /**
+ * This property is not defined on the base class.
+ */
+ sizeUnits?: undefined;
+};
+
+export type ImageElement = ImageElementBase & {
+ tag: 'img';
+ /**
+ * This element doesn't support children.
+ */
+ content?: undefined;
+ /**
+ * The vertical alignment of the image.
+ */
+ verticalAlign?: VerticalAlign;
+ /**
+ * The units for the width and height.
+ */
+ sizeUnits?: SizeUnits;
+};
+
+export type LinkElement = {
+ tag: 'a';
+ content?: Content;
+ /**
+ * The URL for the link. URLs starting with a ? are treated as internal links to other dictionary content.
+ */
+ href: string;
+ /**
+ * Defines the language of an element in the format defined by RFC 5646.
+ */
+ lang?: string;
+};
+
+export type Element = LineBreak | UnstyledElement | TableElement | StyledElement | ImageElement | LinkElement;
+
+export type Content = string | Element | Content[];
diff --git a/types/ext/task-accumulator.d.ts b/types/ext/task-accumulator.d.ts
new file mode 100644
index 00000000..f02d449b
--- /dev/null
+++ b/types/ext/task-accumulator.d.ts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type Task<V> = {
+ data: V;
+ stale: boolean;
+};
diff --git a/types/ext/template-patcher.d.ts b/types/ext/template-patcher.d.ts
new file mode 100644
index 00000000..852d3768
--- /dev/null
+++ b/types/ext/template-patcher.d.ts
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type Patch = {
+ addition: string;
+ modifications: {
+ current: string;
+ replacement: string;
+ }[];
+};
diff --git a/types/ext/template-renderer-frame-api.d.ts b/types/ext/template-renderer-frame-api.d.ts
new file mode 100644
index 00000000..e00a0711
--- /dev/null
+++ b/types/ext/template-renderer-frame-api.d.ts
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Core from './core';
+
+export type MessageData = {
+ action: string;
+ params: Core.SerializableObject;
+ id: string;
+};
diff --git a/types/ext/template-renderer.d.ts b/types/ext/template-renderer.d.ts
new file mode 100644
index 00000000..169fee78
--- /dev/null
+++ b/types/ext/template-renderer.d.ts
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as AnkiNoteBuilder from './anki-note-builder';
+import type * as AnkiTemplates from './anki-templates';
+import type * as Core from './core';
+
+export type RenderResult = {
+ result: string;
+ requirements: AnkiNoteBuilder.Requirement[];
+};
+
+export type RenderMultiItem = {
+ template: string;
+ templateItems: RenderMultiTemplateItem[];
+};
+
+export type RenderMultiTemplateItem = {
+ type: AnkiTemplates.RenderMode;
+ commonData: AnkiNoteBuilder.CommonData;
+ datas: PartialOrCompositeRenderData[];
+};
+
+export type PartialRenderData = {
+ marker: string;
+ commonData?: undefined;
+};
+
+export type CompositeRenderData = {
+ marker: string;
+ commonData: AnkiNoteBuilder.CommonData;
+};
+
+export type PartialOrCompositeRenderData = PartialRenderData | CompositeRenderData;
+
+export type DataType = {
+ modifier: (data: CompositeRenderData) => AnkiTemplates.NoteData;
+ composeData: (data: PartialOrCompositeRenderData, commonData: AnkiNoteBuilder.CommonData) => CompositeRenderData;
+};
+
+export type HelperOptionsFunction<TResult = unknown> = (context: unknown) => TResult;
+
+export type HelperOptions = {
+ fn: HelperOptionsFunction;
+ inverse: HelperOptionsFunction;
+ hash: Core.SafeAny;
+ data?: Core.SafeAny;
+};
+
+export type HelperFunction<TReturn = unknown> = (args: unknown[], context: unknown, options: HelperOptions) => TReturn;
+
+export type HelperFunctionsDescriptor = [
+ name: string,
+ helper: HelperFunction<unknown>,
+][];
+
+export type SetupCallbackResult = {
+ requirements: AnkiNoteBuilder.Requirement[];
+};
+
+export type CleanupCallbackResult = void;
diff --git a/types/ext/text-scanner.d.ts b/types/ext/text-scanner.d.ts
new file mode 100644
index 00000000..4ec7f204
--- /dev/null
+++ b/types/ext/text-scanner.d.ts
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type {TextScanner} from '../../ext/js/language/text-scanner';
+import type * as Dictionary from './dictionary';
+import type * as Display from './display';
+import type * as Input from './input';
+import type * as Settings from './settings';
+import type * as TextSource from './text-source';
+
+export type SearchResultDetail = {
+ documentTitle: string;
+};
+
+export type Options = {
+ inputs?: InputOptionsOuter[];
+ deepContentScan?: boolean;
+ normalizeCssZoom?: boolean;
+ selectText?: boolean;
+ delay?: number;
+ touchInputEnabled?: boolean;
+ pointerEventsEnabled?: boolean;
+ scanLength?: number;
+ layoutAwareScan?: boolean;
+ preventMiddleMouse?: boolean;
+ matchTypePrefix?: boolean;
+ sentenceParsingOptions?: SentenceParsingOptions;
+};
+
+export type InputOptionsOuter = {
+ include: string;
+ exclude: string;
+ types: {
+ mouse: boolean;
+ touch: boolean;
+ pen: boolean;
+ };
+ options: InputOptions;
+};
+
+export type InputOptions = {
+ searchTerms: boolean;
+ searchKanji: boolean;
+ scanOnTouchMove: boolean;
+ scanOnTouchPress: boolean;
+ scanOnTouchRelease: boolean;
+ scanOnPenMove: boolean;
+ scanOnPenHover: boolean;
+ scanOnPenReleaseHover: boolean;
+ scanOnPenPress: boolean;
+ scanOnPenRelease: boolean;
+ preventTouchScrolling: boolean;
+ preventPenScrolling: boolean;
+};
+
+export type SentenceParsingOptions = {
+ scanExtent: number;
+ terminationCharacterMode: Settings.SentenceTerminationCharacterMode;
+ terminationCharacters: Settings.SentenceParsingTerminationCharacterOption[];
+};
+
+export type InputConfig = {
+ include: string[];
+ exclude: string[];
+ types: Set<PointerType>;
+ searchTerms: boolean;
+ searchKanji: boolean;
+ scanOnTouchMove: boolean;
+ scanOnTouchPress: boolean;
+ scanOnTouchRelease: boolean;
+ scanOnPenMove: boolean;
+ scanOnPenHover: boolean;
+ scanOnPenReleaseHover: boolean;
+ scanOnPenPress: boolean;
+ scanOnPenRelease: boolean;
+ preventTouchScrolling: boolean;
+ preventPenScrolling: boolean;
+};
+
+export type SearchedEventDetails = {
+ textScanner: TextScanner;
+ type: Display.PageType | null;
+ dictionaryEntries: Dictionary.DictionaryEntry[] | null;
+ sentence: Display.HistoryStateSentence | null;
+ inputInfo: InputInfo;
+ textSource: TextSource.TextSource;
+ optionsContext: Settings.OptionsContext | null;
+ detail: SearchResultDetail | null;
+ error: Error | null;
+};
+
+export type InputInfo = {
+ input: InputConfig | null;
+ pointerType: PointerType;
+ eventType: PointerEventType;
+ passive: boolean;
+ modifiers: Input.Modifier[];
+ modifierKeys: Input.ModifierKey[];
+ detail: InputInfoDetail | undefined;
+};
+
+export type InputInfoDetail = {
+ focus: boolean;
+ restoreSelection: boolean;
+};
+
+export type EventType = 'searched' | 'clear';
+
+export type GetSearchContextCallback = GetSearchContextCallbackSync | GetSearchContextCallbackAsync;
+
+export type GetSearchContextCallbackSync = () => SearchContext;
+
+export type GetSearchContextCallbackAsync = () => Promise<SearchContext>;
+
+export type ConstructorDetails = {
+ node: HTMLElement | Window;
+ getSearchContext: GetSearchContextCallback;
+ ignoreElements?: (() => Element[]) | null;
+ ignorePoint?: ((x: number, y: number) => Promise<boolean>) | null;
+ searchTerms?: boolean;
+ searchKanji?: boolean;
+ searchOnClick?: boolean;
+ searchOnClickOnly?: boolean;
+};
+
+export type SearchContext = {
+ optionsContext: Settings.OptionsContext;
+ detail?: SearchResultDetail;
+};
+
+export type SelectionRestoreInfo = {
+ ranges: Range[];
+};
+
+export type TermSearchResults = {
+ type: 'terms';
+ dictionaryEntries: Dictionary.TermDictionaryEntry[];
+ sentence: Sentence;
+};
+
+export type KanjiSearchResults = {
+ type: 'kanji';
+ dictionaryEntries: Dictionary.KanjiDictionaryEntry[];
+ sentence: Sentence;
+};
+
+export type SearchResults = TermSearchResults | KanjiSearchResults;
+
+export type Sentence = {
+ text: string;
+ offset: number;
+};
+
+export type PointerType = (
+ 'pen' |
+ 'mouse' |
+ 'touch' |
+ 'script'
+);
+
+export type PointerEventType = (
+ 'mouseMove' |
+ 'pointerOver' |
+ 'pointerDown' |
+ 'pointerMove' |
+ 'pointerUp' |
+ 'touchStart' |
+ 'touchEnd' |
+ 'touchMove' |
+ 'click' |
+ 'script'
+);
diff --git a/types/ext/text-source.d.ts b/types/ext/text-source.d.ts
new file mode 100644
index 00000000..7e085176
--- /dev/null
+++ b/types/ext/text-source.d.ts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type {TextSourceElement} from '../../ext/js/dom/text-source-element';
+import type {TextSourceRange} from '../../ext/js/dom/text-source-range';
+
+export type TextSource = TextSourceRange | TextSourceElement;
diff --git a/types/ext/translation-internal.d.ts b/types/ext/translation-internal.d.ts
new file mode 100644
index 00000000..784a5979
--- /dev/null
+++ b/types/ext/translation-internal.d.ts
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as DictionaryDatabase from './dictionary-database';
+import type * as Translation from './translation';
+
+export type TextDeinflectionOptions = [
+ textReplacements: Translation.FindTermsTextReplacement[] | null,
+ halfWidth: boolean,
+ numeric: boolean,
+ alphabetic: boolean,
+ katakana: boolean,
+ hiragana: boolean,
+ emphatic: [collapseEmphatic: boolean, collapseEmphaticFull: boolean],
+];
+
+export type TextDeinflectionOptionsArrays = [
+ textReplacements: (Translation.FindTermsTextReplacement[] | null)[],
+ halfWidth: boolean[],
+ numeric: boolean[],
+ alphabetic: boolean[],
+ katakana: boolean[],
+ hiragana: boolean[],
+ emphatic: [collapseEmphatic: boolean, collapseEmphaticFull: boolean][],
+];
+
+export enum DeinflectionRuleFlags {
+ None = 0x0,
+ VerbIchidan = 0b00000001, // Verb ichidan
+ VerbGodan = 0b00000010, // Verb godan
+ VerbSuru = 0b00000100, // Verb suru
+ VerbKuru = 0b00001000, // Verb kuru
+ VerbZuru = 0b00010000, // Verb zuru
+ AdjectiveI = 0b00100000, // Adjective i
+ IruEndingIntermediate = 0b01000000, // Intermediate -iru endings for progressive or perfect tense
+}
+
+export type Deinflection = {
+ term: string;
+ rules: DeinflectionRuleFlags;
+ reasons: string[];
+};
+
+export type DatabaseDeinflection = {
+ originalText: string;
+ transformedText: string;
+ deinflectedText: string;
+ rules: DeinflectionRuleFlags;
+ reasons: string[];
+ databaseEntries: DictionaryDatabase.TermEntry[];
+};
diff --git a/types/ext/translation.d.ts b/types/ext/translation.d.ts
new file mode 100644
index 00000000..3c41c9f3
--- /dev/null
+++ b/types/ext/translation.d.ts
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ * Copyright (C) 2022 Yomichan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type * as Dictionary from './dictionary';
+
+// Kanji
+
+/**
+ * An options object for use with `Translator.findKanji`.
+ */
+export type FindKanjiOptions = {
+ /**
+ * The mapping of dictionaries to search for kanji in.
+ * The key is the dictionary name.
+ */
+ enabledDictionaryMap: Map<string, FindKanjiDictionary>;
+};
+
+/**
+ * Details about a dictionary.
+ */
+export type FindKanjiDictionary = {
+ /**
+ * The index of the dictionary
+ */
+ index: number;
+ /**
+ * The priority of the dictionary
+ */
+ priority: number;
+};
+
+// Terms
+
+/**
+ * An options object for use with `Translator.findTerms`.
+ */
+export type FindTermsOptions = {
+ /**
+ * The matching type for looking up terms.
+ */
+ matchType: FindTermsMatchType;
+ /**
+ * Whether or not deinflection should be performed.
+ */
+ deinflect: boolean;
+ /**
+ * The name of the primary dictionary to search.
+ */
+ mainDictionary: string;
+ /**
+ * The name of the frequency dictionary used for sorting
+ */
+ sortFrequencyDictionary: string | null;
+ /**
+ * The order used when using a sorting dictionary.
+ */
+ sortFrequencyDictionaryOrder: FindTermsSortOrder;
+ /**
+ * Whether or not non-Japanese characters should be searched.
+ */
+ removeNonJapaneseCharacters: boolean;
+ /**
+ * Whether or not half-width characters should be converted to full-width characters.
+ */
+ convertHalfWidthCharacters: FindTermsVariantMode;
+ /**
+ * Whether or not ASCII numeric characters should be converted to full-width numeric characters.
+ */
+ convertNumericCharacters: FindTermsVariantMode;
+ /**
+ * Whether or not alphabetic characters should be converted to kana.
+ */
+ convertAlphabeticCharacters: FindTermsVariantMode;
+ /**
+ * Whether or not hiragana characters should be converted to katakana.
+ */
+ convertHiraganaToKatakana: FindTermsVariantMode;
+ /**
+ * Whether or not katakana characters should be converted to hiragana.
+ */
+ convertKatakanaToHiragana: FindTermsVariantMode;
+ /**
+ * How emphatic character sequences should be collapsed.
+ */
+ collapseEmphaticSequences: FindTermsEmphaticSequencesMode;
+ /**
+ * An iterable sequence of text replacements to be applied during the term lookup process.
+ */
+ textReplacements: (FindTermsTextReplacement[] | null)[];
+ /**
+ * The mapping of dictionaries to search for terms in.
+ * The key is the dictionary name.
+ */
+ enabledDictionaryMap: TermEnabledDictionaryMap;
+ /**
+ * A set of dictionary names which should have definitions removed.
+ */
+ excludeDictionaryDefinitions: Set<string> | null;
+};
+
+/**
+ * The matching type for looking up terms.
+ */
+export type FindTermsMatchType = Dictionary.TermSourceMatchType;
+
+/**
+ * A sorting order to use when finding terms.
+ */
+export type FindTermsSortOrder = 'ascending' | 'descending';
+
+/**
+ * Mode describing how to handle variations.
+ */
+export type FindTermsVariantMode = 'false' | 'true' | 'variant';
+
+/**
+ * Mode describing how to handle emphatic sequence variations.
+ */
+export type FindTermsEmphaticSequencesMode = 'false' | 'true' | 'full';
+
+/**
+ * Information about how text should be replaced when looking up terms.
+ */
+export type FindTermsTextReplacement = {
+ /**
+ * The pattern to replace.
+ */
+ pattern: RegExp;
+ /**
+ * The replacement string. This can contain special sequences, such as `$&`.
+ */
+ replacement: string;
+};
+
+/**
+ * Details about a dictionary.
+ */
+export type FindTermDictionary = {
+ /**
+ * The index of the dictionary
+ */
+ index: number;
+ /**
+ * The priority of the dictionary
+ */
+ priority: number;
+ /**
+ * Whether or not secondary term searches are allowed for this dictionary.
+ */
+ allowSecondarySearches: boolean;
+};
+
+export type TermEnabledDictionaryMap = Map<string, FindTermDictionary>;
+
+export type KanjiEnabledDictionaryMap = Map<string, FindKanjiDictionary>;
diff --git a/types/ext/translator.d.ts b/types/ext/translator.d.ts
new file mode 100644
index 00000000..39d4be81
--- /dev/null
+++ b/types/ext/translator.d.ts
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import type {DictionaryDatabase} from '../../ext/js/language/dictionary-database';
+import type {JapaneseUtil} from '../../ext/js/language/sandbox/japanese-util';
+import type * as Dictionary from './dictionary';
+import type * as DictionaryDatabaseTypes from './dictionary-database';
+
+export type ConstructorDetails = {
+ /** An instance of JapaneseUtil. */
+ japaneseUtil: JapaneseUtil;
+ /** An instance of DictionaryDatabase. */
+ database: DictionaryDatabase;
+};
+
+/**
+ * Information about how popup content should be shown, specifically related to the outer popup frame.
+ */
+export type TermFrequencySimple = {
+ /** The term. */
+ term: string;
+ /** The reading of the term. */
+ reading: string | null;
+ /** The name of the dictionary that the term frequency originates from. */
+ dictionary: string;
+ /** Whether or not a reading was specified. */
+ hasReading: boolean;
+ /** The frequency value for the term. */
+ frequency: number;
+ /** The display value for the frequency, or `null` if none is specified. */
+ displayValue: string | null;
+ /** Whether or not the `frequency` field is derived from a parsed string. */
+ displayValueParsed: boolean;
+};
+
+export type TagGroup = {
+ dictionary: string;
+ tagNames: string[];
+};
+
+export type TagExpansionTarget = {
+ tags: Dictionary.Tag[];
+ tagGroups: TagGroup[];
+};
+
+export type DictionaryTagCache = Map<string, TagCache>;
+
+export type TagCache = Map<string, DictionaryDatabaseTypes.Tag | null>;
+
+export type TagTargetMap = Map<string, Map<string, TagTargetItem>>;
+
+export type TagTargetItem = {
+ query: string;
+ dictionary: string;
+ tagName: string;
+ cache: TagCache | null;
+ databaseTag: DictionaryDatabaseTypes.Tag | null;
+ targets: Dictionary.Tag[][];
+};
+
+export type DictionaryEntryGroup = {
+ ids: Set<number>;
+ dictionaryEntries: Dictionary.TermDictionaryEntry[];
+};
+
+export type SequenceQuery = {
+ query: number;
+ dictionary: string;
+};
+
+export type FindTermsMode = 'simple' | 'group' | 'merge' | 'split';
+
+export type TermReadingItem = {
+ term: string;
+ reading: string | null;
+};
+
+export type TermReadingList = TermReadingItem[];
+
+export type FindTermsResult = {
+ dictionaryEntries: Dictionary.TermDictionaryEntry[];
+ originalTextLength: number;
+};
diff --git a/types/other/globals.d.ts b/types/other/globals.d.ts
new file mode 100644
index 00000000..4f6db6c9
--- /dev/null
+++ b/types/other/globals.d.ts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+declare global {
+ function clearTimeout(timeoutId: NodeJS.Timeout | string | number | undefined): void;
+}
+
+export { };
diff --git a/types/other/rollup-parse-ast.d.ts b/types/other/rollup-parse-ast.d.ts
new file mode 100644
index 00000000..52a5ec98
--- /dev/null
+++ b/types/other/rollup-parse-ast.d.ts
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+// Patch for type definitions that aren't exported for rollup/parseAst
+// https://github.com/vitest-dev/vitest/issues/4567
+// https://github.com/rollup/rollup/issues/5199
+
+import type {ParseAst, ParseAstAsync} from 'rollup';
+
+export const parseAst: ParseAst;
+export const parseAstAsync: ParseAstAsync;
diff --git a/types/test/document-types.d.ts b/types/test/document-types.d.ts
new file mode 100644
index 00000000..44831397
--- /dev/null
+++ b/types/test/document-types.d.ts
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2023 Yomitan Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+export type PseudoDOMRectList = DOMRect[] & {item: (index: number) => DOMRect};