From 909a5cd14a7ec67e455c7f3c15349bbe05b4eb7b Mon Sep 17 00:00:00 2001 From: Abourass Date: Thu, 19 Sep 2024 17:33:34 -0600 Subject: [PATCH] Refactor fontLoader module to add FontWatcher and Watcher classes --- dist/class/Tome.d.ts | 8 +- dist/class/Tome.d.ts.map | 2 +- dist/modules/fontLoader/CustomLoader.d.ts | 25 + dist/modules/fontLoader/CustomLoader.d.ts.map | 1 + dist/modules/fontLoader/FontLoader.d.ts | 7 + dist/modules/fontLoader/FontLoader.d.ts.map | 1 + dist/modules/fontLoader/GoogleLoader.d.ts | 38 + dist/modules/fontLoader/GoogleLoader.d.ts.map | 1 + dist/modules/fontLoader/utils/CSSParser.d.ts | 27 + .../fontLoader/utils/CSSParser.d.ts.map | 1 + dist/modules/fontLoader/utils/EventBus.d.ts | 27 + .../fontLoader/utils/EventBus.d.ts.map | 1 + dist/modules/fontLoader/utils/FontParser.d.ts | 21 + .../fontLoader/utils/FontParser.d.ts.map | 1 + .../modules/fontLoader/utils/FontWatcher.d.ts | 10 + .../fontLoader/utils/FontWatcher.d.ts.map | 1 + dist/modules/fontLoader/utils/Watcher.d.ts | 10 + .../modules/fontLoader/utils/Watcher.d.ts.map | 1 + dist/submodules/narrator/Narrator.d.ts | 12 + dist/submodules/narrator/Narrator.d.ts.map | 2 +- dist/wonderlost.mjs | 2 +- dist/wonderlost.mjs.map | 2 +- src/class/Tome.ts | 38 +- src/modules/fontLoader/CustomLoader.ts | 61 + src/modules/fontLoader/FontLoader.ts | 90 + src/modules/fontLoader/GoogleLoader.ts | 82 + src/modules/fontLoader/types/index.d.ts | 57 + src/modules/fontLoader/utils/CSSParser.ts | 75 + src/modules/fontLoader/utils/EventBus.ts | 142 ++ src/modules/fontLoader/utils/FontParser.ts | 177 ++ src/modules/fontLoader/utils/FontWatcher.ts | 28 + src/modules/fontLoader/utils/Watcher.ts | 37 + src/submodules/narrator/Narrator.ts | 182 +- src/wonderlost.ts | 22 +- styles/narrator.css | 1718 +++++++++++++++++ 35 files changed, 2889 insertions(+), 21 deletions(-) create mode 100644 dist/modules/fontLoader/CustomLoader.d.ts create mode 100644 dist/modules/fontLoader/CustomLoader.d.ts.map create mode 100644 dist/modules/fontLoader/FontLoader.d.ts create mode 100644 dist/modules/fontLoader/FontLoader.d.ts.map create mode 100644 dist/modules/fontLoader/GoogleLoader.d.ts create mode 100644 dist/modules/fontLoader/GoogleLoader.d.ts.map create mode 100644 dist/modules/fontLoader/utils/CSSParser.d.ts create mode 100644 dist/modules/fontLoader/utils/CSSParser.d.ts.map create mode 100644 dist/modules/fontLoader/utils/EventBus.d.ts create mode 100644 dist/modules/fontLoader/utils/EventBus.d.ts.map create mode 100644 dist/modules/fontLoader/utils/FontParser.d.ts create mode 100644 dist/modules/fontLoader/utils/FontParser.d.ts.map create mode 100644 dist/modules/fontLoader/utils/FontWatcher.d.ts create mode 100644 dist/modules/fontLoader/utils/FontWatcher.d.ts.map create mode 100644 dist/modules/fontLoader/utils/Watcher.d.ts create mode 100644 dist/modules/fontLoader/utils/Watcher.d.ts.map create mode 100644 src/modules/fontLoader/CustomLoader.ts create mode 100644 src/modules/fontLoader/FontLoader.ts create mode 100644 src/modules/fontLoader/GoogleLoader.ts create mode 100644 src/modules/fontLoader/types/index.d.ts create mode 100644 src/modules/fontLoader/utils/CSSParser.ts create mode 100644 src/modules/fontLoader/utils/EventBus.ts create mode 100644 src/modules/fontLoader/utils/FontParser.ts create mode 100644 src/modules/fontLoader/utils/FontWatcher.ts create mode 100644 src/modules/fontLoader/utils/Watcher.ts create mode 100644 styles/narrator.css diff --git a/dist/class/Tome.d.ts b/dist/class/Tome.d.ts index 524cc9d..b1ae78c 100644 --- a/dist/class/Tome.d.ts +++ b/dist/class/Tome.d.ts @@ -1,4 +1,5 @@ -type HookableEvents = "renderChatLog" | "renderChatMessage"; +type CoreLifeCycleHooks = 'init' | 'ready' | 'error' | 'setup' | 'i18nInit'; +type HookableEvents = "renderChatLog" | "renderChatMessage" | 'renderApplication' | CoreLifeCycleHooks; type HookEvent = (app: Application, html: JQuery, data?: any) => void | Promise; interface RuleMenu extends ClientSettings.PartialSettingSubmenuConfig { } @@ -14,6 +15,7 @@ interface Rule { * @comment false if you dont want it to show in module config */ config?: boolean; + choices?: Record; } type NumberRule = Rule & { type: typeof Number; @@ -65,6 +67,10 @@ export declare abstract class Tome { ready: boolean; get name(): string; get lowercaseName(): string; + get hasHooks(): boolean; + get hasSettings(): boolean; + get hasSocketFns(): boolean; + get needsEarlyInitialization(): boolean; constructor(pTome: Pick & { settings?: TomeRuleConstructor; hooks?: Tome["hooks"]; diff --git a/dist/class/Tome.d.ts.map b/dist/class/Tome.d.ts.map index a6b2659..a7bda47 100644 --- a/dist/class/Tome.d.ts.map +++ b/dist/class/Tome.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"Tome.d.ts","sourceRoot":"","sources":["../../src/class/Tome.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"Tome.d.ts","sourceRoot":"","sources":["../../src/class/Tome.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/modules/fontLoader/CustomLoader.d.ts b/dist/modules/fontLoader/CustomLoader.d.ts new file mode 100644 index 0000000..dedc0c7 --- /dev/null +++ b/dist/modules/fontLoader/CustomLoader.d.ts @@ -0,0 +1,25 @@ +import type { FontLoader, Font, CustomFamilies, ParsedFont } from './types'; +export declare class CustomLoader implements FontLoader { + private readonly fonts_; + private readonly uris_; + constructor(config: CustomFamilies); + /** + * Returns parsed uris strings + */ + getUris(): string[]; + /** + * Return all font's that should be loaded + */ + getFonts(): Font[]; + /** + * Returns font object array + */ + getParsedFonts(): ParsedFont[]; + /** + * Parsing config to separate string and object families + * @param families + * @private + */ + private parseFamilyConfig_; +} +//# sourceMappingURL=CustomLoader.d.ts.map \ No newline at end of file diff --git a/dist/modules/fontLoader/CustomLoader.d.ts.map b/dist/modules/fontLoader/CustomLoader.d.ts.map new file mode 100644 index 0000000..2ebc279 --- /dev/null +++ b/dist/modules/fontLoader/CustomLoader.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"CustomLoader.d.ts","sourceRoot":"","sources":["../../../src/modules/fontLoader/CustomLoader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,EAAE,UAAU,EAAgB,MAAM,SAAS,CAAC;AAE1F,qBAAa,YAAa,YAAW,UAAU;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAW;gBAErB,MAAM,EAAE,cAAc;IAMlC;;OAEG;IACH,OAAO,IAAI,MAAM,EAAE;IAInB;;OAEG;IACH,QAAQ,IAAI,IAAI,EAAE;IAIlB;;OAEG;IACH,cAAc,IAAI,UAAU,EAAE;IAK9B;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;CAqB3B"} \ No newline at end of file diff --git a/dist/modules/fontLoader/FontLoader.d.ts b/dist/modules/fontLoader/FontLoader.d.ts new file mode 100644 index 0000000..5810ad4 --- /dev/null +++ b/dist/modules/fontLoader/FontLoader.d.ts @@ -0,0 +1,7 @@ +import type { FontsLoaderConfig } from './types'; +/** + * Main function that loads all the fonts to tag + * @param fontsLoaderConfig + */ +export declare const FontsLoader: (fontsLoaderConfig: FontsLoaderConfig) => Promise; +//# sourceMappingURL=FontLoader.d.ts.map \ No newline at end of file diff --git a/dist/modules/fontLoader/FontLoader.d.ts.map b/dist/modules/fontLoader/FontLoader.d.ts.map new file mode 100644 index 0000000..aab4777 --- /dev/null +++ b/dist/modules/fontLoader/FontLoader.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"FontLoader.d.ts","sourceRoot":"","sources":["../../../src/modules/fontLoader/FontLoader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAA4B,iBAAiB,EAAc,MAAM,SAAS,CAAC;AAUvF;;;GAGG;AACH,eAAO,MAAM,WAAW,sBAA6B,iBAAiB,KAAG,OAAO,CAAC,IAAI,CA6CpF,CAAC"} \ No newline at end of file diff --git a/dist/modules/fontLoader/GoogleLoader.d.ts b/dist/modules/fontLoader/GoogleLoader.d.ts new file mode 100644 index 0000000..9a5d375 --- /dev/null +++ b/dist/modules/fontLoader/GoogleLoader.d.ts @@ -0,0 +1,38 @@ +import type { FontLoader, FontFamilies, Font, ParsedFont } from './types'; +export declare class GoogleFontApi { + private apiUrl_; + private fonts_; + private version_; + /** + * @param fonts + * @param version + */ + constructor(fonts: string[], version?: 1 | 2); + /** + * Builds font googleapis url from given fonts in constructor + * @return string + */ + buildUri(): string; +} +export declare class GoogleLoader implements FontLoader { + private fonts_; + private uri_; + constructor(fonts: FontFamilies); + /** + * Returns google uri to get all the fonts + */ + getUris(): string[]; + /** + * Return all google font's that should be loaded + */ + getFonts(): Font[]; + /** + * Returns ParsedFont array for native font loading + */ + getParsedFonts(): Promise; + /** + * Generates google font api url from given array of fonts + */ + private generateUri_; +} +//# sourceMappingURL=GoogleLoader.d.ts.map \ No newline at end of file diff --git a/dist/modules/fontLoader/GoogleLoader.d.ts.map b/dist/modules/fontLoader/GoogleLoader.d.ts.map new file mode 100644 index 0000000..37717fb --- /dev/null +++ b/dist/modules/fontLoader/GoogleLoader.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"GoogleLoader.d.ts","sourceRoot":"","sources":["../../../src/modules/fontLoader/GoogleLoader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAI1E,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAsC;IAGrD,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,QAAQ,CAAQ;IAExB;;;OAGG;gBACS,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,CAAC,GAAG,CAAK;IAK/C;;;OAGG;IACI,QAAQ,IAAI,MAAM;CAU1B;AAED,qBAAa,YAAa,YAAW,UAAU;IAC7C,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,IAAI,CAAqB;gBAErB,KAAK,EAAE,YAAY;IAK/B;;OAEG;IACI,OAAO,IAAI,MAAM,EAAE;IAI1B;;OAEG;IACI,QAAQ,IAAI,IAAI,EAAE;IAMzB;;OAEG;IACU,cAAc,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAUpD;;OAEG;IACH,OAAO,CAAC,YAAY;CAIrB"} \ No newline at end of file diff --git a/dist/modules/fontLoader/utils/CSSParser.d.ts b/dist/modules/fontLoader/utils/CSSParser.d.ts new file mode 100644 index 0000000..61b5158 --- /dev/null +++ b/dist/modules/fontLoader/utils/CSSParser.d.ts @@ -0,0 +1,27 @@ +import type { ParsedFont } from '../types'; +export declare class CssParser { + private css_; + private rules_; + constructor(fontFaceResponseText: string); + /** + * Returns ParsedFont array of parsed CSS + */ + getParsedFonts(): ParsedFont[]; + /** + * Parses CSS into array of ParsedFont object + */ + parseCSS(): void; + /** + * Parsing css block + * @param css + * @private + */ + private parseCSSBlock_; + /** + * Removes all empty lines from CSS + * @param css + * @private + */ + private removeNewLines_; +} +//# sourceMappingURL=CSSParser.d.ts.map \ No newline at end of file diff --git a/dist/modules/fontLoader/utils/CSSParser.d.ts.map b/dist/modules/fontLoader/utils/CSSParser.d.ts.map new file mode 100644 index 0000000..b745008 --- /dev/null +++ b/dist/modules/fontLoader/utils/CSSParser.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"CSSParser.d.ts","sourceRoot":"","sources":["../../../../src/modules/fontLoader/utils/CSSParser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,qBAAa,SAAS;IACpB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,MAAM,CAAoB;gBAEtB,oBAAoB,EAAE,MAAM;IAIxC;;OAEG;IACI,cAAc,IAAI,UAAU,EAAE;IAIrC;;OAEG;IACI,QAAQ;IAkBf;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAuBtB;;;;OAIG;IACH,OAAO,CAAC,eAAe;CAGxB"} \ No newline at end of file diff --git a/dist/modules/fontLoader/utils/EventBus.d.ts b/dist/modules/fontLoader/utils/EventBus.d.ts new file mode 100644 index 0000000..fa95076 --- /dev/null +++ b/dist/modules/fontLoader/utils/EventBus.d.ts @@ -0,0 +1,27 @@ +import type { FontsLoaderConfig } from '../types'; +export declare enum FontEvents { + LOADING = "loading", + ACTIVE = "active", + INACTIVE = "inactive", + FONT_LOADING = "fontloading", + FONT_ACTIVE = "fontactive", + FONT_INACTIVE = "fontinactive" +} +export declare class EventBus { + private namespace_; + private classSeparator_; + private event_; + private config_; + private htmlElement_; + constructor(config: FontsLoaderConfig); + private handleLoading_; + private handleActive_; + private handleInactive_; + private handleFontLoading_; + private handleFontActive_; + private handleFontInactive_; + private addClassToHtml_; + private removeClassFromHtml_; + private sanitizeClassName_; +} +//# sourceMappingURL=EventBus.d.ts.map \ No newline at end of file diff --git a/dist/modules/fontLoader/utils/EventBus.d.ts.map b/dist/modules/fontLoader/utils/EventBus.d.ts.map new file mode 100644 index 0000000..7c060a2 --- /dev/null +++ b/dist/modules/fontLoader/utils/EventBus.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"EventBus.d.ts","sourceRoot":"","sources":["../../../../src/modules/fontLoader/utils/EventBus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAElD,oBAAY,UAAU;IACpB,OAAO,YAAY;IACnB,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,YAAY,gBAAgB;IAC5B,WAAW,eAAe;IAC1B,aAAa,iBAAiB;CAC/B;AAED,qBAAa,QAAQ;IACnB,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,eAAe,CAAO;IAC9B,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,YAAY,CAAC;gBAET,MAAM,EAAE,iBAAiB;IAmDrC,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,oBAAoB;IAM5B,OAAO,CAAC,kBAAkB;CAG3B"} \ No newline at end of file diff --git a/dist/modules/fontLoader/utils/FontParser.d.ts b/dist/modules/fontLoader/utils/FontParser.d.ts new file mode 100644 index 0000000..0b7146a --- /dev/null +++ b/dist/modules/fontLoader/utils/FontParser.d.ts @@ -0,0 +1,21 @@ +/** Source: https://github.com/typekit/webfontloader/blob/master/src/modules/google/fontapiparser.js */ +import type { Font } from '../types'; +export declare class FontParser { + private fontFamilies; + private parsedFonts; + private fontTestStrings; + private INT_FONTS; + private WEIGHTS; + private STYLES; + private VARIATION_MATCH; + constructor(fontFamilies: string[]); + parse(): void; + private generateFontVariationDescription; + private normalizeStyle; + private normalizeWeight; + private parseVariations; + parseSubsets(subsets: T): T[]; + getFonts(): Font[]; + getFontTestStrings(): Record; +} +//# sourceMappingURL=FontParser.d.ts.map \ No newline at end of file diff --git a/dist/modules/fontLoader/utils/FontParser.d.ts.map b/dist/modules/fontLoader/utils/FontParser.d.ts.map new file mode 100644 index 0000000..ebbb6af --- /dev/null +++ b/dist/modules/fontLoader/utils/FontParser.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"FontParser.d.ts","sourceRoot":"","sources":["../../../../src/modules/fontLoader/utils/FontParser.ts"],"names":[],"mappings":"AAAA,uGAAuG;AAEvG,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAGrC,qBAAa,UAAU;IACrB,OAAO,CAAC,YAAY,CAAW;IAC/B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,eAAe,CAAyB;IAEhD,OAAO,CAAC,SAAS,CAOf;IACF,OAAO,CAAC,OAAO,CAwBb;IACF,OAAO,CAAC,MAAM,CAKZ;IACF,OAAO,CAAC,eAAe,CAIrB;gBAEU,YAAY,EAAE,MAAM,EAAE;IAM3B,KAAK,IAAI,IAAI;IAuCpB,OAAO,CAAC,gCAAgC;IAcxC,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,eAAe;IAoBhB,YAAY,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE;IASxD,QAAQ;IAIR,kBAAkB;CAG1B"} \ No newline at end of file diff --git a/dist/modules/fontLoader/utils/FontWatcher.d.ts b/dist/modules/fontLoader/utils/FontWatcher.d.ts new file mode 100644 index 0000000..62f9ba7 --- /dev/null +++ b/dist/modules/fontLoader/utils/FontWatcher.d.ts @@ -0,0 +1,10 @@ +import type { Font, LoadingMethod } from '../types'; +export declare class FontWatcher { + private font_; + private load_; + constructor(font: Font, load: LoadingMethod); + private loading_; + getFont(): Font; + watch(): boolean; +} +//# sourceMappingURL=FontWatcher.d.ts.map \ No newline at end of file diff --git a/dist/modules/fontLoader/utils/FontWatcher.d.ts.map b/dist/modules/fontLoader/utils/FontWatcher.d.ts.map new file mode 100644 index 0000000..9337c41 --- /dev/null +++ b/dist/modules/fontLoader/utils/FontWatcher.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"FontWatcher.d.ts","sourceRoot":"","sources":["../../../../src/modules/fontLoader/utils/FontWatcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGpD,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAO;IACpB,OAAO,CAAC,KAAK,CAAgB;gBAEjB,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,aAAa;IAO3C,OAAO,CAAC,QAAQ;IAMT,OAAO,IAAI,IAAI;IAIf,KAAK,IAAI,OAAO;CAGxB"} \ No newline at end of file diff --git a/dist/modules/fontLoader/utils/Watcher.d.ts b/dist/modules/fontLoader/utils/Watcher.d.ts new file mode 100644 index 0000000..d56b149 --- /dev/null +++ b/dist/modules/fontLoader/utils/Watcher.d.ts @@ -0,0 +1,10 @@ +import type { Font, LoadingMethod } from '../types'; +export declare class Watcher { + private fontWatchers_; + private loadedFonts_; + private watched_; + add(font: Font, load: LoadingMethod): void; + fontLoaded(fontName: string): void; + watchFonts(): void; +} +//# sourceMappingURL=Watcher.d.ts.map \ No newline at end of file diff --git a/dist/modules/fontLoader/utils/Watcher.d.ts.map b/dist/modules/fontLoader/utils/Watcher.d.ts.map new file mode 100644 index 0000000..99d578d --- /dev/null +++ b/dist/modules/fontLoader/utils/Watcher.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Watcher.d.ts","sourceRoot":"","sources":["../../../../src/modules/fontLoader/utils/Watcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAIpD,qBAAa,OAAO;IAClB,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,QAAQ,CAAS;IAElB,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,aAAa;IAInC,UAAU,CAAC,QAAQ,EAAE,MAAM;IAI3B,UAAU;CAmBlB"} \ No newline at end of file diff --git a/dist/submodules/narrator/Narrator.d.ts b/dist/submodules/narrator/Narrator.d.ts index a4caa55..d4dc990 100644 --- a/dist/submodules/narrator/Narrator.d.ts +++ b/dist/submodules/narrator/Narrator.d.ts @@ -1,5 +1,17 @@ import { Tome } from 'src/class/Tome'; export declare class Narrator extends Tome { + static fonts: readonly ["Caslon", "CaslonAntique", "SignikaBold", "Riffic", "IronSans", "LinLibertine", "TimesNewRomance", "TimesNewYorker", "LPEducational", "Cardinal", "OldLondon", "StoneHenge", "SunnyDay", "PaulSignature", "LemonTuesday", "FairProsper", "BalletHarmony", "MagieraScript", "Cathallina", "Hamish", "DreamersBrush", "FastInMyCar", "ChildWriting", "Kindergarten", "FuturaHandwritten", "Fewriter", "TrashHand", "GoodBrush", "BaksoSapi", "SuplexmentaryComic", "ComicInk", "DreamyLand", "Yikes", "GangOfThree", "JianGkrik", "Yozakura", "Hiroshio", "ArabDances", "Rooters", "Subway", "Himagsikan", "MilTown", "Galactico", "Oko", "Ethnocentric", "VenusRising", "StampAct", "Kirsty", "Western", "BreakAway", "YoungerThanMe", "Underground", "VarsityTeam", "Valentino", "GlassHouses", "Makayla", "DancingVampyrish", "Codex", "DSNetStamped", "HappyFrushZero", "Shoplifter", "Stereofidelic", "Headache", "HorrorHouse", "GhostTheory2", "Syemox", "GhostChase"]; + static fontWeights: readonly ["100", "200", "300", "400", "500", "600", "700", "800", "900"]; + static fontStyles: readonly ["normal", "italic", "oblique"]; + get titleFont(): "Caslon" | "CaslonAntique" | "SignikaBold" | "Riffic" | "IronSans" | "LinLibertine" | "TimesNewRomance" | "TimesNewYorker" | "LPEducational" | "Cardinal" | "OldLondon" | "StoneHenge" | "SunnyDay" | "PaulSignature" | "LemonTuesday" | "FairProsper" | "BalletHarmony" | "MagieraScript" | "Cathallina" | "Hamish" | "DreamersBrush" | "FastInMyCar" | "ChildWriting" | "Kindergarten" | "FuturaHandwritten" | "Fewriter" | "TrashHand" | "GoodBrush" | "BaksoSapi" | "SuplexmentaryComic" | "ComicInk" | "DreamyLand" | "Yikes" | "GangOfThree" | "JianGkrik" | "Yozakura" | "Hiroshio" | "ArabDances" | "Rooters" | "Subway" | "Himagsikan" | "MilTown" | "Galactico" | "Oko" | "Ethnocentric" | "VenusRising" | "StampAct" | "Kirsty" | "Western" | "BreakAway" | "YoungerThanMe" | "Underground" | "VarsityTeam" | "Valentino" | "GlassHouses" | "Makayla" | "DancingVampyrish" | "Codex" | "DSNetStamped" | "HappyFrushZero" | "Shoplifter" | "Stereofidelic" | "Headache" | "HorrorHouse" | "GhostTheory2" | "Syemox" | "GhostChase"; + static get titleFont(): typeof Narrator['fonts'][number]; + static set titleFont(value: typeof Narrator['fonts'][number]); + get textFont(): "Caslon" | "CaslonAntique" | "SignikaBold" | "Riffic" | "IronSans" | "LinLibertine" | "TimesNewRomance" | "TimesNewYorker" | "LPEducational" | "Cardinal" | "OldLondon" | "StoneHenge" | "SunnyDay" | "PaulSignature" | "LemonTuesday" | "FairProsper" | "BalletHarmony" | "MagieraScript" | "Cathallina" | "Hamish" | "DreamersBrush" | "FastInMyCar" | "ChildWriting" | "Kindergarten" | "FuturaHandwritten" | "Fewriter" | "TrashHand" | "GoodBrush" | "BaksoSapi" | "SuplexmentaryComic" | "ComicInk" | "DreamyLand" | "Yikes" | "GangOfThree" | "JianGkrik" | "Yozakura" | "Hiroshio" | "ArabDances" | "Rooters" | "Subway" | "Himagsikan" | "MilTown" | "Galactico" | "Oko" | "Ethnocentric" | "VenusRising" | "StampAct" | "Kirsty" | "Western" | "BreakAway" | "YoungerThanMe" | "Underground" | "VarsityTeam" | "Valentino" | "GlassHouses" | "Makayla" | "DancingVampyrish" | "Codex" | "DSNetStamped" | "HappyFrushZero" | "Shoplifter" | "Stereofidelic" | "Headache" | "HorrorHouse" | "GhostTheory2" | "Syemox" | "GhostChase"; + static get textFont(): typeof Narrator['fonts'][number]; + static set textFont(value: typeof Narrator['fonts'][number]); + get titleWeight(): "100" | "200" | "300" | "400" | "500" | "600" | "700" | "800" | "900"; + static get titleWeight(): typeof Narrator['fontWeights'][number]; + static set titleWeight(value: typeof Narrator['fontWeights'][number]); constructor(DEBUG?: boolean); } //# sourceMappingURL=Narrator.d.ts.map \ No newline at end of file diff --git a/dist/submodules/narrator/Narrator.d.ts.map b/dist/submodules/narrator/Narrator.d.ts.map index 0fe7e1d..2fbdad8 100644 --- a/dist/submodules/narrator/Narrator.d.ts.map +++ b/dist/submodules/narrator/Narrator.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"Narrator.d.ts","sourceRoot":"","sources":["../../../src/submodules/narrator/Narrator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEtC,qBAAa,QAAS,SAAQ,IAAI;gBACpB,KAAK,UAAQ;CAS1B"} \ No newline at end of file +{"version":3,"file":"Narrator.d.ts","sourceRoot":"","sources":["../../../src/submodules/narrator/Narrator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAGtC,qBAAa,QAAS,SAAQ,IAAI;IAChC,OAAc,KAAK,w7BAoER;IACX,OAAc,WAAW,2EAUd;IACX,OAAc,UAAU,2CAIb;IAEX,IAAW,SAAS,i/BAEnB;IACD,WAAkB,SAAS,IAIQ,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CADlE;IACD,WAAkB,SAAS,CAAC,KAAK,EAAE,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,EAElE;IAED,IAAW,QAAQ,i/BAElB;IACD,WAAkB,QAAQ,IAIQ,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CADjE;IACD,WAAkB,QAAQ,CAAC,KAAK,EAAE,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,EAEjE;IAED,IAAW,WAAW,0EAErB;IACD,WAAkB,WAAW,IAIQ,OAAO,QAAQ,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,CAD1E;IACD,WAAkB,WAAW,CAAC,KAAK,EAAE,OAAO,QAAQ,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,EAE1E;gBAEW,KAAK,UAAQ;CAqE1B"} \ No newline at end of file diff --git a/dist/wonderlost.mjs b/dist/wonderlost.mjs index 22ca89b..f02cd8d 100644 --- a/dist/wonderlost.mjs +++ b/dist/wonderlost.mjs @@ -1,2 +1,2 @@ -import{TweenMax as e}from"../../../scripts/greensock/esm/all.js";const t={silent:Number.NEGATIVE_INFINITY,fatal:0,error:0,warn:1,log:2,info:3,success:3,fail:3,ready:3,start:3,box:3,debug:4,trace:5,verbose:Number.POSITIVE_INFINITY},s={silent:{level:-1},fatal:{level:t.fatal},error:{level:t.error},warn:{level:t.warn},log:{level:t.log},info:{level:t.info},success:{level:t.success},fail:{level:t.fail},ready:{level:t.info},start:{level:t.info},box:{level:t.info},debug:{level:t.debug},trace:{level:t.trace},verbose:{level:t.verbose}};function n(e){return null!==e&&"object"==typeof e}function o(e,t,s=".",i){if(!n(t))return o(e,{},s);const r=Object.assign({},t);for(const t in e){if("__proto__"===t||"constructor"===t)continue;const i=e[t];null!=i&&(Array.isArray(i)&&Array.isArray(r[t])?r[t]=[...i,...r[t]]:n(i)&&n(r[t])?r[t]=o(i,r[t],(s?`${s}.`:"")+t.toString()):r[t]=i)}return r}const i=(...e)=>e.reduce(((e,t)=>o(e,t,"")),{});function r(e){return t=e,"[object Object]"===Object.prototype.toString.call(t)&&(!(!e.message&&!e.args)&&!e.stack);var t}let a=!1;const l=[];class h{constructor(e={}){const t=e.types||s;this.options=i({...e,defaults:{...e.defaults},level:c(e.level,t),reporters:[...e.reporters||[]]},{types:s,throttle:1e3,throttleMin:5,formatOptions:{date:!0,colors:!1,compact:!0}});for(const e in t){const s={type:e,...this.options.defaults,...t[e]};this[e]=this._wrapLogFn(s),this[e].raw=this._wrapLogFn(s,!0)}this.options.mockFn&&this.mockTypes(),this._lastLog={}}get level(){return this.options.level}set level(e){this.options.level=c(e,this.options.types,this.options.level)}prompt(e,t){if(!this.options.prompt)throw new Error("prompt is not supported!");return this.options.prompt(e,t)}create(e){const t=new h({...this.options,...e});return this._mockFn&&t.mockTypes(this._mockFn),t}withDefaults(e){return this.create({...this.options,defaults:{...this.options.defaults,...e}})}withTag(e){return this.withDefaults({tag:this.options.defaults.tag?this.options.defaults.tag+":"+e:e})}addReporter(e){return this.options.reporters.push(e),this}removeReporter(e){if(e){const t=this.options.reporters.indexOf(e);if(t>=0)return this.options.reporters.splice(t,1)}else this.options.reporters.splice(0);return this}setReporters(e){return this.options.reporters=Array.isArray(e)?e:[e],this}wrapAll(){this.wrapConsole(),this.wrapStd()}restoreAll(){this.restoreConsole(),this.restoreStd()}wrapConsole(){for(const e in this.options.types)console["__"+e]||(console["__"+e]=console[e]),console[e]=this[e].raw}restoreConsole(){for(const e in this.options.types)console["__"+e]&&(console[e]=console["__"+e],delete console["__"+e])}wrapStd(){this._wrapStream(this.options.stdout,"log"),this._wrapStream(this.options.stderr,"log")}_wrapStream(e,t){e&&(e.__write||(e.__write=e.write),e.write=e=>{this[t].raw(String(e).trim())})}restoreStd(){this._restoreStream(this.options.stdout),this._restoreStream(this.options.stderr)}_restoreStream(e){e&&e.__write&&(e.write=e.__write,delete e.__write)}pauseLogs(){a=!0}resumeLogs(){a=!1;const e=l.splice(0);for(const t of e)t[0]._logFn(t[1],t[2])}mockTypes(e){const t=e||this.options.mockFn;if(this._mockFn=t,"function"==typeof t)for(const e in this.options.types)this[e]=t(e,this.options.types[e])||this[e],this[e].raw=this[e]}_wrapLogFn(e,t){return(...s)=>{if(!a)return this._logFn(e,s,t);l.push([this,e,s,t])}}_logFn(e,t,s){if((e.level||0)>this.level)return!1;const n={date:new Date,args:[],...e,level:c(e.level,this.options.types)};!s&&1===t.length&&r(t[0])?Object.assign(n,t[0]):n.args=[...t],n.message&&(n.args.unshift(n.message),delete n.message),n.additional&&(Array.isArray(n.additional)||(n.additional=n.additional.split("\n")),n.args.push("\n"+n.additional.join("\n")),delete n.additional),n.type="string"==typeof n.type?n.type.toLowerCase():"log",n.tag="string"==typeof n.tag?n.tag:"";const o=(e=!1)=>{const t=(this._lastLog.count||0)-this.options.throttleMin;if(this._lastLog.object&&t>0){const e=[...this._lastLog.object.args];t>1&&e.push(`(repeated ${t} times)`),this._log({...this._lastLog.object,args:e}),this._lastLog.count=1}e&&(this._lastLog.object=n,this._log(n))};clearTimeout(this._lastLog.timeout);const i=this._lastLog.time&&n.date?n.date.getTime()-this._lastLog.time.getTime():0;if(this._lastLog.time=n.date,ithis.options.throttleMin))return void(this._lastLog.timeout=setTimeout(o,this.options.throttle))}catch{}o(!0)}_log(e){for(const t of this.options.reporters)t.log(e,{options:this.options})}}function c(e,t={},s=3){return void 0===e?s:"number"==typeof e?e:t[e]&&void 0!==t[e].level?t[e].level:s}h.prototype.add=h.prototype.addReporter,h.prototype.remove=h.prototype.removeReporter,h.prototype.clear=h.prototype.removeReporter,h.prototype.withScope=h.prototype.withTag,h.prototype.mock=h.prototype.mockTypes,h.prototype.pause=h.prototype.pauseLogs,h.prototype.resume=h.prototype.resumeLogs;class m{constructor(e){this.options={...e},this.defaultColor="#7f8c8d",this.levelColorMap={0:"#c0392b",1:"#f39c12",3:"#00BCD4"},this.typeColorMap={success:"#2ecc71"}}_getLogFn(e){return e<1?console.__error||console.error:1===e?console.__warn||console.warn:console.__log||console.log}log(e){const t=this._getLogFn(e.level),s="log"===e.type?"":e.type,n=e.tag||"",o=`\n background: ${this.typeColorMap[e.type]||this.levelColorMap[e.level]||this.defaultColor};\n border-radius: 0.5em;\n color: white;\n font-weight: bold;\n padding: 2px 0.5em;\n `,i=`%c${[n,s].filter(Boolean).join(":")}`;"string"==typeof e.args[0]?t(`${i}%c ${e.args[0]}`,o,"",...e.args.slice(1)):t(i,o,...e.args)}}const u=function(e={}){return function(e={}){return new h(e)}({reporters:e.reporters||[new m({})],prompt:(e,t={})=>"confirm"===t.type?Promise.resolve(confirm(e)):Promise.resolve(prompt(e)),...e})}();var d=Object.defineProperty,p=(e,t,s)=>(((e,t,s)=>{t in e?d(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s})(e,"symbol"!=typeof t?t+"":t,s),s);function g(e){return e instanceof HTMLElement}class f{constructor(e){if(p(this,"element"),p(this,"debug",!1),g(e))return void(this.element=e);if("function"==typeof e){const t=e();if(!t)throw new Error("Function must return an element");if(this.debug&&console.log("Function returned",t),g(t))return void(this.element=t);if("string"==typeof t){const s=document.querySelector(t);if(!s)throw new Error(`You tried to grab using '${e}' but that doesn't exist!`);return void(this.element=s)}}const t=document.querySelector(e);if(!t)throw new Error(`You tried to grab using '${e}' but that doesn't exist!`);this.element=t}self(){return this.element}toggleClass(e){return"string"==typeof e&&e.includes(" ")&&(e=e.split(" ")),Array.isArray(e)||(e=[e]),e.forEach((e=>this.element.classList.toggle(e))),this}addClass(e){return"function"==typeof e&&(e=e()),"string"==typeof e&&e.includes(" ")&&(e=e.split(" ")),Array.isArray(e)||(e=[e]),e.forEach((e=>this.element.classList.add(e))),this}removeClass(e){return"function"==typeof e&&(e=e()),"string"==typeof e&&e.includes(" ")&&(e=e.split(" ")),Array.isArray(e)||(e=[e]),e.forEach((e=>this.element.classList.remove(e))),this}hasClass(e){return this.element.classList.contains(e)}replaceWith(e){return this.element.outerHTML=e,this}replaceWithElement(e,t=void 0){const s=document.createElement(e);if(s.id=t??this.element.id,!this.element?.parentNode)throw new Error("Element has no parent node, can not replace");return this.element.parentNode.replaceChild(s,this.element),new f(`#${s.id}`)}html(e){return this.element.innerHTML=e,this}empty(){return this.element.innerHTML="",this}check(e){if(this.element instanceof HTMLInputElement)return this.element.checked=e,this;throw new TypeError(`[El::${this.element.id}] You can only use check() on input elements'`)}checked(){if(this.element instanceof HTMLInputElement)return this.element.checked;throw new TypeError(`[El::${this.element.id}] You can only use checked() on input elements'`)}click(){return this.element.dispatchEvent(new MouseEvent("click",{view:window,bubbles:!0,cancelable:!1})),this}if(e){return e?this:null}wrap(e){const t=document.createElement("div");if(t.className=e,!this.element?.parentNode)throw new Error("Element has no parent node, can not wrap");return this.element.parentNode.insertBefore(t,this.element),this.element.parentNode.removeChild(this.element),t.appendChild(this.element),this}src(e){if(!(this.element instanceof HTMLImageElement))throw new TypeError(`[El::${this.element.id}] You can only use src() on image elements'`);return this.element.src=e,this}alt(e){if(!(this.element instanceof HTMLImageElement))throw new TypeError(`[El::${this.element.id}] You can only use alt() on image elements'`);return this.element.alt=e,this}parent(){const e=this.element.parentElement;if(!e)throw new Error("Element has no parent node, can not get parent");return e.id||(e.id=`parent-${this.element.id}`),new f(`#${e?.id}`)}remove(){if(!this.element?.parentNode)throw new Error("Element has no parent node, can not remove");return this.element.parentNode.removeChild(this.element),this}clear(){return this.element.innerHTML="",this}unset(e){return"string"==typeof e&&(e=[e]),e.forEach((e=>{this.element.removeAttribute(e)})),this}set(e){return Object.entries(e).forEach((([e,t])=>{t&&this.element.setAttribute(e,"string"==typeof t?t:t.toString())})),this}firstChild(){return this.element.firstElementChild}child(e,t=null){return"string"==typeof e?t&&"append"!==t?this.element.insertAdjacentHTML("afterbegin",e):this.element.insertAdjacentHTML("beforeend",e):("append"!==t&&null!=t||this.element.append(e),"prepend"===t&&this.element.prepend(e)),this}children(){return this.element.childNodes}text(e){return e?(this.element.textContent=e.toString(),this):this}textContent(e){return e?(this.element.textContent=e,this):this.element.textContent}textChild(e){const t=document.createTextNode(e.toString());return this.element.appendChild(t),this}type(e){return"type"in this.element&&this.element.setAttribute("type",e),this}name(e){return"name"in this.element&&(this.element.name=e),this}input(e){return"name"in this.element&&(this.element.name=this.element.id),"type"in this.element&&this.element.setAttribute("type",e),this}htmlFor(e){return"htmlFor"in this.element&&this.element.setAttribute("for",e),this}id(e){return e?(this.element.id=e,this):this.element.id}val(e){if(this.element instanceof HTMLInputElement||this.element instanceof HTMLSelectElement||this.element instanceof HTMLTextAreaElement||this.element instanceof HTMLOptionElement||this.element instanceof HTMLProgressElement)return null==e?this.element.value:(this.element.value=e instanceof Date?`${e.getFullYear()}-${e.getMonth()+1}-${e.getDate()}`:"string"==typeof e?e:e.toString(),this);throw new TypeError(`[El::${this.element.id}] You can only use val() on input / select / text area / progress elements'`)}data(e){return this.element.getAttribute(`data-${e}`)}dataset(){return this.element.dataset}on(e,t,s){return this.element.addEventListener(e,t,s),this}once(e,t){return this.element.addEventListener(e,t,{once:!0}),this}now(e,t){return this.element.dispatchEvent(new CustomEvent(e,{detail:t})),this}off(e,t,s){return this.element.removeEventListener(e,t,s),this}trigger(e,t){return this.element.dispatchEvent(new CustomEvent(e,t)),this}triggerChange(){if(this.element instanceof HTMLSelectElement){const e=document.createEvent("HTMLEvents");return e.initEvent("change",!0,!0),this.element.dispatchEvent(e),this}throw new TypeError(`[El::${this.element.id}] You can only use triggerChange() on select elements'`)}find(e){return this.element.querySelectorAll(e)}dispatchEvent(e){return this.element.dispatchEvent(new Event(e)),this}nestFrom(e){return e(`#${this.element.id}`),this}}class y{moduleName;moduleDescription;settings=[];hooks=new Map([]);socketFns=new Map;DEBUG=!1;ready=!1;get name(){return this.moduleName}get lowercaseName(){return this.moduleName.toLowerCase()}constructor(e){this.moduleName=e.moduleName,this.moduleDescription=e.moduleDescription,e?.settings&&(this.settings=e.settings.globalSettings?.map((e=>(e.scope="world",e)))??[],this.settings.push(...e.settings.clientSettings?.map((e=>(e.scope="client",e)))??[])),this.hooks=e?.hooks??new Map,this.socketFns=e?.socketFns??new Map,this.DEBUG=e?.DEBUG??!1}addHook(e,t,s=!1){!this.hooks.has(e)||s?this.hooks.set(e,t):u.warn(`Hook for event "${e}" already exists.`)}initializeHooks(){return this.hooks.forEach(((e,t)=>{this.DEBUG&&u.box({title:`[TOME::${this.moduleName}] => Registering hook for ${t}`,additional:{callback:e.toString()}}),Hooks.on(t,e)})),this}registerSetting(e){switch(e.type){case Number:case Boolean:case String:case Object:case Array:case Color:this.settings.push({...e});break;default:throw new Error(`Unsupported rule type: ${e.type}`)}return this}registerSettings(e){return e.forEach((e=>{this.registerSetting(e)})),this}initializeSettings(){return this.settings.forEach((e=>{this.DEBUG&&u.box({title:`[TOME::${this.moduleName}] => Registering ${e.name}`,additional:{...e}}),game.settings?.register("wonderlost",y.kabob(`${this.lowercaseName}-${e.name}`),{name:e.name,hint:e.hint,scope:e.scope,config:!0,default:e?.defaultValue,type:e.type,choices:e?.choices,range:e?.range,onChange:e.onChange,requiresReload:e.requiresReload})})),this}getSetting(e){return game.settings?.get("wonderlost",y.kabob(`${this.lowercaseName}-${e}`))}async setSetting(e,t){return game.settings?.set("wonderlost",y.kabob(`${this.lowercaseName}-${e}`),t)}registerSettingSubmenu(e){game.settings?.register("wonderlost",y.kabob(`${this.lowercaseName}-allSettings`),{scope:"world",config:!1,type:Object,default:e.data});const t=`${this.lowercaseName}`,s=this.moduleName.toString();game.settings?.registerMenu("wonderlost",y.kabob(`${this.lowercaseName}-allSettings`),{name:e.name,label:e.label,hint:e.hint,icon:e.icon,restricted:e.restricted,type:class extends FormApplication{constructor(){super({})}static get defaultOptions(){return foundry.utils.mergeObject(super.defaultOptions,{title:`Wonderlost: ${s}`,id:`${s}-settings`,width:550,height:"auto",popOut:!0,closeOnSubmit:!0,template:`modules/wonderlost/submodules/${t}/settings.hbs`})}static get moduleName(){return s}getData(){return foundry.utils.isEmpty(game.settings?.get(s,`${s.toLowerCase()}-allSettings`))?game.settings?.get(s,`${s.toLowerCase()}-allSettings`):e.data}async _updateObject(e,t){await(game.settings?.set(s,`${s.toLowerCase()}-allSettings`,t))}}})}initializeSocketListeners(){return 0===this.socketFns.size||this.socketFns.forEach(((e,t)=>{this.DEBUG&&u.info(`Registering socket listener for event: ${t}`),game.socket?.on(t,(t=>e(t)))})),this}initialize(){return this.initializeSettings().initializeHooks().initializeSocketListeners(),this.ready=!0,this}static expandObject(e){if("object"==typeof e&&null!==e)return Object.entries(e).reduce(((e,[t,s])=>{if("string"==typeof s)try{e[t]=JSON.parse(s)}catch(n){e[t]=s}else e[t]=s;return e}),{});throw new Error("Expected object but received "+typeof e)}static kabob(e){return e?e.split("").join("-"):""}}class w extends y{maxMessagesOnScreen=5;alwaysShowNotifications=!0;fadeOutDelay=3e3;menu=null;constructor(e=!1){super({moduleName:"Toasted",moduleDescription:"A customizable toast notification system",hooks:new Map([["renderChatLog",async(e,t)=>{try{if(document.body.classList.contains("stream"))return;const e=new f(t[0].querySelector("#chat-log").cloneNode(!1)).addClass(this.moduleName).id(this.lowercaseName).on("click",(e=>this.handleMouseEvent(e))).on("contextmenu",(e=>this.handleMouseEvent(e)));document.querySelector("body")?.appendChild(e.element),this.DEBUG&&u.success(`${this.moduleName} | Chat log rendered`)}catch(e){}}],["renderChatMessage",async(e,t,s)=>{this.addMessage(t[0].cloneNode(!0))}]]),socketFns:new Map([["module.toasted",e=>{this.alwaysShowNotifications?ui.notifications?.info(e):u.info(e)}]]),DEBUG:e}),this.registerSettings([{name:"Toast Duration",hint:"How long would you like a message to stay on screen?",type:Number,defaultValue:this.fadeOutDelay,range:{min:1e3,max:1e4,step:250},scope:"client",restricted:!1,onChange:e=>{this.fadeOutDelay=Number(e)}},{name:"Max Messages",hint:"How many messages would you like to see on screen (at most)?",type:Number,defaultValue:this.maxMessagesOnScreen,range:{min:1,max:10,step:1},scope:"client",restricted:!1,onChange:e=>{this.maxMessagesOnScreen=Number(e)}},{name:"Always Show Notifications",hint:"Would you prefer toast are shown even if the chat panel is open?",type:Boolean,defaultValue:this.alwaysShowNotifications,scope:"client",restricted:!1,onChange:e=>{this.alwaysShowNotifications=Boolean(e)}}])}static expandSidebarInstant(e){if(!e)throw new Error("[Toasted:expandSidebarInstant] -> Error: Sidebar element was not passed");const t=new f(e).removeClass("collapsed").unset(["width","height"]);ui.sidebar._collapsed=!1;const s=t.element.querySelector("#sidebar-tabs a.collapse i");if(!s)throw new Error("[Toasted:expandSidebarInstant] -> Error: Icon element was not found");new f(s).removeClass("fa-caret-left").addClass("fa-caret-right"),Hooks.callAll("sidebarCollapse",ui.sidebar,ui.sidebar._collapsed)}static findTarget(e,t,s){const n=e.getBoundingClientRect(),o=document.querySelector(`.${this.name}`).getBoundingClientRect();let i=t.clientX-o.left+n.left,r=t.clientY-o.top+n.top,a=document.elementFromPoint(i,r),l=a?.closest(".message"),h=new f(l).data("messageId");if(a&&h===s)return{target:a,x:i,y:r};const c=t.target.getBoundingClientRect(),m=Math.min(c.width/10,5),u=Math.min(c.height/10,5);for(let e=c.top+1;e=this.maxMessagesOnScreen&&s.element.firstElementChild?.remove(),s.child(t,"append"),e.from(t,.3,{height:0,onComplete:()=>{t.style.height="",this.DEBUG&&u.success(`${this.moduleName} | Toasted message ${n}`),setTimeout((()=>{this.removeMessage(t)}),this.fadeOutDelay)}})}removeMessage(t,{time:s=.3,delay:n=this.fadeOutDelay}={}){this.fadeOutDelay<0||e.to(t,s,{opacity:0,height:0,delay:n,onComplete:()=>{t.remove()}})}updateMessage(e,t){t.parentNode?.replaceChild(e,t),this.removeMessage(e)}}class b extends y{constructor(e=!1){super({moduleName:"Narrator",moduleDescription:"An extremely customizable on screen narrator system",hooks:new Map([]),socketFns:new Map([]),DEBUG:e})}}class E{DEBUG;tomes=new Map([["Toasted",w],["Narrator",b]]);constructor(e=!1){this.DEBUG=e,u.info("Wonderlost | Initializing"),this.initializeTomes()}initializeTomes(){this.tomes.forEach(((e,t)=>{new e(this.DEBUG).initialize(),this.DEBUG&&u.info(`Wonderlost | Initialized ${t}`)}))}}Hooks.once("init",(async function(){u.start("Wonderlost | Initialized"),new E(!0),u.success("Wonderlost | Ready")})),Hooks.once("ready",(async function(){})); +import{TweenMax as t}from"../../../scripts/greensock/esm/all.js";const e={silent:Number.NEGATIVE_INFINITY,fatal:0,error:0,warn:1,log:2,info:3,success:3,fail:3,ready:3,start:3,box:3,debug:4,trace:5,verbose:Number.POSITIVE_INFINITY},s={silent:{level:-1},fatal:{level:e.fatal},error:{level:e.error},warn:{level:e.warn},log:{level:e.log},info:{level:e.info},success:{level:e.success},fail:{level:e.fail},ready:{level:e.info},start:{level:e.info},box:{level:e.info},debug:{level:e.debug},trace:{level:e.trace},verbose:{level:e.verbose}};function n(t){return null!==t&&"object"==typeof t}function i(t,e,s=".",o){if(!n(e))return i(t,{},s);const r=Object.assign({},e);for(const e in t){if("__proto__"===e||"constructor"===e)continue;const o=t[e];null!=o&&(Array.isArray(o)&&Array.isArray(r[e])?r[e]=[...o,...r[e]]:n(o)&&n(r[e])?r[e]=i(o,r[e],(s?`${s}.`:"")+e.toString()):r[e]=o)}return r}const o=(...t)=>t.reduce(((t,e)=>i(t,e,"")),{});function r(t){return e=t,"[object Object]"===Object.prototype.toString.call(e)&&(!(!t.message&&!t.args)&&!t.stack);var e}let a=!1;const l=[];class h{constructor(t={}){const e=t.types||s;this.options=o({...t,defaults:{...t.defaults},level:c(t.level,e),reporters:[...t.reporters||[]]},{types:s,throttle:1e3,throttleMin:5,formatOptions:{date:!0,colors:!1,compact:!0}});for(const t in e){const s={type:t,...this.options.defaults,...e[t]};this[t]=this._wrapLogFn(s),this[t].raw=this._wrapLogFn(s,!0)}this.options.mockFn&&this.mockTypes(),this._lastLog={}}get level(){return this.options.level}set level(t){this.options.level=c(t,this.options.types,this.options.level)}prompt(t,e){if(!this.options.prompt)throw new Error("prompt is not supported!");return this.options.prompt(t,e)}create(t){const e=new h({...this.options,...t});return this._mockFn&&e.mockTypes(this._mockFn),e}withDefaults(t){return this.create({...this.options,defaults:{...this.options.defaults,...t}})}withTag(t){return this.withDefaults({tag:this.options.defaults.tag?this.options.defaults.tag+":"+t:t})}addReporter(t){return this.options.reporters.push(t),this}removeReporter(t){if(t){const e=this.options.reporters.indexOf(t);if(e>=0)return this.options.reporters.splice(e,1)}else this.options.reporters.splice(0);return this}setReporters(t){return this.options.reporters=Array.isArray(t)?t:[t],this}wrapAll(){this.wrapConsole(),this.wrapStd()}restoreAll(){this.restoreConsole(),this.restoreStd()}wrapConsole(){for(const t in this.options.types)console["__"+t]||(console["__"+t]=console[t]),console[t]=this[t].raw}restoreConsole(){for(const t in this.options.types)console["__"+t]&&(console[t]=console["__"+t],delete console["__"+t])}wrapStd(){this._wrapStream(this.options.stdout,"log"),this._wrapStream(this.options.stderr,"log")}_wrapStream(t,e){t&&(t.__write||(t.__write=t.write),t.write=t=>{this[e].raw(String(t).trim())})}restoreStd(){this._restoreStream(this.options.stdout),this._restoreStream(this.options.stderr)}_restoreStream(t){t&&t.__write&&(t.write=t.__write,delete t.__write)}pauseLogs(){a=!0}resumeLogs(){a=!1;const t=l.splice(0);for(const e of t)e[0]._logFn(e[1],e[2])}mockTypes(t){const e=t||this.options.mockFn;if(this._mockFn=e,"function"==typeof e)for(const t in this.options.types)this[t]=e(t,this.options.types[t])||this[t],this[t].raw=this[t]}_wrapLogFn(t,e){return(...s)=>{if(!a)return this._logFn(t,s,e);l.push([this,t,s,e])}}_logFn(t,e,s){if((t.level||0)>this.level)return!1;const n={date:new Date,args:[],...t,level:c(t.level,this.options.types)};!s&&1===e.length&&r(e[0])?Object.assign(n,e[0]):n.args=[...e],n.message&&(n.args.unshift(n.message),delete n.message),n.additional&&(Array.isArray(n.additional)||(n.additional=n.additional.split("\n")),n.args.push("\n"+n.additional.join("\n")),delete n.additional),n.type="string"==typeof n.type?n.type.toLowerCase():"log",n.tag="string"==typeof n.tag?n.tag:"";const i=(t=!1)=>{const e=(this._lastLog.count||0)-this.options.throttleMin;if(this._lastLog.object&&e>0){const t=[...this._lastLog.object.args];e>1&&t.push(`(repeated ${e} times)`),this._log({...this._lastLog.object,args:t}),this._lastLog.count=1}t&&(this._lastLog.object=n,this._log(n))};clearTimeout(this._lastLog.timeout);const o=this._lastLog.time&&n.date?n.date.getTime()-this._lastLog.time.getTime():0;if(this._lastLog.time=n.date,othis.options.throttleMin))return void(this._lastLog.timeout=setTimeout(i,this.options.throttle))}catch{}i(!0)}_log(t){for(const e of this.options.reporters)e.log(t,{options:this.options})}}function c(t,e={},s=3){return void 0===t?s:"number"==typeof t?t:e[t]&&void 0!==e[t].level?e[t].level:s}h.prototype.add=h.prototype.addReporter,h.prototype.remove=h.prototype.removeReporter,h.prototype.clear=h.prototype.removeReporter,h.prototype.withScope=h.prototype.withTag,h.prototype.mock=h.prototype.mockTypes,h.prototype.pause=h.prototype.pauseLogs,h.prototype.resume=h.prototype.resumeLogs;class m{constructor(t){this.options={...t},this.defaultColor="#7f8c8d",this.levelColorMap={0:"#c0392b",1:"#f39c12",3:"#00BCD4"},this.typeColorMap={success:"#2ecc71"}}_getLogFn(t){return t<1?console.__error||console.error:1===t?console.__warn||console.warn:console.__log||console.log}log(t){const e=this._getLogFn(t.level),s="log"===t.type?"":t.type,n=t.tag||"",i=`\n background: ${this.typeColorMap[t.type]||this.levelColorMap[t.level]||this.defaultColor};\n border-radius: 0.5em;\n color: white;\n font-weight: bold;\n padding: 2px 0.5em;\n `,o=`%c${[n,s].filter(Boolean).join(":")}`;"string"==typeof t.args[0]?e(`${o}%c ${t.args[0]}`,i,"",...t.args.slice(1)):e(o,i,...t.args)}}const d=function(t={}){return function(t={}){return new h(t)}({reporters:t.reporters||[new m({})],prompt:(t,e={})=>"confirm"===e.type?Promise.resolve(confirm(t)):Promise.resolve(prompt(t)),...t})}();var u,g=Object.defineProperty,p=(t,e,s)=>(((t,e,s)=>{e in t?g(t,e,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[e]=s})(t,"symbol"!=typeof e?e+"":e,s),s);function f(t){return t instanceof HTMLElement}class y{constructor(t){if(p(this,"element"),p(this,"debug",!1),f(t))return void(this.element=t);if("function"==typeof t){const e=t();if(!e)throw new Error("Function must return an element");if(this.debug&&console.log("Function returned",e),f(e))return void(this.element=e);if("string"==typeof e){const s=document.querySelector(e);if(!s)throw new Error(`You tried to grab using '${t}' but that doesn't exist!`);return void(this.element=s)}}const e=document.querySelector(t);if(!e)throw new Error(`You tried to grab using '${t}' but that doesn't exist!`);this.element=e}self(){return this.element}toggleClass(t){return"string"==typeof t&&t.includes(" ")&&(t=t.split(" ")),Array.isArray(t)||(t=[t]),t.forEach((t=>this.element.classList.toggle(t))),this}addClass(t){return"function"==typeof t&&(t=t()),"string"==typeof t&&t.includes(" ")&&(t=t.split(" ")),Array.isArray(t)||(t=[t]),t.forEach((t=>this.element.classList.add(t))),this}removeClass(t){return"function"==typeof t&&(t=t()),"string"==typeof t&&t.includes(" ")&&(t=t.split(" ")),Array.isArray(t)||(t=[t]),t.forEach((t=>this.element.classList.remove(t))),this}hasClass(t){return this.element.classList.contains(t)}replaceWith(t){return this.element.outerHTML=t,this}replaceWithElement(t,e=void 0){const s=document.createElement(t);if(s.id=e??this.element.id,!this.element?.parentNode)throw new Error("Element has no parent node, can not replace");return this.element.parentNode.replaceChild(s,this.element),new y(`#${s.id}`)}html(t){return this.element.innerHTML=t,this}empty(){return this.element.innerHTML="",this}check(t){if(this.element instanceof HTMLInputElement)return this.element.checked=t,this;throw new TypeError(`[El::${this.element.id}] You can only use check() on input elements'`)}checked(){if(this.element instanceof HTMLInputElement)return this.element.checked;throw new TypeError(`[El::${this.element.id}] You can only use checked() on input elements'`)}click(){return this.element.dispatchEvent(new MouseEvent("click",{view:window,bubbles:!0,cancelable:!1})),this}if(t){return t?this:null}wrap(t){const e=document.createElement("div");if(e.className=t,!this.element?.parentNode)throw new Error("Element has no parent node, can not wrap");return this.element.parentNode.insertBefore(e,this.element),this.element.parentNode.removeChild(this.element),e.appendChild(this.element),this}src(t){if(!(this.element instanceof HTMLImageElement))throw new TypeError(`[El::${this.element.id}] You can only use src() on image elements'`);return this.element.src=t,this}alt(t){if(!(this.element instanceof HTMLImageElement))throw new TypeError(`[El::${this.element.id}] You can only use alt() on image elements'`);return this.element.alt=t,this}parent(){const t=this.element.parentElement;if(!t)throw new Error("Element has no parent node, can not get parent");return t.id||(t.id=`parent-${this.element.id}`),new y(`#${t?.id}`)}remove(){if(!this.element?.parentNode)throw new Error("Element has no parent node, can not remove");return this.element.parentNode.removeChild(this.element),this}clear(){return this.element.innerHTML="",this}unset(t){return"string"==typeof t&&(t=[t]),t.forEach((t=>{this.element.removeAttribute(t)})),this}set(t){return Object.entries(t).forEach((([t,e])=>{e&&this.element.setAttribute(t,"string"==typeof e?e:e.toString())})),this}firstChild(){return this.element.firstElementChild}child(t,e=null){return"string"==typeof t?e&&"append"!==e?this.element.insertAdjacentHTML("afterbegin",t):this.element.insertAdjacentHTML("beforeend",t):("append"!==e&&null!=e||this.element.append(t),"prepend"===e&&this.element.prepend(t)),this}children(){return this.element.childNodes}text(t){return t?(this.element.textContent=t.toString(),this):this}textContent(t){return t?(this.element.textContent=t,this):this.element.textContent}textChild(t){const e=document.createTextNode(t.toString());return this.element.appendChild(e),this}type(t){return"type"in this.element&&this.element.setAttribute("type",t),this}name(t){return"name"in this.element&&(this.element.name=t),this}input(t){return"name"in this.element&&(this.element.name=this.element.id),"type"in this.element&&this.element.setAttribute("type",t),this}htmlFor(t){return"htmlFor"in this.element&&this.element.setAttribute("for",t),this}id(t){return t?(this.element.id=t,this):this.element.id}val(t){if(this.element instanceof HTMLInputElement||this.element instanceof HTMLSelectElement||this.element instanceof HTMLTextAreaElement||this.element instanceof HTMLOptionElement||this.element instanceof HTMLProgressElement)return null==t?this.element.value:(this.element.value=t instanceof Date?`${t.getFullYear()}-${t.getMonth()+1}-${t.getDate()}`:"string"==typeof t?t:t.toString(),this);throw new TypeError(`[El::${this.element.id}] You can only use val() on input / select / text area / progress elements'`)}data(t){return this.element.getAttribute(`data-${t}`)}dataset(){return this.element.dataset}on(t,e,s){return this.element.addEventListener(t,e,s),this}once(t,e){return this.element.addEventListener(t,e,{once:!0}),this}now(t,e){return this.element.dispatchEvent(new CustomEvent(t,{detail:e})),this}off(t,e,s){return this.element.removeEventListener(t,e,s),this}trigger(t,e){return this.element.dispatchEvent(new CustomEvent(t,e)),this}triggerChange(){if(this.element instanceof HTMLSelectElement){const t=document.createEvent("HTMLEvents");return t.initEvent("change",!0,!0),this.element.dispatchEvent(t),this}throw new TypeError(`[El::${this.element.id}] You can only use triggerChange() on select elements'`)}find(t){return this.element.querySelectorAll(t)}dispatchEvent(t){return this.element.dispatchEvent(new Event(t)),this}nestFrom(t){return t(`#${this.element.id}`),this}}class w{moduleName;moduleDescription;settings=[];hooks=new Map([]);socketFns=new Map;DEBUG=!1;ready=!1;get name(){return this.moduleName}get lowercaseName(){return this.moduleName.toLowerCase()}get hasHooks(){return this.hooks.size>0}get hasSettings(){return this.settings.length>0}get hasSocketFns(){return this.socketFns.size>0}get needsEarlyInitialization(){return this.hasSettings||this.hasHooks&&this.hooks.has("init")||this.hasHooks&&this.hooks.has("ready")||this.hasSocketFns}constructor(t){this.moduleName=t.moduleName,this.moduleDescription=t.moduleDescription,t?.settings&&(this.settings=t.settings.globalSettings?.map((t=>(t.scope="world",t)))??[],this.settings.push(...t.settings.clientSettings?.map((t=>(t.scope="client",t)))??[])),this.hooks=t?.hooks??new Map,this.socketFns=t?.socketFns??new Map,this.DEBUG=t?.DEBUG??!1}addHook(t,e,s=!1){!this.hooks.has(t)||s?this.hooks.set(t,e):d.warn(`Hook for event "${t}" already exists.`)}initializeHooks(){return this.hooks.forEach(((t,e)=>{this.DEBUG&&d.box({title:`[TOME::${this.moduleName}] => Registering hook for ${e}`,additional:{callback:t.toString()}}),Hooks.on(e,t)})),this}registerSetting(t){switch(t.type){case Number:case Boolean:case String:case Object:case Array:case Color:this.settings.push({...t});break;default:throw new Error(`Unsupported rule type: ${t.type}`)}return this}registerSettings(t){return t.forEach((t=>{this.registerSetting(t)})),this}initializeSettings(){return this.settings.forEach((t=>{this.DEBUG&&d.box({title:`[TOME::${this.moduleName}] => Registering ${t.name}`,additional:{...t}}),game.settings?.register("wonderlost",w.kabob(`${this.lowercaseName}-${t.name}`),{name:t.name,hint:t.hint,scope:t.scope,config:!0,default:t?.defaultValue,type:t.type,choices:t?.choices,range:t?.range,onChange:t.onChange,requiresReload:t.requiresReload})})),this}getSetting(t){return game.settings?.get("wonderlost",w.kabob(`${this.lowercaseName}-${t}`))}async setSetting(t,e){return game.settings?.set("wonderlost",w.kabob(`${this.lowercaseName}-${t}`),e)}registerSettingSubmenu(t){game.settings?.register("wonderlost",w.kabob(`${this.lowercaseName}-allSettings`),{scope:"world",config:!1,type:Object,default:t.data});const e=`${this.lowercaseName}`,s=this.moduleName.toString();game.settings?.registerMenu("wonderlost",w.kabob(`${this.lowercaseName}-allSettings`),{name:t.name,label:t.label,hint:t.hint,icon:t.icon,restricted:t.restricted,type:class extends FormApplication{constructor(){super({})}static get defaultOptions(){return foundry.utils.mergeObject(super.defaultOptions,{title:`Wonderlost: ${s}`,id:`${s}-settings`,width:550,height:"auto",popOut:!0,closeOnSubmit:!0,template:`modules/wonderlost/submodules/${e}/settings.hbs`})}static get moduleName(){return s}getData(){return foundry.utils.isEmpty(game.settings?.get(s,`${s.toLowerCase()}-allSettings`))?game.settings?.get(s,`${s.toLowerCase()}-allSettings`):t.data}async _updateObject(t,e){await(game.settings?.set(s,`${s.toLowerCase()}-allSettings`,e))}}})}initializeSocketListeners(){return 0===this.socketFns.size||this.socketFns.forEach(((t,e)=>{this.DEBUG&&d.info(`Registering socket listener for event: ${e}`),game.socket?.on(e,(e=>t(e)))})),this}initialize(){return this.hasSettings&&this.initializeSettings(),this.hasHooks&&this.initializeHooks(),this.hasSocketFns&&this.initializeSocketListeners(),this.ready=!0,this}static expandObject(t){if("object"==typeof t&&null!==t)return Object.entries(t).reduce(((t,[e,s])=>{if("string"==typeof s)try{t[e]=JSON.parse(s)}catch(n){t[e]=s}else t[e]=s;return t}),{});throw new Error("Expected object but received "+typeof t)}static kabob(t){return t?t.split("").join("-"):""}}class _ extends w{maxMessagesOnScreen=5;alwaysShowNotifications=!0;fadeOutDelay=3e3;menu=null;constructor(t=!1){super({moduleName:"Toasted",moduleDescription:"A customizable toast notification system",hooks:new Map([["renderChatLog",async(t,e)=>{try{if(document.body.classList.contains("stream"))return;const t=new y(e[0].querySelector("#chat-log").cloneNode(!1)).addClass(this.moduleName).id(this.lowercaseName).on("click",(t=>this.handleMouseEvent(t))).on("contextmenu",(t=>this.handleMouseEvent(t)));document.querySelector("body")?.appendChild(t.element),this.DEBUG&&d.success(`${this.moduleName} | Chat log rendered`)}catch(t){}}],["renderChatMessage",async(t,e,s)=>{this.addMessage(e[0].cloneNode(!0))}]]),socketFns:new Map([["module.toasted",t=>{this.alwaysShowNotifications?ui.notifications?.info(t):d.info(t)}]]),DEBUG:t}),this.registerSettings([{name:"Toast Duration",hint:"How long would you like a message to stay on screen?",type:Number,defaultValue:this.fadeOutDelay,range:{min:1e3,max:1e4,step:250},scope:"client",restricted:!1,onChange:t=>{this.fadeOutDelay=Number(t)}},{name:"Max Messages",hint:"How many messages would you like to see on screen (at most)?",type:Number,defaultValue:this.maxMessagesOnScreen,range:{min:1,max:10,step:1},scope:"client",restricted:!1,onChange:t=>{this.maxMessagesOnScreen=Number(t)}},{name:"Always Show Notifications",hint:"Would you prefer toast are shown even if the chat panel is open?",type:Boolean,defaultValue:this.alwaysShowNotifications,scope:"client",restricted:!1,onChange:t=>{this.alwaysShowNotifications=Boolean(t)}}])}static expandSidebarInstant(t){if(!t)throw new Error("[Toasted:expandSidebarInstant] -> Error: Sidebar element was not passed");const e=new y(t).removeClass("collapsed").unset(["width","height"]);ui.sidebar._collapsed=!1;const s=e.element.querySelector("#sidebar-tabs a.collapse i");if(!s)throw new Error("[Toasted:expandSidebarInstant] -> Error: Icon element was not found");new y(s).removeClass("fa-caret-left").addClass("fa-caret-right"),Hooks.callAll("sidebarCollapse",ui.sidebar,ui.sidebar._collapsed)}static findTarget(t,e,s){const n=t.getBoundingClientRect(),i=document.querySelector(`.${this.name}`).getBoundingClientRect();let o=e.clientX-i.left+n.left,r=e.clientY-i.top+n.top,a=document.elementFromPoint(o,r),l=a?.closest(".message"),h=new y(l).data("messageId");if(a&&h===s)return{target:a,x:o,y:r};const c=e.target.getBoundingClientRect(),m=Math.min(c.width/10,5),d=Math.min(c.height/10,5);for(let t=c.top+1;t=this.maxMessagesOnScreen&&s.element.firstElementChild?.remove(),s.child(e,"append"),t.from(e,.3,{height:0,onComplete:()=>{e.style.height="",this.DEBUG&&d.success(`${this.moduleName} | Toasted message ${n}`),setTimeout((()=>{this.removeMessage(e)}),this.fadeOutDelay)}})}removeMessage(e,{time:s=.3,delay:n=this.fadeOutDelay}={}){this.fadeOutDelay<0||t.to(e,s,{opacity:0,height:0,delay:n,onComplete:()=>{e.remove()}})}updateMessage(t,e){e.parentNode?.replaceChild(t,e),this.removeMessage(t)}}class v{fonts_;uris_;constructor(t){this.fonts_=[],this.uris_=t.urls||[],this.parseFamilyConfig_(t.families)}getUris(){return this.uris_||[]}getFonts(){return this.fonts_}getParsedFonts(){return[]}parseFamilyConfig_(t){t.forEach((t=>{if("string"!=typeof t)this.fonts_.push({family:t.name,variation:"n4"}),this.uris_?.push(t.url);else{const e=t.split(":"),s=e[0];let n=e[1]?.split(",");(!n||n.length<1)&&(n=["n4"]),n.forEach((t=>{this.fonts_.push({family:s,variation:t})}))}}))}}class E{css_;rules_=[];constructor(t){this.css_=t}getParsedFonts(){return this.rules_}parseCSS(){this.css_=this.removeNewLines_(this.css_);const t=this.css_.split("}");t.pop(),t.forEach((t=>{const e=t.split("{"),s=this.parseCSSBlock_(e[1]);this.rules_.push({fontFamily:s["font-family"],fontStyle:s["font-style"],fontWeight:s["font-weight"],src:s.src,unicodeRange:s["font-range"]})}))}parseCSSBlock_(t){const e={},s=t.split(";");return s.pop(),s.forEach((t=>{const s=t.indexOf(":"),n=t.substring(0,s).trim();let i=t.substring(s+1).trim();"'"===i[0]&&"'"===i[i.length-1]&&(i=i.replace(/'/g,"")),""!=n&&""!=i&&(e[n]=i)})),e}removeNewLines_(t){return t.replace(/\n/g,"")}}class b{fontFamilies;parsedFonts;fontTestStrings;INT_FONTS={latin:"BESbswy","latin-ext":"çöüğş",cyrillic:"йяЖ",greek:"αβΣ",khmer:"កខគ",Hanuman:"កខគ"};WEIGHTS={thin:"1",extralight:"2","extra-light":"2",ultralight:"2","ultra-light":"2",light:"3",regular:"4",book:"4",medium:"5","semi-bold":"6",semibold:"6","demi-bold":"6",demibold:"6",bold:"7","extra-bold":"8",extrabold:"8","ultra-bold":"8",ultrabold:"8",black:"9",heavy:"9",l:"3",r:"4",b:"7"};STYLES={i:"i",italic:"i",n:"n",normal:"n"};VARIATION_MATCH=new RegExp("^(thin|(?:(?:extra|ultra)-?)?light|regular|book|medium|(?:(?:semi|demi|extra|ultra)-?)?bold|black|heavy|l|r|b|[1-9]00)?(n|i|normal|italic)?$");constructor(t){this.fontFamilies=t,this.parsedFonts=[],this.fontTestStrings={}}parse(){for(const t of this.fontFamilies){const e=t.split(":"),s=e[0].replace(/\+/g," ");let n=["n4"];if(e.length>=2){const t=this.parseVariations(e[1]);if(t.length>0&&(n=t),3===e.length){const t=this.parseSubsets(e[2]);if(t.length>0){const e=this.INT_FONTS[t[0]];e&&(this.fontTestStrings[s]=e)}}}if(!this.fontTestStrings[s]){const t=this.INT_FONTS[s];t&&(this.fontTestStrings[s]=t)}for(const t of n)this.parsedFonts.push({family:s,variation:t})}}generateFontVariationDescription(t){if(!t.match(/^[\w-]+$/))return"";const e=t.toLowerCase(),s=this.VARIATION_MATCH.exec(e);if(null==s)return"";return[this.normalizeStyle(s[2]),this.normalizeWeight(s[1])].join("")}normalizeStyle(t){return null==t||""==t?"n":this.STYLES[t]}normalizeWeight(t){if(null==t||""==t)return"4";if("string"==typeof t){const e=this.WEIGHTS[t];if(e)return e}return"number"==typeof t&&isNaN(t)?"4":t.toString().substr(0,1)}parseVariations(t){const e=[];if(!t)return e;const s=t.split(","),n=s.length;for(let t=0;t`${t.family}:${t.variation}`.replace(/\s/g,"+"))).join("|");return`${this.apiUrl_}?family=${e}`}}class C{fonts_;uri_;constructor(t){this.fonts_=t,this.generateUri_()}getUris(){return this.uri_?[this.uri_]:[]}getFonts(){const t=new b(this.fonts_.families);return t.parse(),t.getFonts()}async getParsedFonts(){if(!this.uri_)throw new Error("No uri provided. Nothing to parse.");const t=await fetch(this.uri_).then((t=>t.text())),e=new E(t);return e.parseCSS(),e.getParsedFonts()}generateUri_(){const t=new T(this.fonts_.families);this.uri_=t.buildUri()}}!function(t){t.LOADING="loading",t.ACTIVE="active",t.INACTIVE="inactive",t.FONT_LOADING="fontloading",t.FONT_ACTIVE="fontactive",t.FONT_INACTIVE="fontinactive"}(u||(u={}));class S{namespace_="wf";classSeparator_="-";event_;config_;htmlElement_;constructor(t){this.config_=t,this.event_=document.createEvent("CustomEvent"),this.htmlElement_=document.documentElement,document.addEventListener(u.LOADING,(()=>{this.handleLoading_()}),!1),document.addEventListener(u.ACTIVE,(()=>{this.handleActive_()}),!1),document.addEventListener(u.INACTIVE,(()=>{this.handleInactive_()}),!1),document.addEventListener(u.FONT_LOADING,(t=>{const{detail:e}=t;this.handleFontLoading_(e)}),!1),document.addEventListener(u.FONT_ACTIVE,(t=>{const{detail:e}=t;this.handleFontActive_(e)}),!1),document.addEventListener(u.FONT_INACTIVE,(t=>{const{detail:e}=t;this.handleFontInactive_(e)}),!1)}handleLoading_(){this.config_.events&&this.config_.loading&&(this.config_.loading.call(null),this.addClassToHtml_(u.LOADING),this.removeClassFromHtml_(u.ACTIVE),this.removeClassFromHtml_(u.INACTIVE))}handleActive_(){this.config_.events&&this.config_.active&&(this.config_.active.call(null),this.removeClassFromHtml_(u.LOADING),this.addClassToHtml_(u.ACTIVE),this.removeClassFromHtml_(u.INACTIVE))}handleInactive_(){this.config_.events&&this.config_.inactive&&(this.config_.inactive.call(null),this.removeClassFromHtml_(u.LOADING),this.removeClassFromHtml_(u.ACTIVE),this.addClassToHtml_(u.INACTIVE))}handleFontLoading_(t){if(this.config_.events&&this.config_.fontloading){const e=t.split(":");this.config_.fontloading.call(null,e[0],e[1]),this.addClassToHtml_(u.LOADING,[e[0],e[1]]),this.removeClassFromHtml_(u.ACTIVE,[e[0],e[1]]),this.removeClassFromHtml_(u.INACTIVE,[e[0],e[1]])}}handleFontActive_(t){if(this.config_.events&&this.config_.fontactive){const e=t.split(":");this.config_.fontactive.call(null,e[0],e[1]),this.removeClassFromHtml_(u.LOADING,[e[0],e[1]]),this.addClassToHtml_(u.ACTIVE,[e[0],e[1]]),this.removeClassFromHtml_(u.INACTIVE,[e[0],e[1]])}}handleFontInactive_(t){if(this.config_.events&&this.config_.fontinactive){const e=t.split(":");this.config_.fontinactive.call(null,e[0],e[1]),this.removeClassFromHtml_(u.LOADING,[e[0],e[1]]),this.removeClassFromHtml_(u.ACTIVE,[e[0],e[1]]),this.addClassToHtml_(u.INACTIVE,[e[0],e[1]])}}addClassToHtml_(t,e=[]){this.htmlElement_.classList.add([this.namespace_].concat(e.map(this.sanitizeClassName_),t).join(this.classSeparator_))}removeClassFromHtml_(t,e=[]){this.htmlElement_.classList.remove([this.namespace_].concat(e.map(this.sanitizeClassName_),t).join(this.classSeparator_))}sanitizeClassName_(t){return t.replace(/[\W_]+/g,"").toLowerCase()}}class F{font_;load_;constructor(t,e){this.font_=t,this.load_=e,this.loading_()}loading_(){document.dispatchEvent(new CustomEvent(u.FONT_LOADING,{detail:`${this.font_.family}:${this.font_.variation}`}))}getFont(){return this.font_}watch(){return document.fonts.check(`16px ${this.font_.family}`,"BESbswy")}}class N{fontWatchers_=[];loadedFonts_=[];watched_=!1;add(t,e){this.fontWatchers_.push(new F(t,e))}fontLoaded(t){this.loadedFonts_.push(t)}watchFonts(){if(!this.watched_){this.watched_=!0;let t=!1;this.fontWatchers_.forEach((e=>{const s=e.getFont(),n=this.loadedFonts_.includes(s.family)||e.watch();n&&(t=!0),document.dispatchEvent(new CustomEvent(n?u.FONT_ACTIVE:u.FONT_INACTIVE,{detail:`${s.family}:${s.variation}`}))})),document.dispatchEvent(new CustomEvent(t?u.ACTIVE:u.INACTIVE,{}))}}}const L={events:!1,classes:!1,timeout:3e3},k=async t=>{const e={...L,...t},s=new N;if((e.classes||e.events)&&new S(e),e.google){const t=new C(e.google);"native"===e.google.load?await I(await t.getParsedFonts()):t.getUris().forEach(A),t.getFonts().forEach((t=>{s.add(t,e.google?.load||"link")}))}if(e.custom){if("native"===e.custom.load)throw new Error("Native load is not implemented for custom fonts.");const t=new v(e.custom);t.getUris().forEach(A),t.getFonts().forEach((t=>{s.add(t,"link")}))}(e.classes||e.events)&&(document.dispatchEvent(new CustomEvent(u.LOADING,{})),document.fonts.onloadingdone=t=>{t.fontfaces.forEach((async t=>{"loaded"===t.status&&s.fontLoaded(t.family)})),s.watchFonts()},setTimeout((()=>{s.watchFonts()}),e.timeout))},I=async t=>{for(const e of t){const t=new FontFace(e.fontFamily,e.src,{style:e.fontStyle,unicodeRange:e.unicodeRange,weight:e.fontWeight});await t.load(),document.fonts.add(t)}},A=t=>{const e=document.createElement("link");e.rel="stylesheet",e.href=t,e.media="all",document.head.appendChild(e)};class H extends w{static fonts=["Caslon","CaslonAntique","SignikaBold","Riffic","IronSans","LinLibertine","TimesNewRomance","TimesNewYorker","LPEducational","Cardinal","OldLondon","StoneHenge","SunnyDay","PaulSignature","LemonTuesday","FairProsper","BalletHarmony","MagieraScript","Cathallina","Hamish","DreamersBrush","FastInMyCar","ChildWriting","Kindergarten","FuturaHandwritten","Fewriter","TrashHand","GoodBrush","BaksoSapi","SuplexmentaryComic","ComicInk","DreamyLand","Yikes","GangOfThree","JianGkrik","Yozakura","Hiroshio","ArabDances","Rooters","Subway","Himagsikan","MilTown","Galactico","Oko","Ethnocentric","VenusRising","StampAct","Kirsty","Western","BreakAway","YoungerThanMe","Underground","VarsityTeam","Valentino","GlassHouses","Makayla","DancingVampyrish","Codex","DSNetStamped","HappyFrushZero","Shoplifter","Stereofidelic","Headache","HorrorHouse","GhostTheory2","Syemox","GhostChase"];static fontWeights=["100","200","300","400","500","600","700","800","900"];static fontStyles=["normal","italic","oblique"];get titleFont(){return this.getSetting("Title Font")??"GhostTheory2"}static get titleFont(){return game.settings?.get("wonderlost","narrator-title-font")??"GhostTheory2"}static set titleFont(t){game.settings?.set("wonderlost","narrator-title-font",t)}get textFont(){return this.getSetting("Text Font")??"GhostTheory2"}static get textFont(){return game.settings?.get("wonderlost","narrator-text-font")??"GhostTheory2"}static set textFont(t){game.settings?.set("wonderlost","narrator-text-font",t)}get titleWeight(){return this.getSetting("Title Weight")??"400"}static get titleWeight(){return game.settings?.get("wonderlost","narrator-title-weight")??"400"}static set titleWeight(t){game.settings?.set("wonderlost","narrator-title-weight",t)}constructor(t=!1){super({moduleName:"Narrator",moduleDescription:"An extremely customizable on screen narrator system",settings:{globalSettings:[{name:"Title Font",hint:"The font used for the title text",type:String,defaultValue:"GhostTheory2",choices:Object.fromEntries(H.fonts.map((t=>[t,t]))),onChange:t=>{H.titleFont=t}},{name:"Text Font",hint:"The font used for the text body",type:String,defaultValue:"GhostTheory2",choices:Object.fromEntries(H.fonts.map((t=>[t,t]))),onChange:t=>{H.textFont=t}},{name:"Title Weight",hint:"The weight of the title font",type:String,defaultValue:"400",choices:Object.fromEntries(H.fontWeights.map((t=>[t,t]))),onChange:t=>{H.titleWeight=t}}]},hooks:new Map([["ready",(t,e)=>{k({custom:{families:[H.titleFont,H.textFont]}});let s=[];for(let t=H.fonts.length-1;t>=0;--t)H.fonts[t]!==H.titleFont&&H.fonts[t]!==H.textFont&&s.push(H.fonts[t]);!async function(t){k({custom:{families:t}})}(s)}]]),socketFns:new Map([]),DEBUG:t})}}class x{DEBUG;tomes=new Map([["Toasted",new _],["Narrator",new H]]);constructor(t=!1){this.DEBUG=t,d.info("Wonderlost | Initialized",this)}initializeTomes(){for(const[t,e]of this.tomes)e.initialize(),this.DEBUG&&d.info(`Wonderlost | Initialized ${t}`,e)}}Hooks.once("init",(async function(){d.start("Wonderlost | Initialized"),new x(!0).initializeTomes(),d.success("Wonderlost | Ready")})),Hooks.once("ready",(async function(){})); //# sourceMappingURL=wonderlost.mjs.map diff --git a/dist/wonderlost.mjs.map b/dist/wonderlost.mjs.map index 675cf6f..6ed6775 100644 --- a/dist/wonderlost.mjs.map +++ b/dist/wonderlost.mjs.map @@ -1 +1 @@ -{"version":3,"file":"wonderlost.mjs","sources":["../node_modules/.pnpm/consola@3.2.3/node_modules/consola/dist/core.mjs","../node_modules/.pnpm/consola@3.2.3/node_modules/consola/dist/browser.mjs","../node_modules/.pnpm/@magik_io+mote@1.6.6/node_modules/@magik_io/mote/dist/El.mjs","../src/class/Tome.ts","../src/submodules/toasted/Toasted.ts","../src/submodules/narrator/Narrator.ts","../src/wonderlost.ts"],"sourcesContent":["const LogLevels = {\n silent: Number.NEGATIVE_INFINITY,\n fatal: 0,\n error: 0,\n warn: 1,\n log: 2,\n info: 3,\n success: 3,\n fail: 3,\n ready: 3,\n start: 3,\n box: 3,\n debug: 4,\n trace: 5,\n verbose: Number.POSITIVE_INFINITY\n};\nconst LogTypes = {\n // Silent\n silent: {\n level: -1\n },\n // Level 0\n fatal: {\n level: LogLevels.fatal\n },\n error: {\n level: LogLevels.error\n },\n // Level 1\n warn: {\n level: LogLevels.warn\n },\n // Level 2\n log: {\n level: LogLevels.log\n },\n // Level 3\n info: {\n level: LogLevels.info\n },\n success: {\n level: LogLevels.success\n },\n fail: {\n level: LogLevels.fail\n },\n ready: {\n level: LogLevels.info\n },\n start: {\n level: LogLevels.info\n },\n box: {\n level: LogLevels.info\n },\n // Level 4\n debug: {\n level: LogLevels.debug\n },\n // Level 5\n trace: {\n level: LogLevels.trace\n },\n // Verbose\n verbose: {\n level: LogLevels.verbose\n }\n};\n\nfunction isObject(value) {\n return value !== null && typeof value === \"object\";\n}\nfunction _defu(baseObject, defaults, namespace = \".\", merger) {\n if (!isObject(defaults)) {\n return _defu(baseObject, {}, namespace, merger);\n }\n const object = Object.assign({}, defaults);\n for (const key in baseObject) {\n if (key === \"__proto__\" || key === \"constructor\") {\n continue;\n }\n const value = baseObject[key];\n if (value === null || value === void 0) {\n continue;\n }\n if (merger && merger(object, key, value, namespace)) {\n continue;\n }\n if (Array.isArray(value) && Array.isArray(object[key])) {\n object[key] = [...value, ...object[key]];\n } else if (isObject(value) && isObject(object[key])) {\n object[key] = _defu(\n value,\n object[key],\n (namespace ? `${namespace}.` : \"\") + key.toString(),\n merger\n );\n } else {\n object[key] = value;\n }\n }\n return object;\n}\nfunction createDefu(merger) {\n return (...arguments_) => (\n // eslint-disable-next-line unicorn/no-array-reduce\n arguments_.reduce((p, c) => _defu(p, c, \"\", merger), {})\n );\n}\nconst defu = createDefu();\n\nfunction isPlainObject(obj) {\n return Object.prototype.toString.call(obj) === \"[object Object]\";\n}\nfunction isLogObj(arg) {\n if (!isPlainObject(arg)) {\n return false;\n }\n if (!arg.message && !arg.args) {\n return false;\n }\n if (arg.stack) {\n return false;\n }\n return true;\n}\n\nlet paused = false;\nconst queue = [];\nclass Consola {\n constructor(options = {}) {\n const types = options.types || LogTypes;\n this.options = defu(\n {\n ...options,\n defaults: { ...options.defaults },\n level: _normalizeLogLevel(options.level, types),\n reporters: [...options.reporters || []]\n },\n {\n types: LogTypes,\n throttle: 1e3,\n throttleMin: 5,\n formatOptions: {\n date: true,\n colors: false,\n compact: true\n }\n }\n );\n for (const type in types) {\n const defaults = {\n type,\n ...this.options.defaults,\n ...types[type]\n };\n this[type] = this._wrapLogFn(defaults);\n this[type].raw = this._wrapLogFn(\n defaults,\n true\n );\n }\n if (this.options.mockFn) {\n this.mockTypes();\n }\n this._lastLog = {};\n }\n get level() {\n return this.options.level;\n }\n set level(level) {\n this.options.level = _normalizeLogLevel(\n level,\n this.options.types,\n this.options.level\n );\n }\n prompt(message, opts) {\n if (!this.options.prompt) {\n throw new Error(\"prompt is not supported!\");\n }\n return this.options.prompt(message, opts);\n }\n create(options) {\n const instance = new Consola({\n ...this.options,\n ...options\n });\n if (this._mockFn) {\n instance.mockTypes(this._mockFn);\n }\n return instance;\n }\n withDefaults(defaults) {\n return this.create({\n ...this.options,\n defaults: {\n ...this.options.defaults,\n ...defaults\n }\n });\n }\n withTag(tag) {\n return this.withDefaults({\n tag: this.options.defaults.tag ? this.options.defaults.tag + \":\" + tag : tag\n });\n }\n addReporter(reporter) {\n this.options.reporters.push(reporter);\n return this;\n }\n removeReporter(reporter) {\n if (reporter) {\n const i = this.options.reporters.indexOf(reporter);\n if (i >= 0) {\n return this.options.reporters.splice(i, 1);\n }\n } else {\n this.options.reporters.splice(0);\n }\n return this;\n }\n setReporters(reporters) {\n this.options.reporters = Array.isArray(reporters) ? reporters : [reporters];\n return this;\n }\n wrapAll() {\n this.wrapConsole();\n this.wrapStd();\n }\n restoreAll() {\n this.restoreConsole();\n this.restoreStd();\n }\n wrapConsole() {\n for (const type in this.options.types) {\n if (!console[\"__\" + type]) {\n console[\"__\" + type] = console[type];\n }\n console[type] = this[type].raw;\n }\n }\n restoreConsole() {\n for (const type in this.options.types) {\n if (console[\"__\" + type]) {\n console[type] = console[\"__\" + type];\n delete console[\"__\" + type];\n }\n }\n }\n wrapStd() {\n this._wrapStream(this.options.stdout, \"log\");\n this._wrapStream(this.options.stderr, \"log\");\n }\n _wrapStream(stream, type) {\n if (!stream) {\n return;\n }\n if (!stream.__write) {\n stream.__write = stream.write;\n }\n stream.write = (data) => {\n this[type].raw(String(data).trim());\n };\n }\n restoreStd() {\n this._restoreStream(this.options.stdout);\n this._restoreStream(this.options.stderr);\n }\n _restoreStream(stream) {\n if (!stream) {\n return;\n }\n if (stream.__write) {\n stream.write = stream.__write;\n delete stream.__write;\n }\n }\n pauseLogs() {\n paused = true;\n }\n resumeLogs() {\n paused = false;\n const _queue = queue.splice(0);\n for (const item of _queue) {\n item[0]._logFn(item[1], item[2]);\n }\n }\n mockTypes(mockFn) {\n const _mockFn = mockFn || this.options.mockFn;\n this._mockFn = _mockFn;\n if (typeof _mockFn !== \"function\") {\n return;\n }\n for (const type in this.options.types) {\n this[type] = _mockFn(type, this.options.types[type]) || this[type];\n this[type].raw = this[type];\n }\n }\n _wrapLogFn(defaults, isRaw) {\n return (...args) => {\n if (paused) {\n queue.push([this, defaults, args, isRaw]);\n return;\n }\n return this._logFn(defaults, args, isRaw);\n };\n }\n _logFn(defaults, args, isRaw) {\n if ((defaults.level || 0) > this.level) {\n return false;\n }\n const logObj = {\n date: /* @__PURE__ */ new Date(),\n args: [],\n ...defaults,\n level: _normalizeLogLevel(defaults.level, this.options.types)\n };\n if (!isRaw && args.length === 1 && isLogObj(args[0])) {\n Object.assign(logObj, args[0]);\n } else {\n logObj.args = [...args];\n }\n if (logObj.message) {\n logObj.args.unshift(logObj.message);\n delete logObj.message;\n }\n if (logObj.additional) {\n if (!Array.isArray(logObj.additional)) {\n logObj.additional = logObj.additional.split(\"\\n\");\n }\n logObj.args.push(\"\\n\" + logObj.additional.join(\"\\n\"));\n delete logObj.additional;\n }\n logObj.type = typeof logObj.type === \"string\" ? logObj.type.toLowerCase() : \"log\";\n logObj.tag = typeof logObj.tag === \"string\" ? logObj.tag : \"\";\n const resolveLog = (newLog = false) => {\n const repeated = (this._lastLog.count || 0) - this.options.throttleMin;\n if (this._lastLog.object && repeated > 0) {\n const args2 = [...this._lastLog.object.args];\n if (repeated > 1) {\n args2.push(`(repeated ${repeated} times)`);\n }\n this._log({ ...this._lastLog.object, args: args2 });\n this._lastLog.count = 1;\n }\n if (newLog) {\n this._lastLog.object = logObj;\n this._log(logObj);\n }\n };\n clearTimeout(this._lastLog.timeout);\n const diffTime = this._lastLog.time && logObj.date ? logObj.date.getTime() - this._lastLog.time.getTime() : 0;\n this._lastLog.time = logObj.date;\n if (diffTime < this.options.throttle) {\n try {\n const serializedLog = JSON.stringify([\n logObj.type,\n logObj.tag,\n logObj.args\n ]);\n const isSameLog = this._lastLog.serialized === serializedLog;\n this._lastLog.serialized = serializedLog;\n if (isSameLog) {\n this._lastLog.count = (this._lastLog.count || 0) + 1;\n if (this._lastLog.count > this.options.throttleMin) {\n this._lastLog.timeout = setTimeout(\n resolveLog,\n this.options.throttle\n );\n return;\n }\n }\n } catch {\n }\n }\n resolveLog(true);\n }\n _log(logObj) {\n for (const reporter of this.options.reporters) {\n reporter.log(logObj, {\n options: this.options\n });\n }\n }\n}\nfunction _normalizeLogLevel(input, types = {}, defaultLevel = 3) {\n if (input === void 0) {\n return defaultLevel;\n }\n if (typeof input === \"number\") {\n return input;\n }\n if (types[input] && types[input].level !== void 0) {\n return types[input].level;\n }\n return defaultLevel;\n}\nConsola.prototype.add = Consola.prototype.addReporter;\nConsola.prototype.remove = Consola.prototype.removeReporter;\nConsola.prototype.clear = Consola.prototype.removeReporter;\nConsola.prototype.withScope = Consola.prototype.withTag;\nConsola.prototype.mock = Consola.prototype.mockTypes;\nConsola.prototype.pause = Consola.prototype.pauseLogs;\nConsola.prototype.resume = Consola.prototype.resumeLogs;\nfunction createConsola(options = {}) {\n return new Consola(options);\n}\n\nexport { Consola, LogLevels, LogTypes, createConsola };\n","import { createConsola as createConsola$1 } from './core.mjs';\nexport { Consola, LogLevels, LogTypes } from './core.mjs';\n\nclass BrowserReporter {\n constructor(options) {\n this.options = { ...options };\n this.defaultColor = \"#7f8c8d\";\n this.levelColorMap = {\n 0: \"#c0392b\",\n // Red\n 1: \"#f39c12\",\n // Yellow\n 3: \"#00BCD4\"\n // Cyan\n };\n this.typeColorMap = {\n success: \"#2ecc71\"\n // Green\n };\n }\n _getLogFn(level) {\n if (level < 1) {\n return console.__error || console.error;\n }\n if (level === 1) {\n return console.__warn || console.warn;\n }\n return console.__log || console.log;\n }\n log(logObj) {\n const consoleLogFn = this._getLogFn(logObj.level);\n const type = logObj.type === \"log\" ? \"\" : logObj.type;\n const tag = logObj.tag || \"\";\n const color = this.typeColorMap[logObj.type] || this.levelColorMap[logObj.level] || this.defaultColor;\n const style = `\n background: ${color};\n border-radius: 0.5em;\n color: white;\n font-weight: bold;\n padding: 2px 0.5em;\n `;\n const badge = `%c${[tag, type].filter(Boolean).join(\":\")}`;\n if (typeof logObj.args[0] === \"string\") {\n consoleLogFn(\n `${badge}%c ${logObj.args[0]}`,\n style,\n // Empty string as style resets to default console style\n \"\",\n ...logObj.args.slice(1)\n );\n } else {\n consoleLogFn(badge, style, ...logObj.args);\n }\n }\n}\n\nfunction createConsola(options = {}) {\n const consola2 = createConsola$1({\n reporters: options.reporters || [new BrowserReporter({})],\n prompt(message, options2 = {}) {\n if (options2.type === \"confirm\") {\n return Promise.resolve(confirm(message));\n }\n return Promise.resolve(prompt(message));\n },\n ...options\n });\n return consola2;\n}\nconst consola = createConsola();\n\nexport { consola, createConsola, consola as default };\n","var __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => {\n __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\n return value;\n};\nfunction isAElement(selector) {\n return selector instanceof HTMLElement;\n}\nclass El {\n /**\n * Create a new instance of El.\n * @param {selectorString} selector - The CSS selector for the HTML element.\n */\n constructor(selector) {\n __publicField(this, \"element\");\n __publicField(this, \"debug\", false);\n if (isAElement(selector)) {\n this.element = selector;\n return;\n }\n if (typeof selector === \"function\") {\n const t = selector();\n if (!t)\n throw new Error(\"Function must return an element\");\n if (this.debug)\n console.log(\"Function returned\", t);\n if (isAElement(t)) {\n this.element = t;\n return;\n }\n if (typeof t === \"string\") {\n const element2 = document.querySelector(t);\n if (!element2)\n throw new Error(`You tried to grab using '${selector}' but that doesn't exist!`);\n this.element = element2;\n return;\n }\n }\n const element = document.querySelector(selector);\n if (!element)\n throw new Error(`You tried to grab using '${selector}' but that doesn't exist!`);\n this.element = element;\n return;\n }\n /**\n * Get the current HTML element.\n * @returns {htmlElements} The current HTML element.\n */\n self() {\n return this.element;\n }\n /**\n * Toggle a class or classes on the current HTML element.\n * @param {string | Array} className - The class or classes to toggle.\n * @returns {this} The current instance for chaining.\n */\n toggleClass(className) {\n if (typeof className === \"string\" && className.includes(\" \"))\n className = className.split(\" \");\n if (!Array.isArray(className))\n className = [className];\n className.forEach((c) => this.element.classList.toggle(c));\n return this;\n }\n /**\n * Add a class or classes to the current HTML element.\n * @param {Array | string | (() => string) | (() => Array)} className - The class or classes to add.\n * @returns {this} The current instance for chaining.\n */\n addClass(className) {\n if (typeof className === \"function\")\n className = className();\n if (typeof className === \"string\" && className.includes(\" \"))\n className = className.split(\" \");\n if (!Array.isArray(className))\n className = [className];\n className.forEach((singleClass) => this.element.classList.add(singleClass));\n return this;\n }\n /**\n * Remove a class or classes from the current HTML element.\n * @param {Array | string | (() => string) | (() => Array)} className - The class or classes to remove.\n * @returns {this} The current instance for chaining.\n */\n removeClass(className) {\n if (typeof className === \"function\")\n className = className();\n if (typeof className === \"string\" && className.includes(\" \"))\n className = className.split(\" \");\n if (!Array.isArray(className))\n className = [className];\n className.forEach((singleClass) => this.element.classList.remove(singleClass));\n return this;\n }\n /**\n * Check if the current HTML element has a class.\n * @param {string} className - The class to check.\n * @returns {boolean} True if the element has the class, false otherwise.\n */\n hasClass(className) {\n return this.element.classList.contains(className);\n }\n /**\n * Replace the current HTML element with a string.\n * @param {string} string - The string to replace the element with.\n * @returns {this} The current instance for chaining.\n */\n replaceWith(string) {\n this.element.outerHTML = string;\n return this;\n }\n /**\n * Replace the current HTML element with a new element.\n * @template NewElement - The name of the new HTML element tag.\n * @param {NewElement} tagName - The tag name of the new element.\n * @param {string | undefined} idForNewElement - The id for the new element.\n * @returns {El} A new instance of El for the new element.\n */\n replaceWithElement(tagName, idForNewElement = void 0) {\n const newEl = document.createElement(tagName);\n newEl.id = idForNewElement ?? this.element.id;\n if (!this.element?.parentNode)\n throw new Error(\"Element has no parent node, can not replace\");\n this.element.parentNode.replaceChild(newEl, this.element);\n return new El(`#${newEl.id}`);\n }\n /**\n * Set the inner HTML of the current HTML element.\n * @param {string} string - The new inner HTML.\n * @returns {this} The current instance for chaining.\n */\n html(string) {\n this.element.innerHTML = string;\n return this;\n }\n /**\n * Empty the inner HTML of the current HTML element.\n * @returns {this} The current instance for chaining.\n */\n empty() {\n this.element.innerHTML = \"\";\n return this;\n }\n /**\n * Check or uncheck the current HTML element if it is an input element.\n * @param {boolean} trueOrFalse - Whether to check or uncheck the element.\n * @returns {this} The current instance for chaining.\n * @throws {TypeError} If the current HTML element is not an input element.\n */\n check(trueOrFalse) {\n if (this.element instanceof HTMLInputElement) {\n this.element.checked = trueOrFalse;\n return this;\n }\n throw new TypeError(`[El::${this.element.id}] You can only use check() on input elements'`);\n }\n /**\n * Get whether the current HTML element is checked if it is an input element.\n * @returns {boolean} Whether the element is checked.\n * @throws {TypeError} If the current HTML element is not an input element.\n */\n checked() {\n if (this.element instanceof HTMLInputElement)\n return this.element.checked;\n throw new TypeError(`[El::${this.element.id}] You can only use checked() on input elements'`);\n }\n /**\n * Dispatch a click event on the current HTML element.\n * @returns {this} The current instance for chaining.\n */\n click() {\n this.element.dispatchEvent(\n new MouseEvent(\"click\", { view: window, bubbles: true, cancelable: false })\n );\n return this;\n }\n /**\n * Return the current instance if the expression is true, otherwise return undefined, useful for chaining\n * @param {boolean} expression - The expression to evaluate.\n * @returns {this | undefined} The current instance if the expression is true, otherwise null.\n */\n if(expression) {\n return expression ? this : null;\n }\n /**\n * Wrap the current HTML element with a div.\n * @param {string} classForDiv - The class for the div.\n * @returns {this} The current instance for chaining.\n */\n wrap(classForDiv) {\n const wrapper = document.createElement(\"div\");\n wrapper.className = classForDiv;\n if (!this.element?.parentNode)\n throw new Error(\"Element has no parent node, can not wrap\");\n this.element.parentNode.insertBefore(wrapper, this.element);\n this.element.parentNode.removeChild(this.element);\n wrapper.appendChild(this.element);\n return this;\n }\n /**\n * Set the src attribute of the current HTML element if it is an image element.\n * @param {string} srcString - The new src.\n * @returns {this} The current instance for chaining.\n * @throws {TypeError} If the current HTML element is not an image element.\n */\n src(srcString) {\n if (this.element instanceof HTMLImageElement) {\n this.element.src = srcString;\n } else {\n throw new TypeError(`[El::${this.element.id}] You can only use src() on image elements'`);\n }\n return this;\n }\n /**\n * Set the alt attribute of the current HTML element if it is an image element.\n * @param {string} altString - The new alt.\n * @returns {this} The current instance for chaining.\n * @throws {TypeError} If the current HTML element is not an image element.\n */\n alt(altString) {\n if (this.element instanceof HTMLImageElement) {\n this.element.alt = altString;\n } else {\n throw new TypeError(`[El::${this.element.id}] You can only use alt() on image elements'`);\n }\n return this;\n }\n /**\n * Returns the parent element of the current HTML element.\n * @returns El\n */\n parent() {\n const parentElement = this.element.parentElement;\n if (!parentElement)\n throw new Error(\"Element has no parent node, can not get parent\");\n if (!parentElement.id)\n parentElement.id = `parent-${this.element.id}`;\n return new El(`#${parentElement?.id}`);\n }\n /**\n * Remove the current HTML element from the DOM.\n * @returns {this} The current instance for chaining.\n */\n remove() {\n if (!this.element?.parentNode)\n throw new Error(\"Element has no parent node, can not remove\");\n this.element.parentNode.removeChild(this.element);\n return this;\n }\n /**\n * Clear the innerHTML of the current HTML element.\n * @returns {this} The current instance for chaining.\n */\n clear() {\n this.element.innerHTML = \"\";\n return this;\n }\n /**\n * Remove specified attributes from the current HTML element.\n * @param {Array | string} properties - The attributes to remove.\n * @returns {this} The current instance for chaining.\n */\n unset(properties) {\n if (typeof properties === \"string\")\n properties = [properties];\n properties.forEach((key) => {\n this.element.removeAttribute(key);\n });\n return this;\n }\n /**\n * Set specified attributes and their values for the current HTML element.\n * @param {Record} setObj - The attributes and their values to set.\n * @returns {this} The current instance for chaining.\n */\n set(setObj) {\n Object.entries(setObj).forEach(([key, value]) => {\n if (!value)\n return;\n this.element.setAttribute(key, typeof value === \"string\" ? value : value.toString());\n });\n return this;\n }\n /**\n * Get the first child element of the current HTML element.\n * @returns {Element | undefined} The first child element, or undefined if there are no child elements.\n */\n firstChild() {\n return this.element.firstElementChild;\n }\n /**\n * Append or prepend a child element or HTML string to the current HTML element.\n * @param {HTMLElement | string} child - The child element or HTML string to append or prepend.\n * @param {'append' | 'prepend' | null} insertAt - Where to insert the child.\n * @returns {this} The current instance for chaining.\n */\n child(child, insertAt = null) {\n if (typeof child === \"string\") {\n if (!insertAt || insertAt === \"append\") {\n this.element.insertAdjacentHTML(\"beforeend\", child);\n } else {\n this.element.insertAdjacentHTML(\"afterbegin\", child);\n }\n } else {\n if (insertAt === \"append\" || insertAt == null) {\n this.element.append(child);\n }\n if (insertAt === \"prepend\") {\n this.element.prepend(child);\n }\n }\n return this;\n }\n /**\n * Get all child nodes of the current HTML element.\n * @returns {NodeListOf} The child nodes.\n */\n children() {\n return this.element.childNodes;\n }\n /**\n * Set the text content of the current HTML element.\n * @param {string | number | boolean} txt - The text content to set.\n * @returns {this} The current instance for chaining.\n */\n text(txt) {\n if (!txt)\n return this;\n this.element.textContent = txt.toString();\n return this;\n }\n /**\n * Set the text content of the current HTML element.\n * @param {string} content - The text content to set.\n * @returns {this|string|undefined} The current instance for chaining.\n */\n textContent(content) {\n if (!content) {\n return this.element.textContent;\n }\n this.element.textContent = content;\n return this;\n }\n /**\n * Append a text node as a child of the current HTML element.\n * @param {string} s - The text to append.\n * @returns {this} The current instance for chaining.\n */\n textChild(s) {\n const textEl = document.createTextNode(s.toString());\n this.element.appendChild(textEl);\n return this;\n }\n /**\n * Set the type attribute of the current HTML element.\n * @param {string} T - The type attribute to set.\n * @returns {this} The current instance for chaining.\n */\n type(_type) {\n if (\"type\" in this.element)\n this.element.setAttribute(\"type\", _type);\n return this;\n }\n /**\n * Set the name attribute of the current HTML element.\n * @param {string} N - The name attribute to set.\n * @returns {this} The current instance for chaining.\n */\n name(_name) {\n if (\"name\" in this.element)\n this.element.name = _name;\n return this;\n }\n /**\n * Set the type attribute of the current HTML element.\n * @param {string} type - The type attribute to set.\n * @returns {this} The current instance for chaining.\n */\n input(type) {\n if (\"name\" in this.element)\n this.element.name = this.element.id;\n if (\"type\" in this.element)\n this.element.setAttribute(\"type\", type);\n return this;\n }\n /**\n * Set the htmlFor attribute of the current HTML element.\n * @param {string} elementTheLabelIsFor - The id of the element the label is for.\n * @returns {this} The current instance for chaining.\n */\n htmlFor(elementTheLabelIsFor) {\n if (\"htmlFor\" in this.element)\n this.element.setAttribute(\"for\", elementTheLabelIsFor);\n return this;\n }\n /**\n * Set or retrieving the id attribute of the current HTML element.\n * @param {string | undefined} idForEl - The id attribute to set.\n * @returns {this | string} The current instance for chaining or the id value.\n */\n id(idForEl) {\n if (!idForEl)\n return this.element.id;\n this.element.id = idForEl;\n return this;\n }\n /**\n * Get or set the value of the current HTML element.\n * @param {string} newVal - The new value to set.\n * @returns {this | string} The current instance for chaining or the value.\n */\n val(newVal) {\n if (this.element instanceof HTMLInputElement || this.element instanceof HTMLSelectElement || this.element instanceof HTMLTextAreaElement || this.element instanceof HTMLOptionElement || this.element instanceof HTMLProgressElement) {\n if (newVal === void 0 || newVal === null)\n return this.element.value;\n this.element.value = newVal instanceof Date ? `${newVal.getFullYear()}-${newVal.getMonth() + 1}-${newVal.getDate()}` : typeof newVal === \"string\" ? newVal : newVal.toString();\n return this;\n }\n throw new TypeError(`[El::${this.element.id}] You can only use val() on input / select / text area / progress elements'`);\n }\n /**\n * Get the value of a data attribute of the current HTML element.\n * @param {string} dataSuffix - The suffix of the data attribute.\n * @returns {string | null} The value of the data attribute.\n */\n data(dataSuffix) {\n return this.element.getAttribute(`data-${dataSuffix}`);\n }\n /**\n * Get the dataset of the current HTML element.\n * @returns {DOMStringMap} The dataset.\n */\n dataset() {\n return this.element.dataset;\n }\n /**\n * Add an event listener to the current HTML element.\n * @param {string} event - The event name to listen for.\n * @param {EventListenerOrEventListenerObject} listener - The event listener function or object.\n * @param {boolean | AddEventListenerOptions} options - The options for the event listener.\n * @returns {this} The current instance for chaining.\n */\n on(event, listener, options) {\n this.element.addEventListener(event, listener, options);\n return this;\n }\n /**\n * Add an event listener to the current HTML element that will be triggered only once.\n * @param {string} eventName - The name of the event to listen for.\n * @param {(event: Event) => void | Promise} eventHandler - The event handler function.\n * @returns {this} The current instance for chaining.\n */\n once(eventName, eventHandler) {\n this.element.addEventListener(eventName, eventHandler, { once: true });\n return this;\n }\n /**\n * Dispatch a custom event on the current HTML element.\n * @param {string} eventName - The name of the event to dispatch.\n * @param {any} detail - The event detail.\n * @returns {this} The current instance for chaining.\n */\n now(eventName, detail) {\n this.element.dispatchEvent(new CustomEvent(eventName, {\n detail\n }));\n return this;\n }\n /**\n * Remove an event listener from the current HTML element.\n * @param {string} event - The event name to remove the listener from.\n * @param {EventListenerOrEventListenerObject} listener - The event listener function or object to remove.\n * @param {boolean | EventListenerOptions} options - The options for the event listener.\n * @returns {this} The current instance for chaining.\n */\n off(event, listener, options) {\n this.element.removeEventListener(event, listener, options);\n return this;\n }\n /**\n * Trigger an event on the current HTML element.\n * @param {string} event - The event name to trigger.\n * @param {CustomEventInit} options - The options for the custom event.\n * @returns {this} The current instance for chaining.\n */\n trigger(event, options) {\n this.element.dispatchEvent(new CustomEvent(event, options));\n return this;\n }\n /**\n * Trigger a change event on the current HTML element.\n * @returns {this} The current instance for chaining.\n */\n triggerChange() {\n if (this.element instanceof HTMLSelectElement) {\n const event = document.createEvent(\"HTMLEvents\");\n event.initEvent(\"change\", true, true);\n this.element.dispatchEvent(event);\n return this;\n }\n throw new TypeError(`[El::${this.element.id}] You can only use triggerChange() on select elements'`);\n }\n /**\n * Find all elements with the specified tag inside the current HTML element.\n * @param {string} tag - The tag name to search for.\n * @returns {NodeList} A NodeList containing all matching elements.\n */\n find(tag) {\n return this.element.querySelectorAll(tag);\n }\n /**\n * Dispatch a custom event on the current HTML element.\n * @param {string} eventName - The name of the event to dispatch.\n * @returns {this} The current instance for chaining.\n */\n dispatchEvent(eventName) {\n this.element.dispatchEvent(new Event(eventName));\n return this;\n }\n /**\n * Execute a callback function with the current HTML element's id as the argument.\n * @param {(id: idString) => any} cb - The callback function to execute.\n * @returns {this} The current instance for chaining.\n */\n nestFrom(cb) {\n cb(`#${this.element.id}`);\n return this;\n }\n}\nfunction el(selector) {\n return new El(selector);\n}\n\nexport { El, el };\n","import consola from \"consola\";\nimport type ApplicationV2 from 'src/types/foundry/client-esm/applications/api/application.mjs';\nimport type { DataModel } from \"src/types/foundry/common/abstract/module.mjs\";\nimport type { MaybePromise } from 'src/types/types/utils.mjs';\n\ntype HookableEvents = \"renderChatLog\" | \"renderChatMessage\";\ntype HookEvent = (\n app: Application,\n html: JQuery,\n data?: any,\n) => void | Promise;\n\ninterface RuleMenu extends ClientSettings.PartialSettingSubmenuConfig {\n\n}\n\ninterface Rule {\n name: string;\n hint?: string;\n restricted?: boolean;\n onChange?: (value: unknown) => void | Promise;\n /** true if you want to prompt the user to reload */\n requiresReload?: boolean;\n /**\n * @default true\n * @comment false if you dont want it to show in module config\n */\n config?: boolean;\n}\n\n// Define rule-specific types\ntype NumberRule = Rule & {\n type: typeof Number;\n range?: { min?: number; max?: number; step?: number };\n defaultValue?: number;\n};\ntype BooleanRule = Rule & { type: typeof Boolean; defaultValue?: boolean };\ntype StringRule = Rule & { type: typeof String; defaultValue?: string };\ntype ObjectRule = Rule & {\n type: typeof Object;\n defaultValue?: Record;\n};\ntype ArrayRule = Rule & {\n type: typeof Array;\n defaultValue?: unknown[];\n};\ntype ColorRule = Rule & { type: typeof Color; defaultValue?: string };\n\n// Define the Rules union type\ntype Rules =\n | NumberRule\n | BooleanRule\n | StringRule\n | ObjectRule\n | ArrayRule\n | ColorRule;\n\ninterface TomeRuleConstructor {\n globalSettings?: Array;\n clientSettings?: Array;\n}\n\nexport abstract class Tome {\n public moduleName: string;\n public moduleDescription: string;\n public settings: Array = [];\n public hooks = new Map([] as Array<[HookableEvents, HookEvent]>);\n public socketFns: Map void> = new Map();\n public DEBUG?: boolean = false;\n public ready = false;\n\n get name() {\n return this.moduleName;\n }\n\n get lowercaseName() {\n return this.moduleName.toLowerCase();\n }\n\n constructor(\n pTome: Pick & {\n settings?: TomeRuleConstructor;\n hooks?: Tome[\"hooks\"];\n socketFns?: Tome[\"socketFns\"];\n DEBUG?: boolean;\n },\n ) {\n this.moduleName = pTome.moduleName;\n this.moduleDescription = pTome.moduleDescription;\n if (pTome?.settings) {\n this.settings =\n pTome.settings.globalSettings?.map((s) => {\n s.scope = \"world\";\n return s as Rules & { scope: \"world\" };\n }) ?? [];\n\n this.settings.push(\n ...(pTome.settings.clientSettings?.map((s) => {\n s.scope = \"client\";\n return s as Rules & { scope: \"client\" };\n }) ?? []),\n );\n }\n\n this.hooks = pTome?.hooks ?? new Map();\n this.socketFns = pTome?.socketFns ?? new Map();\n this.DEBUG = pTome?.DEBUG ?? false;\n }\n\n public addHook(\n event: HookableEvents,\n callback: HookEvent,\n overwrite: boolean = false,\n ) {\n if (!this.hooks.has(event) || overwrite) {\n this.hooks.set(event, callback);\n } else {\n consola.warn(`Hook for event \"${event}\" already exists.`);\n }\n }\n\n public initializeHooks() {\n this.hooks.forEach((callback, event) => {\n if (this.DEBUG) {\n consola.box({\n title: `[TOME::${this.moduleName}] => Registering hook for ${event}`,\n additional: { callback: callback.toString() },\n })\n }\n\n Hooks.on(event, callback);\n });\n\n return this;\n }\n\n // Method to register global settings\n public registerSetting(rule: Rules & { scope: \"world\" | \"client\" }): Tome {\n switch (rule.type) {\n case Number:\n this.settings.push({ ...rule } as NumberRule & {\n scope: \"world\" | \"client\";\n });\n break;\n case Boolean:\n this.settings.push({ ...rule } as BooleanRule & {\n scope: \"world\" | \"client\";\n });\n break;\n case String:\n this.settings.push({ ...rule } as StringRule & {\n scope: \"world\" | \"client\";\n });\n break;\n case Object:\n this.settings.push({ ...rule } as ObjectRule & {\n scope: \"world\" | \"client\";\n });\n break;\n case Array:\n this.settings.push({ ...rule } as ArrayRule & {\n scope: \"world\" | \"client\";\n });\n break;\n case Color:\n this.settings.push({ ...rule } as ColorRule & {\n scope: \"world\" | \"client\";\n });\n break;\n default:\n throw new Error(`Unsupported rule type: ${rule.type}`);\n }\n\n return this;\n }\n\n public registerSettings(\n rules: Array,\n ): Tome {\n rules.forEach((rule) => {\n this.registerSetting(rule);\n });\n return this;\n }\n\n public initializeSettings() {\n this.settings.forEach((setting) => {\n if (this.DEBUG) {\n consola.box({\n title: `[TOME::${this.moduleName}] => Registering ${setting.name}`,\n additional: { ...setting },\n });\n }\n\n game.settings?.register('wonderlost', Tome.kabob(`${this.lowercaseName}-${setting.name}`), {\n name: setting.name,\n hint: setting.hint,\n scope: setting.scope,\n config: true,\n default: setting?.defaultValue,\n type: setting.type as unknown as DataModel,\n // @ts-ignore -> These are only there when the type is correct, but TS doesn't know that\n choices: setting?.choices,\n // @ts-ignore -> Same as above\n range: setting?.range,\n onChange: setting.onChange,\n requiresReload: setting.requiresReload,\n });\n });\n\n return this;\n }\n\n public getSetting(settingName: string) {\n return game.settings?.get('wonderlost', Tome.kabob(`${this.lowercaseName}-${settingName}`)) as ExpectedReturn;\n }\n\n public async setSetting(settingName: string, value: unknown) {\n return game.settings?.set('wonderlost', Tome.kabob(`${this.lowercaseName}-${settingName}`), value);\n }\n\n public registerSettingSubmenu = Record>(menu: RuleMenu & { data: Data }) {\n game.settings?.register('wonderlost', Tome.kabob(`${this.lowercaseName}-allSettings`), {\n scope: 'world',\n config: false,\n type: Object as unknown as DataModel,\n default: menu.data,\n })\n\n const lowercaseName = `${this.lowercaseName}`;\n const moduleName = this.moduleName.toString();\n\n game.settings?.registerMenu('wonderlost', Tome.kabob(`${this.lowercaseName}-allSettings`), {\n name: menu.name,\n label: menu.label,\n hint: menu.hint,\n icon: menu.icon,\n restricted: menu.restricted,\n // @ts-ignore\n type: class extends FormApplication {\n constructor() {\n super({});\n }\n\n static get defaultOptions() {\n return foundry.utils.mergeObject(super.defaultOptions, {\n title: `Wonderlost: ${moduleName}`,\n id: `${moduleName}-settings`,\n width: 550,\n height: \"auto\",\n popOut: true,\n closeOnSubmit: true as boolean,\n template: `modules/wonderlost/submodules/${lowercaseName}/settings.hbs`,\n });\n }\n\n static get moduleName() {\n return moduleName\n }\n\n getData() {\n return foundry.utils.isEmpty(game.settings?.get(moduleName, `${moduleName.toLowerCase()}-allSettings`) as any) ?\n game.settings?.get(moduleName, `${moduleName.toLowerCase()}-allSettings`) as MaybePromise\n : menu.data as MaybePromise;\n }\n\n async _updateObject(_event: Event, formData: Data) {\n await game.settings?.set(moduleName, `${moduleName.toLowerCase()}-allSettings`, formData);\n }\n }\n })\n }\n\n public initializeSocketListeners() {\n if (this.socketFns.size === 0) return this;\n\n this.socketFns.forEach((fn, event) => {\n if (this.DEBUG) {\n consola.info(`Registering socket listener for event: ${event}`);\n }\n\n game.socket?.on(event, (data: unknown) => fn(data));\n });\n\n return this;\n }\n\n public initialize() {\n this.initializeSettings()\n .initializeHooks()\n .initializeSocketListeners();\n\n this.ready = true;\n\n\n return this;\n }\n\n // Utility function to expand object rules\n static expandObject(value: unknown): Record {\n if (typeof value === \"object\" && value !== null) {\n return Object.entries(value).reduce(\n (acc, [key, val]) => {\n if (typeof val === \"string\") {\n try {\n acc[key] = JSON.parse(val);\n } catch (e) {\n acc[key] = val;\n }\n } else {\n acc[key] = val;\n }\n return acc;\n },\n {} as Record,\n );\n }\n throw new Error(`Expected object but received ${typeof value}`);\n }\n\n static kabob(str: string) {\n if (!str) return \"\";\n return str.split(\"\").join(\"-\");\n }\n}\n","import { El } from \"@magik_io/mote\";\nimport consola from 'consola';\nimport { Tome } from \"../../class/Tome\";\nimport { TweenMax } from \"/scripts/greensock/esm/all.js\";\n\nexport class Toasted extends Tome {\n public maxMessagesOnScreen = 5;\n public alwaysShowNotifications = true;\n public fadeOutDelay = 3000;\n\n public menu: El<'div', true> | null = null;\n\n constructor(DEBUG = false) {\n super({\n moduleName: \"Toasted\",\n moduleDescription: \"A customizable toast notification system\",\n hooks: new Map([\n [\n \"renderChatLog\",\n async (app, html) => {\n try {\n if (document.body.classList.contains(\"stream\")) return;\n const div = new El<'div', true>(\n html[0]\n .querySelector(`#chat-log`)!\n .cloneNode(false) as unknown as `div#${string}`,\n )\n .addClass(this.moduleName)\n .id(this.lowercaseName)\n .on(\"click\", (ev) => this.handleMouseEvent(ev))\n .on(\"contextmenu\" as \"click\", (ev) => this.handleMouseEvent(ev));\n\n document.querySelector('body')?.appendChild(div.element);\n\n if (this.DEBUG) consola.success(`${this.moduleName} | Chat log rendered`);\n } catch (error) {\n\n }\n },\n ],\n [\n \"renderChatMessage\",\n async (_app, html, _options) => {\n this.addMessage(html[0].cloneNode(true) as ChildNode);\n }\n ]\n ]),\n socketFns: new Map([\n [\n \"module.toasted\",\n (data) => {\n if (this.alwaysShowNotifications) {\n ui.notifications?.info(data);\n return;\n }\n\n consola.info(data);\n\n // this.toasts.push(data);\n // if (this.toasts.length > this.maxMessagesOnScreen) this.toasts.shift();\n\n // const toast = ui.notifications?.info(data);\n // toast?.element.addEventListener(\"click\", () => {\n // this.toasts.shift();\n // toast.close();\n // });\n },\n ]\n ]),\n DEBUG\n });\n\n this.registerSettings([\n {\n name: \"Toast Duration\",\n hint: \"How long would you like a message to stay on screen?\",\n type: Number,\n defaultValue: this.fadeOutDelay,\n range: { min: 1000, max: 10000, step: 250 },\n scope: \"client\",\n restricted: false,\n onChange: (value) => {\n this.fadeOutDelay = Number(value);\n },\n },\n {\n name: \"Max Messages\",\n hint: \"How many messages would you like to see on screen (at most)?\",\n type: Number,\n defaultValue: this.maxMessagesOnScreen,\n range: { min: 1, max: 10, step: 1 },\n scope: \"client\",\n restricted: false,\n onChange: (value) => {\n this.maxMessagesOnScreen = Number(value);\n },\n },\n {\n name: \"Always Show Notifications\",\n hint: \"Would you prefer toast are shown even if the chat panel is open?\",\n type: Boolean,\n defaultValue: this.alwaysShowNotifications,\n scope: \"client\",\n restricted: false,\n onChange: (value) => {\n this.alwaysShowNotifications = Boolean(value);\n },\n },\n ]);\n }\n\n static expandSidebarInstant(sidebar: HTMLDivElement) {\n if (!sidebar) {\n throw new Error(\n \"[Toasted:expandSidebarInstant] -> Error: Sidebar element was not passed\",\n );\n }\n\n const sideB = new El<\"div\", true>(sidebar)\n .removeClass(\"collapsed\")\n .unset([\"width\", \"height\"]);\n ui.sidebar._collapsed = false;\n\n const icon = sideB.element.querySelector(\"#sidebar-tabs a.collapse i\") as HTMLDivElement;\n\n if (!icon) {\n throw new Error(\n \"[Toasted:expandSidebarInstant] -> Error: Icon element was not found\",\n );\n }\n\n new El(icon).removeClass(\"fa-caret-left\").addClass(\"fa-caret-right\");\n\n Hooks.callAll(\"sidebarCollapse\", ui.sidebar, ui.sidebar._collapsed);\n }\n\n static findTarget(\n card: HTMLDivElement,\n event: MouseEvent,\n messageID: string,\n ) {\n const cardRect = card.getBoundingClientRect();\n const popupRect = document\n .querySelector(`.${this.name}`)!\n .getBoundingClientRect();\n let x = event.clientX - popupRect.left + cardRect.left;\n let y = event.clientY - popupRect.top + cardRect.top;\n\n let target = document.elementFromPoint(x, y);\n let closestMessage = target?.closest(\".message\");\n let closestMessageID = new El(closestMessage as HTMLDivElement).data(\n \"messageId\",\n );\n\n if (target && closestMessageID === messageID) {\n return { target, x, y };\n }\n const targetRect = (event.target as HTMLElement).getBoundingClientRect();\n // If click element is obscured, rasterize the target and test if some point is free\n // doing 10 steps in each direction, with a minimum of 5 px is some arbitrary number chosen, \n // but i think its quite okay in regards of accuracy and performance\n const dx = Math.min(targetRect.width / 10, 5);\n const dy = Math.min(targetRect.height / 10, 5);\n for (let vert = targetRect.top + 1; vert < targetRect.bottom; vert += dy) {\n y = vert - popupRect.top + cardRect.top;\n for (let hor = targetRect.left + 1; hor < targetRect.right; hor += dx) {\n x = hor - popupRect.left + cardRect.left;\n target = document.elementFromPoint(x, y);\n closestMessage = target?.closest(\".message\");\n closestMessageID = new El(closestMessage as HTMLDivElement).data(\n \"messageId\",\n );\n\n if (target && closestMessageID === messageID) return { target, x, y };\n }\n }\n\n return { target: null, x, y };\n }\n\n protected delegateEvent(n: Node, ev: MouseEvent) {\n const node = new El(n as HTMLDivElement);\n const card = new El(`.${this.moduleName}`).element.querySelector(\n `[data-message-id=\"${node.data(\"messageId\")}\"]`,\n ) as HTMLDivElement;\n // Card not found? strange.. just return\n if (!card) return;\n card.scrollIntoView();\n // Get target element on \"real\" chat-card\n const { target, x, y } = Toasted.findTarget(\n card,\n ev,\n node.data(\"messageId\")!,\n );\n // If for some reason wrong one was found.. just do nothing\n if (!target) return;\n\n const event = new MouseEvent(ev.type, {\n bubbles: true,\n cancelable: true,\n shiftKey: ev.shiftKey,\n metaKey: ev.metaKey,\n ctrlKey: ev.ctrlKey,\n clientX: x,\n clientY: y,\n });\n\n consola.info({\n title: `${this.moduleName} | Delegating event to chat log`,\n data: {\n target, x, y, event,\n },\n })\n\n\n target.dispatchEvent(event);\n }\n\n protected handleMouseEvent(ev: MouseEvent) {\n const targetElement = ev.target as HTMLElement;\n const node = targetElement?.closest(\".message\");\n if (!node) return;\n // activate chat\n const tabBtn = document.getElementById(\"sidebar-tabs\")?.children[0];\n if (tabBtn && !tabBtn.classList.contains(\"active\")) {\n tabBtn.dispatchEvent(\n new MouseEvent(\"click\", { bubbles: true, cancelable: true }),\n );\n }\n\n const sidebar = tabBtn?.closest(\"#sidebar\");\n if (sidebar && sidebar?.classList.contains(\"collapsed\")) {\n Toasted.expandSidebarInstant(sidebar as HTMLDivElement);\n }\n this.delegateEvent(node, ev);\n node.remove();\n }\n\n protected addMessage(node: ChildNode) {\n if (!this.ready) return;\n const div = new El(`#${this.lowercaseName}`);\n if (!div) {\n if (this.DEBUG) {\n consola.error(`${this.moduleName} | Chat log not found`, { this: this, node, div });\n }\n throw new Error(\"Chat log not found\");\n }\n\n const { messageId } = (node as HTMLElement).dataset;\n if (!messageId) throw new Error(\"Message ID not found\");\n\n const oldNode = div.element\n .querySelector(`[data-message-id=\"${messageId}\"]`);\n if (oldNode) return this.updateMessage(node, oldNode);\n if (div.children.length >= this.maxMessagesOnScreen) {\n div.element.firstElementChild?.remove();\n }\n\n div.child(node as HTMLDivElement, \"append\");\n TweenMax.from(node, 0.3, {\n height: 0,\n onComplete: () => {\n (node as HTMLDivElement).style.height = \"\"\n if (this.DEBUG) consola.success(`${this.moduleName} | Toasted message ${messageId}`);\n\n setTimeout(() => {\n this.removeMessage(node);\n }, this.fadeOutDelay);\n },\n });\n }\n\n protected removeMessage(node: ChildNode, { time = 0.3, delay = this.fadeOutDelay } = {}) {\n if (this.fadeOutDelay < 0) return;\n\n TweenMax.to(node, time, {\n opacity: 0,\n height: 0,\n delay,\n onComplete: () => { node.remove(); },\n });\n }\n\n protected updateMessage(newNode: ChildNode, oldNode: Node) {\n oldNode.parentNode?.replaceChild(newNode, oldNode);\n this.removeMessage(newNode);\n }\n}\n","import { Tome } from 'src/class/Tome';\n\nexport class Narrator extends Tome {\n constructor(DEBUG = false) {\n super({\n moduleName: \"Narrator\",\n moduleDescription: \"An extremely customizable on screen narrator system\",\n hooks: new Map([]),\n socketFns: new Map([]),\n DEBUG\n })\n }\n}\n","import consola from 'consola';\nimport { Toasted } from \"./submodules/toasted/Toasted\";\nimport { Narrator } from './submodules/narrator/Narrator';\n\nclass Wonderlost {\n public tomes = new Map([\n ['Toasted', Toasted],\n ['Narrator', Narrator],\n ])\n\n constructor(public DEBUG = false) {\n consola.info(\"Wonderlost | Initializing\");\n this.initializeTomes();\n }\n\n initializeTomes() {\n this.tomes.forEach((tome, tomeName) => {\n new tome(this.DEBUG).initialize();\n\n if (this.DEBUG) {\n consola.info(`Wonderlost | Initialized ${tomeName}`);\n }\n })\n }\n}\n\nHooks.once(\"init\", async function () {\n consola.start(\"Wonderlost | Initialized\");\n new Wonderlost(true);\n consola.success(\"Wonderlost | Ready\");\n});\n\nHooks.once(\"ready\", async function () { });\n\n"],"names":["LogLevels","silent","Number","NEGATIVE_INFINITY","fatal","error","warn","log","info","success","fail","ready","start","box","debug","trace","verbose","POSITIVE_INFINITY","LogTypes","level","isObject","value","_defu","baseObject","defaults","namespace","merger","object","Object","assign","key","Array","isArray","toString","defu","arguments_","reduce","p","c","isLogObj","arg","obj","prototype","call","message","args","stack","paused","queue","Consola","constructor","options","types","this","_normalizeLogLevel","reporters","throttle","throttleMin","formatOptions","date","colors","compact","type","_wrapLogFn","raw","mockFn","mockTypes","_lastLog","prompt","opts","Error","create","instance","_mockFn","withDefaults","withTag","tag","addReporter","reporter","push","removeReporter","i","indexOf","splice","setReporters","wrapAll","wrapConsole","wrapStd","restoreAll","restoreConsole","restoreStd","console","_wrapStream","stdout","stderr","stream","__write","write","data","String","trim","_restoreStream","pauseLogs","resumeLogs","_queue","item","_logFn","isRaw","logObj","Date","length","unshift","additional","split","join","toLowerCase","resolveLog","newLog","repeated","count","args2","_log","clearTimeout","timeout","diffTime","time","getTime","serializedLog","JSON","stringify","isSameLog","serialized","setTimeout","input","defaultLevel","add","remove","clear","withScope","mock","pause","resume","BrowserReporter","defaultColor","levelColorMap","typeColorMap","_getLogFn","__error","__warn","__log","consoleLogFn","style","badge","filter","Boolean","slice","consola","createConsola$1","options2","Promise","resolve","confirm","createConsola","__defProp","defineProperty","__publicField","enumerable","configurable","writable","__defNormalProp","isAElement","selector","HTMLElement","El","element","t","element2","document","querySelector","self","toggleClass","className","includes","forEach","classList","toggle","addClass","singleClass","removeClass","hasClass","contains","replaceWith","string","outerHTML","replaceWithElement","tagName","idForNewElement","newEl","createElement","id","parentNode","replaceChild","html","innerHTML","empty","check","trueOrFalse","HTMLInputElement","checked","TypeError","click","dispatchEvent","MouseEvent","view","window","bubbles","cancelable","expression","wrap","classForDiv","wrapper","insertBefore","removeChild","appendChild","src","srcString","HTMLImageElement","alt","altString","parent","parentElement","unset","properties","removeAttribute","set","setObj","entries","setAttribute","firstChild","firstElementChild","child","insertAt","insertAdjacentHTML","append","prepend","children","childNodes","text","txt","textContent","content","textChild","s","textEl","createTextNode","_type","name","_name","htmlFor","elementTheLabelIsFor","idForEl","val","newVal","HTMLSelectElement","HTMLTextAreaElement","HTMLOptionElement","HTMLProgressElement","getFullYear","getMonth","getDate","dataSuffix","getAttribute","dataset","on","event","listener","addEventListener","once","eventName","eventHandler","now","detail","CustomEvent","off","removeEventListener","trigger","triggerChange","createEvent","initEvent","find","querySelectorAll","Event","nestFrom","cb","Tome","moduleName","moduleDescription","settings","hooks","Map","socketFns","DEBUG","lowercaseName","pTome","globalSettings","map","scope","clientSettings","addHook","callback","overwrite","has","initializeHooks","title","Hooks","registerSetting","rule","Color","registerSettings","rules","initializeSettings","setting","game","register","kabob","hint","config","default","defaultValue","choices","range","onChange","requiresReload","getSetting","settingName","get","setSetting","registerSettingSubmenu","menu","registerMenu","label","icon","restricted","FormApplication","super","defaultOptions","foundry","utils","mergeObject","width","height","popOut","closeOnSubmit","template","getData","isEmpty","_updateObject","_event","formData","initializeSocketListeners","size","fn","socket","initialize","expandObject","acc","parse","e","str","Toasted","maxMessagesOnScreen","alwaysShowNotifications","fadeOutDelay","async","app","body","div","cloneNode","ev","handleMouseEvent","_app","_options","addMessage","ui","notifications","min","max","step","expandSidebarInstant","sidebar","sideB","_collapsed","callAll","findTarget","card","messageID","cardRect","getBoundingClientRect","popupRect","x","clientX","left","y","clientY","top","target","elementFromPoint","closestMessage","closest","closestMessageID","targetRect","dx","Math","dy","vert","bottom","hor","right","delegateEvent","n","node","scrollIntoView","shiftKey","metaKey","ctrlKey","targetElement","tabBtn","getElementById","messageId","oldNode","updateMessage","TweenMax","from","onComplete","removeMessage","delay","to","opacity","newNode","Narrator","Wonderlost","tomes","initializeTomes","tome","tomeName"],"mappings":"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","x_google_ignoreList":[0,1,2]} \ No newline at end of file +{"version":3,"file":"wonderlost.mjs","sources":["../node_modules/.pnpm/consola@3.2.3/node_modules/consola/dist/core.mjs","../node_modules/.pnpm/consola@3.2.3/node_modules/consola/dist/browser.mjs","../node_modules/.pnpm/@magik_io+mote@1.6.6/node_modules/@magik_io/mote/dist/El.mjs","../src/modules/fontLoader/utils/EventBus.ts","../src/class/Tome.ts","../src/submodules/toasted/Toasted.ts","../src/modules/fontLoader/CustomLoader.ts","../src/modules/fontLoader/utils/CSSParser.ts","../src/modules/fontLoader/utils/FontParser.ts","../src/modules/fontLoader/GoogleLoader.ts","../src/modules/fontLoader/utils/FontWatcher.ts","../src/modules/fontLoader/utils/Watcher.ts","../src/modules/fontLoader/FontLoader.ts","../src/submodules/narrator/Narrator.ts","../src/wonderlost.ts"],"sourcesContent":["const LogLevels = {\n silent: Number.NEGATIVE_INFINITY,\n fatal: 0,\n error: 0,\n warn: 1,\n log: 2,\n info: 3,\n success: 3,\n fail: 3,\n ready: 3,\n start: 3,\n box: 3,\n debug: 4,\n trace: 5,\n verbose: Number.POSITIVE_INFINITY\n};\nconst LogTypes = {\n // Silent\n silent: {\n level: -1\n },\n // Level 0\n fatal: {\n level: LogLevels.fatal\n },\n error: {\n level: LogLevels.error\n },\n // Level 1\n warn: {\n level: LogLevels.warn\n },\n // Level 2\n log: {\n level: LogLevels.log\n },\n // Level 3\n info: {\n level: LogLevels.info\n },\n success: {\n level: LogLevels.success\n },\n fail: {\n level: LogLevels.fail\n },\n ready: {\n level: LogLevels.info\n },\n start: {\n level: LogLevels.info\n },\n box: {\n level: LogLevels.info\n },\n // Level 4\n debug: {\n level: LogLevels.debug\n },\n // Level 5\n trace: {\n level: LogLevels.trace\n },\n // Verbose\n verbose: {\n level: LogLevels.verbose\n }\n};\n\nfunction isObject(value) {\n return value !== null && typeof value === \"object\";\n}\nfunction _defu(baseObject, defaults, namespace = \".\", merger) {\n if (!isObject(defaults)) {\n return _defu(baseObject, {}, namespace, merger);\n }\n const object = Object.assign({}, defaults);\n for (const key in baseObject) {\n if (key === \"__proto__\" || key === \"constructor\") {\n continue;\n }\n const value = baseObject[key];\n if (value === null || value === void 0) {\n continue;\n }\n if (merger && merger(object, key, value, namespace)) {\n continue;\n }\n if (Array.isArray(value) && Array.isArray(object[key])) {\n object[key] = [...value, ...object[key]];\n } else if (isObject(value) && isObject(object[key])) {\n object[key] = _defu(\n value,\n object[key],\n (namespace ? `${namespace}.` : \"\") + key.toString(),\n merger\n );\n } else {\n object[key] = value;\n }\n }\n return object;\n}\nfunction createDefu(merger) {\n return (...arguments_) => (\n // eslint-disable-next-line unicorn/no-array-reduce\n arguments_.reduce((p, c) => _defu(p, c, \"\", merger), {})\n );\n}\nconst defu = createDefu();\n\nfunction isPlainObject(obj) {\n return Object.prototype.toString.call(obj) === \"[object Object]\";\n}\nfunction isLogObj(arg) {\n if (!isPlainObject(arg)) {\n return false;\n }\n if (!arg.message && !arg.args) {\n return false;\n }\n if (arg.stack) {\n return false;\n }\n return true;\n}\n\nlet paused = false;\nconst queue = [];\nclass Consola {\n constructor(options = {}) {\n const types = options.types || LogTypes;\n this.options = defu(\n {\n ...options,\n defaults: { ...options.defaults },\n level: _normalizeLogLevel(options.level, types),\n reporters: [...options.reporters || []]\n },\n {\n types: LogTypes,\n throttle: 1e3,\n throttleMin: 5,\n formatOptions: {\n date: true,\n colors: false,\n compact: true\n }\n }\n );\n for (const type in types) {\n const defaults = {\n type,\n ...this.options.defaults,\n ...types[type]\n };\n this[type] = this._wrapLogFn(defaults);\n this[type].raw = this._wrapLogFn(\n defaults,\n true\n );\n }\n if (this.options.mockFn) {\n this.mockTypes();\n }\n this._lastLog = {};\n }\n get level() {\n return this.options.level;\n }\n set level(level) {\n this.options.level = _normalizeLogLevel(\n level,\n this.options.types,\n this.options.level\n );\n }\n prompt(message, opts) {\n if (!this.options.prompt) {\n throw new Error(\"prompt is not supported!\");\n }\n return this.options.prompt(message, opts);\n }\n create(options) {\n const instance = new Consola({\n ...this.options,\n ...options\n });\n if (this._mockFn) {\n instance.mockTypes(this._mockFn);\n }\n return instance;\n }\n withDefaults(defaults) {\n return this.create({\n ...this.options,\n defaults: {\n ...this.options.defaults,\n ...defaults\n }\n });\n }\n withTag(tag) {\n return this.withDefaults({\n tag: this.options.defaults.tag ? this.options.defaults.tag + \":\" + tag : tag\n });\n }\n addReporter(reporter) {\n this.options.reporters.push(reporter);\n return this;\n }\n removeReporter(reporter) {\n if (reporter) {\n const i = this.options.reporters.indexOf(reporter);\n if (i >= 0) {\n return this.options.reporters.splice(i, 1);\n }\n } else {\n this.options.reporters.splice(0);\n }\n return this;\n }\n setReporters(reporters) {\n this.options.reporters = Array.isArray(reporters) ? reporters : [reporters];\n return this;\n }\n wrapAll() {\n this.wrapConsole();\n this.wrapStd();\n }\n restoreAll() {\n this.restoreConsole();\n this.restoreStd();\n }\n wrapConsole() {\n for (const type in this.options.types) {\n if (!console[\"__\" + type]) {\n console[\"__\" + type] = console[type];\n }\n console[type] = this[type].raw;\n }\n }\n restoreConsole() {\n for (const type in this.options.types) {\n if (console[\"__\" + type]) {\n console[type] = console[\"__\" + type];\n delete console[\"__\" + type];\n }\n }\n }\n wrapStd() {\n this._wrapStream(this.options.stdout, \"log\");\n this._wrapStream(this.options.stderr, \"log\");\n }\n _wrapStream(stream, type) {\n if (!stream) {\n return;\n }\n if (!stream.__write) {\n stream.__write = stream.write;\n }\n stream.write = (data) => {\n this[type].raw(String(data).trim());\n };\n }\n restoreStd() {\n this._restoreStream(this.options.stdout);\n this._restoreStream(this.options.stderr);\n }\n _restoreStream(stream) {\n if (!stream) {\n return;\n }\n if (stream.__write) {\n stream.write = stream.__write;\n delete stream.__write;\n }\n }\n pauseLogs() {\n paused = true;\n }\n resumeLogs() {\n paused = false;\n const _queue = queue.splice(0);\n for (const item of _queue) {\n item[0]._logFn(item[1], item[2]);\n }\n }\n mockTypes(mockFn) {\n const _mockFn = mockFn || this.options.mockFn;\n this._mockFn = _mockFn;\n if (typeof _mockFn !== \"function\") {\n return;\n }\n for (const type in this.options.types) {\n this[type] = _mockFn(type, this.options.types[type]) || this[type];\n this[type].raw = this[type];\n }\n }\n _wrapLogFn(defaults, isRaw) {\n return (...args) => {\n if (paused) {\n queue.push([this, defaults, args, isRaw]);\n return;\n }\n return this._logFn(defaults, args, isRaw);\n };\n }\n _logFn(defaults, args, isRaw) {\n if ((defaults.level || 0) > this.level) {\n return false;\n }\n const logObj = {\n date: /* @__PURE__ */ new Date(),\n args: [],\n ...defaults,\n level: _normalizeLogLevel(defaults.level, this.options.types)\n };\n if (!isRaw && args.length === 1 && isLogObj(args[0])) {\n Object.assign(logObj, args[0]);\n } else {\n logObj.args = [...args];\n }\n if (logObj.message) {\n logObj.args.unshift(logObj.message);\n delete logObj.message;\n }\n if (logObj.additional) {\n if (!Array.isArray(logObj.additional)) {\n logObj.additional = logObj.additional.split(\"\\n\");\n }\n logObj.args.push(\"\\n\" + logObj.additional.join(\"\\n\"));\n delete logObj.additional;\n }\n logObj.type = typeof logObj.type === \"string\" ? logObj.type.toLowerCase() : \"log\";\n logObj.tag = typeof logObj.tag === \"string\" ? logObj.tag : \"\";\n const resolveLog = (newLog = false) => {\n const repeated = (this._lastLog.count || 0) - this.options.throttleMin;\n if (this._lastLog.object && repeated > 0) {\n const args2 = [...this._lastLog.object.args];\n if (repeated > 1) {\n args2.push(`(repeated ${repeated} times)`);\n }\n this._log({ ...this._lastLog.object, args: args2 });\n this._lastLog.count = 1;\n }\n if (newLog) {\n this._lastLog.object = logObj;\n this._log(logObj);\n }\n };\n clearTimeout(this._lastLog.timeout);\n const diffTime = this._lastLog.time && logObj.date ? logObj.date.getTime() - this._lastLog.time.getTime() : 0;\n this._lastLog.time = logObj.date;\n if (diffTime < this.options.throttle) {\n try {\n const serializedLog = JSON.stringify([\n logObj.type,\n logObj.tag,\n logObj.args\n ]);\n const isSameLog = this._lastLog.serialized === serializedLog;\n this._lastLog.serialized = serializedLog;\n if (isSameLog) {\n this._lastLog.count = (this._lastLog.count || 0) + 1;\n if (this._lastLog.count > this.options.throttleMin) {\n this._lastLog.timeout = setTimeout(\n resolveLog,\n this.options.throttle\n );\n return;\n }\n }\n } catch {\n }\n }\n resolveLog(true);\n }\n _log(logObj) {\n for (const reporter of this.options.reporters) {\n reporter.log(logObj, {\n options: this.options\n });\n }\n }\n}\nfunction _normalizeLogLevel(input, types = {}, defaultLevel = 3) {\n if (input === void 0) {\n return defaultLevel;\n }\n if (typeof input === \"number\") {\n return input;\n }\n if (types[input] && types[input].level !== void 0) {\n return types[input].level;\n }\n return defaultLevel;\n}\nConsola.prototype.add = Consola.prototype.addReporter;\nConsola.prototype.remove = Consola.prototype.removeReporter;\nConsola.prototype.clear = Consola.prototype.removeReporter;\nConsola.prototype.withScope = Consola.prototype.withTag;\nConsola.prototype.mock = Consola.prototype.mockTypes;\nConsola.prototype.pause = Consola.prototype.pauseLogs;\nConsola.prototype.resume = Consola.prototype.resumeLogs;\nfunction createConsola(options = {}) {\n return new Consola(options);\n}\n\nexport { Consola, LogLevels, LogTypes, createConsola };\n","import { createConsola as createConsola$1 } from './core.mjs';\nexport { Consola, LogLevels, LogTypes } from './core.mjs';\n\nclass BrowserReporter {\n constructor(options) {\n this.options = { ...options };\n this.defaultColor = \"#7f8c8d\";\n this.levelColorMap = {\n 0: \"#c0392b\",\n // Red\n 1: \"#f39c12\",\n // Yellow\n 3: \"#00BCD4\"\n // Cyan\n };\n this.typeColorMap = {\n success: \"#2ecc71\"\n // Green\n };\n }\n _getLogFn(level) {\n if (level < 1) {\n return console.__error || console.error;\n }\n if (level === 1) {\n return console.__warn || console.warn;\n }\n return console.__log || console.log;\n }\n log(logObj) {\n const consoleLogFn = this._getLogFn(logObj.level);\n const type = logObj.type === \"log\" ? \"\" : logObj.type;\n const tag = logObj.tag || \"\";\n const color = this.typeColorMap[logObj.type] || this.levelColorMap[logObj.level] || this.defaultColor;\n const style = `\n background: ${color};\n border-radius: 0.5em;\n color: white;\n font-weight: bold;\n padding: 2px 0.5em;\n `;\n const badge = `%c${[tag, type].filter(Boolean).join(\":\")}`;\n if (typeof logObj.args[0] === \"string\") {\n consoleLogFn(\n `${badge}%c ${logObj.args[0]}`,\n style,\n // Empty string as style resets to default console style\n \"\",\n ...logObj.args.slice(1)\n );\n } else {\n consoleLogFn(badge, style, ...logObj.args);\n }\n }\n}\n\nfunction createConsola(options = {}) {\n const consola2 = createConsola$1({\n reporters: options.reporters || [new BrowserReporter({})],\n prompt(message, options2 = {}) {\n if (options2.type === \"confirm\") {\n return Promise.resolve(confirm(message));\n }\n return Promise.resolve(prompt(message));\n },\n ...options\n });\n return consola2;\n}\nconst consola = createConsola();\n\nexport { consola, createConsola, consola as default };\n","var __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => {\n __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\n return value;\n};\nfunction isAElement(selector) {\n return selector instanceof HTMLElement;\n}\nclass El {\n /**\n * Create a new instance of El.\n * @param {selectorString} selector - The CSS selector for the HTML element.\n */\n constructor(selector) {\n __publicField(this, \"element\");\n __publicField(this, \"debug\", false);\n if (isAElement(selector)) {\n this.element = selector;\n return;\n }\n if (typeof selector === \"function\") {\n const t = selector();\n if (!t)\n throw new Error(\"Function must return an element\");\n if (this.debug)\n console.log(\"Function returned\", t);\n if (isAElement(t)) {\n this.element = t;\n return;\n }\n if (typeof t === \"string\") {\n const element2 = document.querySelector(t);\n if (!element2)\n throw new Error(`You tried to grab using '${selector}' but that doesn't exist!`);\n this.element = element2;\n return;\n }\n }\n const element = document.querySelector(selector);\n if (!element)\n throw new Error(`You tried to grab using '${selector}' but that doesn't exist!`);\n this.element = element;\n return;\n }\n /**\n * Get the current HTML element.\n * @returns {htmlElements} The current HTML element.\n */\n self() {\n return this.element;\n }\n /**\n * Toggle a class or classes on the current HTML element.\n * @param {string | Array} className - The class or classes to toggle.\n * @returns {this} The current instance for chaining.\n */\n toggleClass(className) {\n if (typeof className === \"string\" && className.includes(\" \"))\n className = className.split(\" \");\n if (!Array.isArray(className))\n className = [className];\n className.forEach((c) => this.element.classList.toggle(c));\n return this;\n }\n /**\n * Add a class or classes to the current HTML element.\n * @param {Array | string | (() => string) | (() => Array)} className - The class or classes to add.\n * @returns {this} The current instance for chaining.\n */\n addClass(className) {\n if (typeof className === \"function\")\n className = className();\n if (typeof className === \"string\" && className.includes(\" \"))\n className = className.split(\" \");\n if (!Array.isArray(className))\n className = [className];\n className.forEach((singleClass) => this.element.classList.add(singleClass));\n return this;\n }\n /**\n * Remove a class or classes from the current HTML element.\n * @param {Array | string | (() => string) | (() => Array)} className - The class or classes to remove.\n * @returns {this} The current instance for chaining.\n */\n removeClass(className) {\n if (typeof className === \"function\")\n className = className();\n if (typeof className === \"string\" && className.includes(\" \"))\n className = className.split(\" \");\n if (!Array.isArray(className))\n className = [className];\n className.forEach((singleClass) => this.element.classList.remove(singleClass));\n return this;\n }\n /**\n * Check if the current HTML element has a class.\n * @param {string} className - The class to check.\n * @returns {boolean} True if the element has the class, false otherwise.\n */\n hasClass(className) {\n return this.element.classList.contains(className);\n }\n /**\n * Replace the current HTML element with a string.\n * @param {string} string - The string to replace the element with.\n * @returns {this} The current instance for chaining.\n */\n replaceWith(string) {\n this.element.outerHTML = string;\n return this;\n }\n /**\n * Replace the current HTML element with a new element.\n * @template NewElement - The name of the new HTML element tag.\n * @param {NewElement} tagName - The tag name of the new element.\n * @param {string | undefined} idForNewElement - The id for the new element.\n * @returns {El} A new instance of El for the new element.\n */\n replaceWithElement(tagName, idForNewElement = void 0) {\n const newEl = document.createElement(tagName);\n newEl.id = idForNewElement ?? this.element.id;\n if (!this.element?.parentNode)\n throw new Error(\"Element has no parent node, can not replace\");\n this.element.parentNode.replaceChild(newEl, this.element);\n return new El(`#${newEl.id}`);\n }\n /**\n * Set the inner HTML of the current HTML element.\n * @param {string} string - The new inner HTML.\n * @returns {this} The current instance for chaining.\n */\n html(string) {\n this.element.innerHTML = string;\n return this;\n }\n /**\n * Empty the inner HTML of the current HTML element.\n * @returns {this} The current instance for chaining.\n */\n empty() {\n this.element.innerHTML = \"\";\n return this;\n }\n /**\n * Check or uncheck the current HTML element if it is an input element.\n * @param {boolean} trueOrFalse - Whether to check or uncheck the element.\n * @returns {this} The current instance for chaining.\n * @throws {TypeError} If the current HTML element is not an input element.\n */\n check(trueOrFalse) {\n if (this.element instanceof HTMLInputElement) {\n this.element.checked = trueOrFalse;\n return this;\n }\n throw new TypeError(`[El::${this.element.id}] You can only use check() on input elements'`);\n }\n /**\n * Get whether the current HTML element is checked if it is an input element.\n * @returns {boolean} Whether the element is checked.\n * @throws {TypeError} If the current HTML element is not an input element.\n */\n checked() {\n if (this.element instanceof HTMLInputElement)\n return this.element.checked;\n throw new TypeError(`[El::${this.element.id}] You can only use checked() on input elements'`);\n }\n /**\n * Dispatch a click event on the current HTML element.\n * @returns {this} The current instance for chaining.\n */\n click() {\n this.element.dispatchEvent(\n new MouseEvent(\"click\", { view: window, bubbles: true, cancelable: false })\n );\n return this;\n }\n /**\n * Return the current instance if the expression is true, otherwise return undefined, useful for chaining\n * @param {boolean} expression - The expression to evaluate.\n * @returns {this | undefined} The current instance if the expression is true, otherwise null.\n */\n if(expression) {\n return expression ? this : null;\n }\n /**\n * Wrap the current HTML element with a div.\n * @param {string} classForDiv - The class for the div.\n * @returns {this} The current instance for chaining.\n */\n wrap(classForDiv) {\n const wrapper = document.createElement(\"div\");\n wrapper.className = classForDiv;\n if (!this.element?.parentNode)\n throw new Error(\"Element has no parent node, can not wrap\");\n this.element.parentNode.insertBefore(wrapper, this.element);\n this.element.parentNode.removeChild(this.element);\n wrapper.appendChild(this.element);\n return this;\n }\n /**\n * Set the src attribute of the current HTML element if it is an image element.\n * @param {string} srcString - The new src.\n * @returns {this} The current instance for chaining.\n * @throws {TypeError} If the current HTML element is not an image element.\n */\n src(srcString) {\n if (this.element instanceof HTMLImageElement) {\n this.element.src = srcString;\n } else {\n throw new TypeError(`[El::${this.element.id}] You can only use src() on image elements'`);\n }\n return this;\n }\n /**\n * Set the alt attribute of the current HTML element if it is an image element.\n * @param {string} altString - The new alt.\n * @returns {this} The current instance for chaining.\n * @throws {TypeError} If the current HTML element is not an image element.\n */\n alt(altString) {\n if (this.element instanceof HTMLImageElement) {\n this.element.alt = altString;\n } else {\n throw new TypeError(`[El::${this.element.id}] You can only use alt() on image elements'`);\n }\n return this;\n }\n /**\n * Returns the parent element of the current HTML element.\n * @returns El\n */\n parent() {\n const parentElement = this.element.parentElement;\n if (!parentElement)\n throw new Error(\"Element has no parent node, can not get parent\");\n if (!parentElement.id)\n parentElement.id = `parent-${this.element.id}`;\n return new El(`#${parentElement?.id}`);\n }\n /**\n * Remove the current HTML element from the DOM.\n * @returns {this} The current instance for chaining.\n */\n remove() {\n if (!this.element?.parentNode)\n throw new Error(\"Element has no parent node, can not remove\");\n this.element.parentNode.removeChild(this.element);\n return this;\n }\n /**\n * Clear the innerHTML of the current HTML element.\n * @returns {this} The current instance for chaining.\n */\n clear() {\n this.element.innerHTML = \"\";\n return this;\n }\n /**\n * Remove specified attributes from the current HTML element.\n * @param {Array | string} properties - The attributes to remove.\n * @returns {this} The current instance for chaining.\n */\n unset(properties) {\n if (typeof properties === \"string\")\n properties = [properties];\n properties.forEach((key) => {\n this.element.removeAttribute(key);\n });\n return this;\n }\n /**\n * Set specified attributes and their values for the current HTML element.\n * @param {Record} setObj - The attributes and their values to set.\n * @returns {this} The current instance for chaining.\n */\n set(setObj) {\n Object.entries(setObj).forEach(([key, value]) => {\n if (!value)\n return;\n this.element.setAttribute(key, typeof value === \"string\" ? value : value.toString());\n });\n return this;\n }\n /**\n * Get the first child element of the current HTML element.\n * @returns {Element | undefined} The first child element, or undefined if there are no child elements.\n */\n firstChild() {\n return this.element.firstElementChild;\n }\n /**\n * Append or prepend a child element or HTML string to the current HTML element.\n * @param {HTMLElement | string} child - The child element or HTML string to append or prepend.\n * @param {'append' | 'prepend' | null} insertAt - Where to insert the child.\n * @returns {this} The current instance for chaining.\n */\n child(child, insertAt = null) {\n if (typeof child === \"string\") {\n if (!insertAt || insertAt === \"append\") {\n this.element.insertAdjacentHTML(\"beforeend\", child);\n } else {\n this.element.insertAdjacentHTML(\"afterbegin\", child);\n }\n } else {\n if (insertAt === \"append\" || insertAt == null) {\n this.element.append(child);\n }\n if (insertAt === \"prepend\") {\n this.element.prepend(child);\n }\n }\n return this;\n }\n /**\n * Get all child nodes of the current HTML element.\n * @returns {NodeListOf} The child nodes.\n */\n children() {\n return this.element.childNodes;\n }\n /**\n * Set the text content of the current HTML element.\n * @param {string | number | boolean} txt - The text content to set.\n * @returns {this} The current instance for chaining.\n */\n text(txt) {\n if (!txt)\n return this;\n this.element.textContent = txt.toString();\n return this;\n }\n /**\n * Set the text content of the current HTML element.\n * @param {string} content - The text content to set.\n * @returns {this|string|undefined} The current instance for chaining.\n */\n textContent(content) {\n if (!content) {\n return this.element.textContent;\n }\n this.element.textContent = content;\n return this;\n }\n /**\n * Append a text node as a child of the current HTML element.\n * @param {string} s - The text to append.\n * @returns {this} The current instance for chaining.\n */\n textChild(s) {\n const textEl = document.createTextNode(s.toString());\n this.element.appendChild(textEl);\n return this;\n }\n /**\n * Set the type attribute of the current HTML element.\n * @param {string} T - The type attribute to set.\n * @returns {this} The current instance for chaining.\n */\n type(_type) {\n if (\"type\" in this.element)\n this.element.setAttribute(\"type\", _type);\n return this;\n }\n /**\n * Set the name attribute of the current HTML element.\n * @param {string} N - The name attribute to set.\n * @returns {this} The current instance for chaining.\n */\n name(_name) {\n if (\"name\" in this.element)\n this.element.name = _name;\n return this;\n }\n /**\n * Set the type attribute of the current HTML element.\n * @param {string} type - The type attribute to set.\n * @returns {this} The current instance for chaining.\n */\n input(type) {\n if (\"name\" in this.element)\n this.element.name = this.element.id;\n if (\"type\" in this.element)\n this.element.setAttribute(\"type\", type);\n return this;\n }\n /**\n * Set the htmlFor attribute of the current HTML element.\n * @param {string} elementTheLabelIsFor - The id of the element the label is for.\n * @returns {this} The current instance for chaining.\n */\n htmlFor(elementTheLabelIsFor) {\n if (\"htmlFor\" in this.element)\n this.element.setAttribute(\"for\", elementTheLabelIsFor);\n return this;\n }\n /**\n * Set or retrieving the id attribute of the current HTML element.\n * @param {string | undefined} idForEl - The id attribute to set.\n * @returns {this | string} The current instance for chaining or the id value.\n */\n id(idForEl) {\n if (!idForEl)\n return this.element.id;\n this.element.id = idForEl;\n return this;\n }\n /**\n * Get or set the value of the current HTML element.\n * @param {string} newVal - The new value to set.\n * @returns {this | string} The current instance for chaining or the value.\n */\n val(newVal) {\n if (this.element instanceof HTMLInputElement || this.element instanceof HTMLSelectElement || this.element instanceof HTMLTextAreaElement || this.element instanceof HTMLOptionElement || this.element instanceof HTMLProgressElement) {\n if (newVal === void 0 || newVal === null)\n return this.element.value;\n this.element.value = newVal instanceof Date ? `${newVal.getFullYear()}-${newVal.getMonth() + 1}-${newVal.getDate()}` : typeof newVal === \"string\" ? newVal : newVal.toString();\n return this;\n }\n throw new TypeError(`[El::${this.element.id}] You can only use val() on input / select / text area / progress elements'`);\n }\n /**\n * Get the value of a data attribute of the current HTML element.\n * @param {string} dataSuffix - The suffix of the data attribute.\n * @returns {string | null} The value of the data attribute.\n */\n data(dataSuffix) {\n return this.element.getAttribute(`data-${dataSuffix}`);\n }\n /**\n * Get the dataset of the current HTML element.\n * @returns {DOMStringMap} The dataset.\n */\n dataset() {\n return this.element.dataset;\n }\n /**\n * Add an event listener to the current HTML element.\n * @param {string} event - The event name to listen for.\n * @param {EventListenerOrEventListenerObject} listener - The event listener function or object.\n * @param {boolean | AddEventListenerOptions} options - The options for the event listener.\n * @returns {this} The current instance for chaining.\n */\n on(event, listener, options) {\n this.element.addEventListener(event, listener, options);\n return this;\n }\n /**\n * Add an event listener to the current HTML element that will be triggered only once.\n * @param {string} eventName - The name of the event to listen for.\n * @param {(event: Event) => void | Promise} eventHandler - The event handler function.\n * @returns {this} The current instance for chaining.\n */\n once(eventName, eventHandler) {\n this.element.addEventListener(eventName, eventHandler, { once: true });\n return this;\n }\n /**\n * Dispatch a custom event on the current HTML element.\n * @param {string} eventName - The name of the event to dispatch.\n * @param {any} detail - The event detail.\n * @returns {this} The current instance for chaining.\n */\n now(eventName, detail) {\n this.element.dispatchEvent(new CustomEvent(eventName, {\n detail\n }));\n return this;\n }\n /**\n * Remove an event listener from the current HTML element.\n * @param {string} event - The event name to remove the listener from.\n * @param {EventListenerOrEventListenerObject} listener - The event listener function or object to remove.\n * @param {boolean | EventListenerOptions} options - The options for the event listener.\n * @returns {this} The current instance for chaining.\n */\n off(event, listener, options) {\n this.element.removeEventListener(event, listener, options);\n return this;\n }\n /**\n * Trigger an event on the current HTML element.\n * @param {string} event - The event name to trigger.\n * @param {CustomEventInit} options - The options for the custom event.\n * @returns {this} The current instance for chaining.\n */\n trigger(event, options) {\n this.element.dispatchEvent(new CustomEvent(event, options));\n return this;\n }\n /**\n * Trigger a change event on the current HTML element.\n * @returns {this} The current instance for chaining.\n */\n triggerChange() {\n if (this.element instanceof HTMLSelectElement) {\n const event = document.createEvent(\"HTMLEvents\");\n event.initEvent(\"change\", true, true);\n this.element.dispatchEvent(event);\n return this;\n }\n throw new TypeError(`[El::${this.element.id}] You can only use triggerChange() on select elements'`);\n }\n /**\n * Find all elements with the specified tag inside the current HTML element.\n * @param {string} tag - The tag name to search for.\n * @returns {NodeList} A NodeList containing all matching elements.\n */\n find(tag) {\n return this.element.querySelectorAll(tag);\n }\n /**\n * Dispatch a custom event on the current HTML element.\n * @param {string} eventName - The name of the event to dispatch.\n * @returns {this} The current instance for chaining.\n */\n dispatchEvent(eventName) {\n this.element.dispatchEvent(new Event(eventName));\n return this;\n }\n /**\n * Execute a callback function with the current HTML element's id as the argument.\n * @param {(id: idString) => any} cb - The callback function to execute.\n * @returns {this} The current instance for chaining.\n */\n nestFrom(cb) {\n cb(`#${this.element.id}`);\n return this;\n }\n}\nfunction el(selector) {\n return new El(selector);\n}\n\nexport { El, el };\n","import type { FontsLoaderConfig } from '../types';\n\nexport enum FontEvents {\n LOADING = 'loading',\n ACTIVE = 'active',\n INACTIVE = 'inactive',\n FONT_LOADING = 'fontloading',\n FONT_ACTIVE = 'fontactive',\n FONT_INACTIVE = 'fontinactive',\n}\n\nexport class EventBus {\n private namespace_ = 'wf';\n private classSeparator_ = '-';\n private event_: Event;\n private config_: FontsLoaderConfig;\n private htmlElement_;\n\n constructor(config: FontsLoaderConfig) {\n this.config_ = config;\n this.event_ = document.createEvent('CustomEvent');\n this.htmlElement_ = document.documentElement;\n document.addEventListener(\n FontEvents.LOADING,\n () => {\n this.handleLoading_();\n },\n false\n );\n document.addEventListener(\n FontEvents.ACTIVE,\n () => {\n this.handleActive_();\n },\n false\n );\n document.addEventListener(\n FontEvents.INACTIVE,\n () => {\n this.handleInactive_();\n },\n false\n );\n document.addEventListener(\n FontEvents.FONT_LOADING,\n (event) => {\n const { detail } = event as CustomEvent;\n this.handleFontLoading_(detail);\n },\n false\n );\n document.addEventListener(\n FontEvents.FONT_ACTIVE,\n (event) => {\n const { detail } = event as CustomEvent;\n this.handleFontActive_(detail);\n },\n false\n );\n document.addEventListener(\n FontEvents.FONT_INACTIVE,\n (event) => {\n const { detail } = event as CustomEvent;\n this.handleFontInactive_(detail);\n },\n false\n );\n }\n\n private handleLoading_() {\n if (this.config_.events && this.config_.loading) {\n this.config_.loading.call(null);\n this.addClassToHtml_(FontEvents.LOADING);\n this.removeClassFromHtml_(FontEvents.ACTIVE);\n this.removeClassFromHtml_(FontEvents.INACTIVE);\n }\n }\n\n private handleActive_() {\n if (this.config_.events && this.config_.active) {\n this.config_.active.call(null);\n this.removeClassFromHtml_(FontEvents.LOADING);\n this.addClassToHtml_(FontEvents.ACTIVE);\n this.removeClassFromHtml_(FontEvents.INACTIVE);\n }\n }\n\n private handleInactive_() {\n if (this.config_.events && this.config_.inactive) {\n this.config_.inactive.call(null);\n this.removeClassFromHtml_(FontEvents.LOADING);\n this.removeClassFromHtml_(FontEvents.ACTIVE);\n this.addClassToHtml_(FontEvents.INACTIVE);\n }\n }\n\n private handleFontLoading_(font: string) {\n if (this.config_.events && this.config_.fontloading) {\n const fontArray = font.split(':');\n this.config_.fontloading.call(null, fontArray[0], fontArray[1]);\n this.addClassToHtml_(FontEvents.LOADING, [fontArray[0], fontArray[1]]);\n this.removeClassFromHtml_(FontEvents.ACTIVE, [fontArray[0], fontArray[1]]);\n this.removeClassFromHtml_(FontEvents.INACTIVE, [fontArray[0], fontArray[1]]);\n }\n }\n\n private handleFontActive_(font: string) {\n if (this.config_.events && this.config_.fontactive) {\n const fontArray = font.split(':');\n this.config_.fontactive.call(null, fontArray[0], fontArray[1]);\n this.removeClassFromHtml_(FontEvents.LOADING, [fontArray[0], fontArray[1]]);\n this.addClassToHtml_(FontEvents.ACTIVE, [fontArray[0], fontArray[1]]);\n this.removeClassFromHtml_(FontEvents.INACTIVE, [fontArray[0], fontArray[1]]);\n }\n }\n\n private handleFontInactive_(font: string) {\n if (this.config_.events && this.config_.fontinactive) {\n const fontArray = font.split(':');\n this.config_.fontinactive.call(null, fontArray[0], fontArray[1]);\n this.removeClassFromHtml_(FontEvents.LOADING, [fontArray[0], fontArray[1]]);\n this.removeClassFromHtml_(FontEvents.ACTIVE, [fontArray[0], fontArray[1]]);\n this.addClassToHtml_(FontEvents.INACTIVE, [fontArray[0], fontArray[1]]);\n }\n }\n\n private addClassToHtml_(className: string, prefix: string[] = []) {\n this.htmlElement_.classList.add(\n [this.namespace_].concat(prefix.map(this.sanitizeClassName_), className).join(this.classSeparator_)\n );\n }\n\n private removeClassFromHtml_(className: string, prefix: string[] = []) {\n this.htmlElement_.classList.remove(\n [this.namespace_].concat(prefix.map(this.sanitizeClassName_), className).join(this.classSeparator_)\n );\n }\n\n private sanitizeClassName_(className: string) {\n return className.replace(/[\\W_]+/g, '').toLowerCase();\n }\n}\n","import consola from \"consola\";\nimport type ApplicationV2 from 'src/types/foundry/client-esm/applications/api/application.mjs';\nimport type { DataModel } from \"src/types/foundry/common/abstract/module.mjs\";\nimport type { MaybePromise } from 'src/types/types/utils.mjs';\n\ntype CoreLifeCycleHooks = 'init' | 'ready' | 'error' | 'setup' | 'i18nInit'\n\ntype HookableEvents = \"renderChatLog\" | \"renderChatMessage\" | 'renderApplication' | CoreLifeCycleHooks\ntype HookEvent = (\n app: Application,\n html: JQuery,\n data?: any,\n) => void | Promise;\n\ninterface RuleMenu extends ClientSettings.PartialSettingSubmenuConfig {\n\n}\n\ninterface Rule {\n name: string;\n hint?: string;\n restricted?: boolean;\n onChange?: (value: unknown) => void | Promise;\n /** true if you want to prompt the user to reload */\n requiresReload?: boolean;\n /**\n * @default true\n * @comment false if you dont want it to show in module config\n */\n config?: boolean;\n choices?: Record;\n}\n\n// Define rule-specific types\ntype NumberRule = Rule & {\n type: typeof Number;\n range?: { min?: number; max?: number; step?: number };\n defaultValue?: number;\n};\ntype BooleanRule = Rule & { type: typeof Boolean; defaultValue?: boolean };\ntype StringRule = Rule & { type: typeof String; defaultValue?: string };\ntype ObjectRule = Rule & {\n type: typeof Object;\n defaultValue?: Record;\n};\ntype ArrayRule = Rule & {\n type: typeof Array;\n defaultValue?: unknown[];\n};\ntype ColorRule = Rule & { type: typeof Color; defaultValue?: string };\n\n// Define the Rules union type\ntype Rules =\n | NumberRule\n | BooleanRule\n | StringRule\n | ObjectRule\n | ArrayRule\n | ColorRule;\n\ninterface TomeRuleConstructor {\n globalSettings?: Array;\n clientSettings?: Array;\n}\n\nexport abstract class Tome {\n public moduleName: string;\n public moduleDescription: string;\n public settings: Array = [];\n public hooks = new Map([] as Array<[HookableEvents, HookEvent]>);\n public socketFns: Map void> = new Map();\n public DEBUG?: boolean = false;\n public ready = false;\n\n get name() {\n return this.moduleName;\n }\n\n get lowercaseName() {\n return this.moduleName.toLowerCase();\n }\n\n get hasHooks() {\n return this.hooks.size > 0;\n }\n\n get hasSettings() {\n return this.settings.length > 0;\n }\n\n get hasSocketFns() {\n return this.socketFns.size > 0;\n }\n\n get needsEarlyInitialization() {\n return (this.hasSettings\n || (this.hasHooks && this.hooks.has('init') || this.hasHooks && this.hooks.has('ready'))\n || this.hasSocketFns)\n }\n\n constructor(\n pTome: Pick & {\n settings?: TomeRuleConstructor;\n hooks?: Tome[\"hooks\"];\n socketFns?: Tome[\"socketFns\"];\n DEBUG?: boolean;\n },\n ) {\n this.moduleName = pTome.moduleName;\n this.moduleDescription = pTome.moduleDescription;\n if (pTome?.settings) {\n this.settings =\n pTome.settings.globalSettings?.map((s) => {\n s.scope = \"world\";\n return s as Rules & { scope: \"world\" };\n }) ?? [];\n\n this.settings.push(\n ...(pTome.settings.clientSettings?.map((s) => {\n s.scope = \"client\";\n return s as Rules & { scope: \"client\" };\n }) ?? []),\n );\n }\n\n this.hooks = pTome?.hooks ?? new Map();\n this.socketFns = pTome?.socketFns ?? new Map();\n this.DEBUG = pTome?.DEBUG ?? false;\n }\n\n public addHook(\n event: HookableEvents,\n callback: HookEvent,\n overwrite: boolean = false,\n ) {\n if (!this.hooks.has(event) || overwrite) {\n this.hooks.set(event, callback);\n } else {\n consola.warn(`Hook for event \"${event}\" already exists.`);\n }\n }\n\n public initializeHooks() {\n this.hooks.forEach((callback, event) => {\n if (this.DEBUG) {\n consola.box({\n title: `[TOME::${this.moduleName}] => Registering hook for ${event}`,\n additional: { callback: callback.toString() },\n })\n }\n\n Hooks.on(event, callback);\n });\n\n return this;\n }\n\n // Method to register global settings\n public registerSetting(rule: Rules & { scope: \"world\" | \"client\" }): Tome {\n switch (rule.type) {\n case Number:\n this.settings.push({ ...rule } as NumberRule & {\n scope: \"world\" | \"client\";\n });\n break;\n case Boolean:\n this.settings.push({ ...rule } as BooleanRule & {\n scope: \"world\" | \"client\";\n });\n break;\n case String:\n this.settings.push({ ...rule } as StringRule & {\n scope: \"world\" | \"client\";\n });\n break;\n case Object:\n this.settings.push({ ...rule } as ObjectRule & {\n scope: \"world\" | \"client\";\n });\n break;\n case Array:\n this.settings.push({ ...rule } as ArrayRule & {\n scope: \"world\" | \"client\";\n });\n break;\n case Color:\n this.settings.push({ ...rule } as ColorRule & {\n scope: \"world\" | \"client\";\n });\n break;\n default:\n throw new Error(`Unsupported rule type: ${rule.type}`);\n }\n\n return this;\n }\n\n public registerSettings(\n rules: Array,\n ): Tome {\n rules.forEach((rule) => {\n this.registerSetting(rule);\n });\n return this;\n }\n\n public initializeSettings() {\n this.settings.forEach((setting) => {\n if (this.DEBUG) {\n consola.box({\n title: `[TOME::${this.moduleName}] => Registering ${setting.name}`,\n additional: { ...setting },\n });\n }\n\n game.settings?.register('wonderlost', Tome.kabob(`${this.lowercaseName}-${setting.name}`), {\n name: setting.name,\n hint: setting.hint,\n scope: setting.scope,\n config: true,\n default: setting?.defaultValue,\n type: setting.type as unknown as DataModel,\n // @ts-ignore -> These are only there when the type is correct, but TS doesn't know that\n choices: setting?.choices,\n // @ts-ignore -> Same as above\n range: setting?.range,\n onChange: setting.onChange,\n requiresReload: setting.requiresReload,\n });\n });\n\n return this;\n }\n\n public getSetting(settingName: string) {\n return game.settings?.get('wonderlost', Tome.kabob(`${this.lowercaseName}-${settingName}`)) as ExpectedReturn;\n }\n\n public async setSetting(settingName: string, value: unknown) {\n return game.settings?.set('wonderlost', Tome.kabob(`${this.lowercaseName}-${settingName}`), value);\n }\n\n public registerSettingSubmenu = Record>(menu: RuleMenu & { data: Data }) {\n game.settings?.register('wonderlost', Tome.kabob(`${this.lowercaseName}-allSettings`), {\n scope: 'world',\n config: false,\n type: Object as unknown as DataModel,\n default: menu.data,\n })\n\n const lowercaseName = `${this.lowercaseName}`;\n const moduleName = this.moduleName.toString();\n\n game.settings?.registerMenu('wonderlost', Tome.kabob(`${this.lowercaseName}-allSettings`), {\n name: menu.name,\n label: menu.label,\n hint: menu.hint,\n icon: menu.icon,\n restricted: menu.restricted,\n // @ts-ignore\n type: class extends FormApplication {\n constructor() {\n super({});\n }\n\n static get defaultOptions() {\n return foundry.utils.mergeObject(super.defaultOptions, {\n title: `Wonderlost: ${moduleName}`,\n id: `${moduleName}-settings`,\n width: 550,\n height: \"auto\",\n popOut: true,\n closeOnSubmit: true as boolean,\n template: `modules/wonderlost/submodules/${lowercaseName}/settings.hbs`,\n });\n }\n\n static get moduleName() {\n return moduleName\n }\n\n getData() {\n return foundry.utils.isEmpty(game.settings?.get(moduleName, `${moduleName.toLowerCase()}-allSettings`) as any) ?\n game.settings?.get(moduleName, `${moduleName.toLowerCase()}-allSettings`) as MaybePromise\n : menu.data as MaybePromise;\n }\n\n async _updateObject(_event: Event, formData: Data) {\n await game.settings?.set(moduleName, `${moduleName.toLowerCase()}-allSettings`, formData);\n }\n }\n })\n }\n\n public initializeSocketListeners() {\n if (this.socketFns.size === 0) return this;\n\n this.socketFns.forEach((fn, event) => {\n if (this.DEBUG) {\n consola.info(`Registering socket listener for event: ${event}`);\n }\n\n game.socket?.on(event, (data: unknown) => fn(data));\n });\n\n return this;\n }\n\n public initialize() {\n if (this.hasSettings) {\n this.initializeSettings()\n }\n\n if (this.hasHooks) {\n this.initializeHooks();\n }\n\n if (this.hasSocketFns) {\n this.initializeSocketListeners();\n }\n\n this.ready = true;\n\n return this;\n }\n\n // Utility function to expand object rules\n static expandObject(value: unknown): Record {\n if (typeof value === \"object\" && value !== null) {\n return Object.entries(value).reduce(\n (acc, [key, val]) => {\n if (typeof val === \"string\") {\n try {\n acc[key] = JSON.parse(val);\n } catch (e) {\n acc[key] = val;\n }\n } else {\n acc[key] = val;\n }\n return acc;\n },\n {} as Record,\n );\n }\n throw new Error(`Expected object but received ${typeof value}`);\n }\n\n static kabob(str: string) {\n if (!str) return \"\";\n return str.split(\"\").join(\"-\");\n }\n}\n","import { El } from \"@magik_io/mote\";\nimport consola from 'consola';\nimport { Tome } from \"../../class/Tome\";\nimport { TweenMax } from \"/scripts/greensock/esm/all.js\";\n\nexport class Toasted extends Tome {\n public maxMessagesOnScreen = 5;\n public alwaysShowNotifications = true;\n public fadeOutDelay = 3000;\n\n public menu: El<'div', true> | null = null;\n\n constructor(DEBUG = false) {\n super({\n moduleName: \"Toasted\",\n moduleDescription: \"A customizable toast notification system\",\n hooks: new Map([\n [\n \"renderChatLog\",\n async (app, html) => {\n try {\n if (document.body.classList.contains(\"stream\")) return;\n const div = new El<'div', true>(\n html[0]\n .querySelector(`#chat-log`)!\n .cloneNode(false) as unknown as `div#${string}`,\n )\n .addClass(this.moduleName)\n .id(this.lowercaseName)\n .on(\"click\", (ev) => this.handleMouseEvent(ev))\n .on(\"contextmenu\" as \"click\", (ev) => this.handleMouseEvent(ev));\n\n document.querySelector('body')?.appendChild(div.element);\n\n if (this.DEBUG) consola.success(`${this.moduleName} | Chat log rendered`);\n } catch (error) {\n\n }\n },\n ],\n [\n \"renderChatMessage\",\n async (_app, html, _options) => {\n this.addMessage(html[0].cloneNode(true) as ChildNode);\n }\n ]\n ]),\n socketFns: new Map([\n [\n \"module.toasted\",\n (data) => {\n if (this.alwaysShowNotifications) {\n ui.notifications?.info(data);\n return;\n }\n\n consola.info(data);\n\n // this.toasts.push(data);\n // if (this.toasts.length > this.maxMessagesOnScreen) this.toasts.shift();\n\n // const toast = ui.notifications?.info(data);\n // toast?.element.addEventListener(\"click\", () => {\n // this.toasts.shift();\n // toast.close();\n // });\n },\n ]\n ]),\n DEBUG\n });\n\n this.registerSettings([\n {\n name: \"Toast Duration\",\n hint: \"How long would you like a message to stay on screen?\",\n type: Number,\n defaultValue: this.fadeOutDelay,\n range: { min: 1000, max: 10000, step: 250 },\n scope: \"client\",\n restricted: false,\n onChange: (value) => {\n this.fadeOutDelay = Number(value);\n },\n },\n {\n name: \"Max Messages\",\n hint: \"How many messages would you like to see on screen (at most)?\",\n type: Number,\n defaultValue: this.maxMessagesOnScreen,\n range: { min: 1, max: 10, step: 1 },\n scope: \"client\",\n restricted: false,\n onChange: (value) => {\n this.maxMessagesOnScreen = Number(value);\n },\n },\n {\n name: \"Always Show Notifications\",\n hint: \"Would you prefer toast are shown even if the chat panel is open?\",\n type: Boolean,\n defaultValue: this.alwaysShowNotifications,\n scope: \"client\",\n restricted: false,\n onChange: (value) => {\n this.alwaysShowNotifications = Boolean(value);\n },\n },\n ]);\n }\n\n static expandSidebarInstant(sidebar: HTMLDivElement) {\n if (!sidebar) {\n throw new Error(\n \"[Toasted:expandSidebarInstant] -> Error: Sidebar element was not passed\",\n );\n }\n\n const sideB = new El<\"div\", true>(sidebar)\n .removeClass(\"collapsed\")\n .unset([\"width\", \"height\"]);\n ui.sidebar._collapsed = false;\n\n const icon = sideB.element.querySelector(\"#sidebar-tabs a.collapse i\") as HTMLDivElement;\n\n if (!icon) {\n throw new Error(\n \"[Toasted:expandSidebarInstant] -> Error: Icon element was not found\",\n );\n }\n\n new El(icon).removeClass(\"fa-caret-left\").addClass(\"fa-caret-right\");\n\n Hooks.callAll(\"sidebarCollapse\", ui.sidebar, ui.sidebar._collapsed);\n }\n\n static findTarget(\n card: HTMLDivElement,\n event: MouseEvent,\n messageID: string,\n ) {\n const cardRect = card.getBoundingClientRect();\n const popupRect = document\n .querySelector(`.${this.name}`)!\n .getBoundingClientRect();\n let x = event.clientX - popupRect.left + cardRect.left;\n let y = event.clientY - popupRect.top + cardRect.top;\n\n let target = document.elementFromPoint(x, y);\n let closestMessage = target?.closest(\".message\");\n let closestMessageID = new El(closestMessage as HTMLDivElement).data(\n \"messageId\",\n );\n\n if (target && closestMessageID === messageID) {\n return { target, x, y };\n }\n const targetRect = (event.target as HTMLElement).getBoundingClientRect();\n // If click element is obscured, rasterize the target and test if some point is free\n // doing 10 steps in each direction, with a minimum of 5 px is some arbitrary number chosen, \n // but i think its quite okay in regards of accuracy and performance\n const dx = Math.min(targetRect.width / 10, 5);\n const dy = Math.min(targetRect.height / 10, 5);\n for (let vert = targetRect.top + 1; vert < targetRect.bottom; vert += dy) {\n y = vert - popupRect.top + cardRect.top;\n for (let hor = targetRect.left + 1; hor < targetRect.right; hor += dx) {\n x = hor - popupRect.left + cardRect.left;\n target = document.elementFromPoint(x, y);\n closestMessage = target?.closest(\".message\");\n closestMessageID = new El(closestMessage as HTMLDivElement).data(\n \"messageId\",\n );\n\n if (target && closestMessageID === messageID) return { target, x, y };\n }\n }\n\n return { target: null, x, y };\n }\n\n protected delegateEvent(n: Node, ev: MouseEvent) {\n const node = new El(n as HTMLDivElement);\n const card = new El(`.${this.moduleName}`).element.querySelector(\n `[data-message-id=\"${node.data(\"messageId\")}\"]`,\n ) as HTMLDivElement;\n // Card not found? strange.. just return\n if (!card) return;\n card.scrollIntoView();\n // Get target element on \"real\" chat-card\n const { target, x, y } = Toasted.findTarget(\n card,\n ev,\n node.data(\"messageId\")!,\n );\n // If for some reason wrong one was found.. just do nothing\n if (!target) return;\n\n const event = new MouseEvent(ev.type, {\n bubbles: true,\n cancelable: true,\n shiftKey: ev.shiftKey,\n metaKey: ev.metaKey,\n ctrlKey: ev.ctrlKey,\n clientX: x,\n clientY: y,\n });\n\n consola.info({\n title: `${this.moduleName} | Delegating event to chat log`,\n data: {\n target, x, y, event,\n },\n })\n\n\n target.dispatchEvent(event);\n }\n\n protected handleMouseEvent(ev: MouseEvent) {\n const targetElement = ev.target as HTMLElement;\n const node = targetElement?.closest(\".message\");\n if (!node) return;\n // activate chat\n const tabBtn = document.getElementById(\"sidebar-tabs\")?.children[0];\n if (tabBtn && !tabBtn.classList.contains(\"active\")) {\n tabBtn.dispatchEvent(\n new MouseEvent(\"click\", { bubbles: true, cancelable: true }),\n );\n }\n\n const sidebar = tabBtn?.closest(\"#sidebar\");\n if (sidebar && sidebar?.classList.contains(\"collapsed\")) {\n Toasted.expandSidebarInstant(sidebar as HTMLDivElement);\n }\n this.delegateEvent(node, ev);\n node.remove();\n }\n\n protected addMessage(node: ChildNode) {\n if (!this.ready) return;\n const div = new El(`#${this.lowercaseName}`);\n if (!div) {\n if (this.DEBUG) {\n consola.error(`${this.moduleName} | Chat log not found`, { this: this, node, div });\n }\n throw new Error(\"Chat log not found\");\n }\n\n const { messageId } = (node as HTMLElement).dataset;\n if (!messageId) throw new Error(\"Message ID not found\");\n\n const oldNode = div.element\n .querySelector(`[data-message-id=\"${messageId}\"]`);\n if (oldNode) return this.updateMessage(node, oldNode);\n if (div.children.length >= this.maxMessagesOnScreen) {\n div.element.firstElementChild?.remove();\n }\n\n div.child(node as HTMLDivElement, \"append\");\n TweenMax.from(node, 0.3, {\n height: 0,\n onComplete: () => {\n (node as HTMLDivElement).style.height = \"\"\n if (this.DEBUG) consola.success(`${this.moduleName} | Toasted message ${messageId}`);\n\n setTimeout(() => {\n this.removeMessage(node);\n }, this.fadeOutDelay);\n },\n });\n }\n\n protected removeMessage(node: ChildNode, { time = 0.3, delay = this.fadeOutDelay } = {}) {\n if (this.fadeOutDelay < 0) return;\n\n TweenMax.to(node, time, {\n opacity: 0,\n height: 0,\n delay,\n onComplete: () => { node.remove(); },\n });\n }\n\n protected updateMessage(newNode: ChildNode, oldNode: Node) {\n oldNode.parentNode?.replaceChild(newNode, oldNode);\n this.removeMessage(newNode);\n }\n}\n","import type { FontLoader, Font, CustomFamilies, ParsedFont, CustomFamily } from './types';\n\nexport class CustomLoader implements FontLoader {\n private readonly fonts_: Font[];\n private readonly uris_: string[];\n\n constructor(config: CustomFamilies) {\n this.fonts_ = [];\n this.uris_ = config.urls || [];\n this.parseFamilyConfig_(config.families);\n }\n\n /**\n * Returns parsed uris strings\n */\n getUris(): string[] {\n return this.uris_ || [];\n }\n\n /**\n * Return all font's that should be loaded\n */\n getFonts(): Font[] {\n return this.fonts_;\n }\n\n /**\n * Returns font object array\n */\n getParsedFonts(): ParsedFont[] {\n // TODO: implement with native font loader\n return [];\n }\n\n /**\n * Parsing config to separate string and object families\n * @param families\n * @private\n */\n private parseFamilyConfig_(families: (string | CustomFamily)[]): void {\n families.forEach((family) => {\n if (typeof family !== 'string') {\n this.fonts_.push({ family: family.name, variation: 'n4' });\n this.uris_?.push(family.url);\n } else {\n const font = family.split(':');\n const fontName = font[0];\n let fontVariants = font[1]?.split(',');\n if (!fontVariants || fontVariants.length < 1) {\n fontVariants = ['n4'];\n }\n fontVariants.forEach((fontVariant) => {\n this.fonts_.push({\n family: fontName,\n variation: fontVariant,\n });\n });\n }\n });\n }\n}\n","import type { ParsedFont } from '../types';\n\nexport class CssParser {\n private css_: string;\n private rules_: ParsedFont[] = [];\n\n constructor(fontFaceResponseText: string) {\n this.css_ = fontFaceResponseText;\n }\n\n /**\n * Returns ParsedFont array of parsed CSS\n */\n public getParsedFonts(): ParsedFont[] {\n return this.rules_;\n }\n\n /**\n * Parses CSS into array of ParsedFont object\n */\n public parseCSS() {\n this.css_ = this.removeNewLines_(this.css_);\n const blocks = this.css_.split('}');\n blocks.pop();\n blocks.forEach((block) => {\n const pair = block.split('{');\n const parsed = this.parseCSSBlock_(pair[1]);\n\n this.rules_.push({\n fontFamily: parsed['font-family'],\n fontStyle: parsed['font-style'],\n fontWeight: parsed['font-weight'],\n src: parsed.src,\n unicodeRange: parsed['font-range'],\n });\n });\n }\n\n /**\n * Parsing css block\n * @param css\n * @private\n */\n private parseCSSBlock_(css: string): {\n 'font-family': string;\n 'font-style': string;\n 'font-weight': string;\n src: string;\n 'font-range': string;\n } {\n const rule: any = {};\n const declarations = css.split(';');\n declarations.pop();\n declarations.forEach((declaration) => {\n const loc = declaration.indexOf(':');\n const property = declaration.substring(0, loc).trim();\n let value = declaration.substring(loc + 1).trim();\n if (value[0] === \"'\" && value[value.length - 1] === \"'\") {\n value = value.replace(/'/g, '');\n }\n\n if (property != '' && value != '') rule[property] = value;\n });\n return rule;\n }\n\n /**\n * Removes all empty lines from CSS\n * @param css\n * @private\n */\n private removeNewLines_(css: string) {\n return css.replace(/\\n/g, '');\n }\n}\n","/** Source: https://github.com/typekit/webfontloader/blob/master/src/modules/google/fontapiparser.js */\n\nimport type { Font } from '../types';\n\n\nexport class FontParser {\n private fontFamilies: string[];\n private parsedFonts: Font[];\n private fontTestStrings: Record;\n\n private INT_FONTS = {\n latin: 'BESbswy',\n 'latin-ext': '\\u00E7\\u00F6\\u00FC\\u011F\\u015F',\n cyrillic: '\\u0439\\u044f\\u0416',\n greek: '\\u03b1\\u03b2\\u03a3',\n khmer: '\\u1780\\u1781\\u1782',\n Hanuman: '\\u1780\\u1781\\u1782', // For backward compatibility\n };\n private WEIGHTS = {\n thin: '1',\n extralight: '2',\n 'extra-light': '2',\n ultralight: '2',\n 'ultra-light': '2',\n light: '3',\n regular: '4',\n book: '4',\n medium: '5',\n 'semi-bold': '6',\n semibold: '6',\n 'demi-bold': '6',\n demibold: '6',\n bold: '7',\n 'extra-bold': '8',\n extrabold: '8',\n 'ultra-bold': '8',\n ultrabold: '8',\n black: '9',\n heavy: '9',\n l: '3',\n r: '4',\n b: '7',\n };\n private STYLES = {\n i: 'i',\n italic: 'i',\n n: 'n',\n normal: 'n',\n };\n private VARIATION_MATCH = new RegExp(\n '^(thin|(?:(?:extra|ultra)-?)?light|regular|book|medium|' +\n '(?:(?:semi|demi|extra|ultra)-?)?bold|black|heavy|l|r|b|[1-9]00)?(n|i' +\n '|normal|italic)?$'\n );\n\n constructor(fontFamilies: string[]) {\n this.fontFamilies = fontFamilies;\n this.parsedFonts = [];\n this.fontTestStrings = {};\n }\n\n public parse(): void {\n for (const fontFamilyString of this.fontFamilies) {\n const elements = fontFamilyString.split(':');\n const fontFamily = elements[0].replace(/\\+/g, ' ');\n let variations = ['n4'];\n\n if (elements.length >= 2) {\n const fvds = this.parseVariations(elements[1]);\n if (fvds.length > 0) {\n variations = fvds;\n }\n if (elements.length === 3) {\n const subsets = this.parseSubsets(elements[2]);\n if (subsets.length > 0) {\n const fontTestString = this.INT_FONTS[subsets[0] as keyof typeof this.INT_FONTS];\n if (fontTestString) {\n this.fontTestStrings[fontFamily] = fontTestString;\n }\n }\n }\n }\n\n // For backward compatibility\n if (!this.fontTestStrings[fontFamily]) {\n const hanumanTestString = this.INT_FONTS[fontFamily as keyof typeof this.INT_FONTS];\n if (hanumanTestString) {\n this.fontTestStrings[fontFamily] = hanumanTestString;\n }\n }\n\n for (const variation of variations) {\n this.parsedFonts.push({\n family: fontFamily,\n variation,\n });\n }\n }\n }\n\n private generateFontVariationDescription(variation: string) {\n if (!variation.match(/^[\\w-]+$/)) {\n return '';\n }\n const normalizedVariation = variation.toLowerCase();\n const groups = this.VARIATION_MATCH.exec(normalizedVariation);\n if (groups == null) {\n return '';\n }\n const styleMatch = this.normalizeStyle(groups[2] as keyof typeof this.STYLES);\n const weightMatch = this.normalizeWeight(groups[1] as keyof typeof this.WEIGHTS);\n return [styleMatch, weightMatch].join('');\n }\n\n private normalizeStyle(parsedStyle: keyof typeof this.STYLES | '' | null) {\n if (parsedStyle == null || parsedStyle == '') {\n return 'n';\n }\n return this.STYLES[parsedStyle];\n }\n\n private normalizeWeight(parsedWeight?: keyof typeof this.WEIGHTS | '' | number) {\n if (parsedWeight == null || parsedWeight == '') {\n return '4';\n }\n if (typeof parsedWeight === 'string') {\n const weight = this.WEIGHTS[parsedWeight];\n if (weight) {\n return weight;\n }\n }\n if (typeof parsedWeight === 'number') {\n if (isNaN(parsedWeight)) {\n return '4';\n }\n\n }\n return parsedWeight.toString().substr(0, 1);\n }\n\n private parseVariations(variations: string) {\n const finalVariations: string[] = [];\n\n if (!variations) {\n return finalVariations;\n }\n const providedVariations = variations.split(',');\n const length = providedVariations.length;\n\n for (let i = 0; i < length; i++) {\n const variation = providedVariations[i];\n const fvd = this.generateFontVariationDescription(variation);\n\n if (fvd) {\n finalVariations.push(fvd);\n }\n }\n return finalVariations;\n }\n\n public parseSubsets(subsets: T): T[] {\n const finalSubsets: T[] = [];\n\n if (!subsets) {\n return finalSubsets;\n }\n return subsets.split(',') as T[];\n }\n\n public getFonts() {\n return this.parsedFonts;\n }\n\n public getFontTestStrings() {\n return this.fontTestStrings;\n }\n}\n","import type { FontLoader, FontFamilies, Font, ParsedFont } from './types';\nimport { CssParser } from './utils/CSSParser';\nimport { FontParser } from './utils/FontParser';\n\nexport class GoogleFontApi {\n private apiUrl_ = 'https://fonts.googleapis.com/css';\n // TODO: implement google v2 api query\n // private apiUrlV2_ = 'https://fonts.googleapis.com/css2';\n private fonts_: string[];\n private version_: 1 | 2;\n\n /**\n * @param fonts\n * @param version\n */\n constructor(fonts: string[], version: 1 | 2 = 1) {\n this.fonts_ = fonts;\n this.version_ = version;\n }\n\n /**\n * Builds font googleapis url from given fonts in constructor\n * @return string\n */\n public buildUri(): string {\n const fontApiParser = new FontParser(this.fonts_);\n fontApiParser.parse();\n const request = fontApiParser.getFonts().map((font) => {\n const fontString = `${font.family}:${font.variation}`;\n return fontString.replace(/\\s/g, '+');\n });\n const requestString: string = request.join('|');\n return `${this.apiUrl_}?family=${requestString}`;\n }\n}\n\nexport class GoogleLoader implements FontLoader {\n private fonts_: FontFamilies;\n private uri_: string | undefined;\n\n constructor(fonts: FontFamilies) {\n this.fonts_ = fonts;\n this.generateUri_();\n }\n\n /**\n * Returns google uri to get all the fonts\n */\n public getUris(): string[] {\n return this.uri_ ? [this.uri_] : [];\n }\n\n /**\n * Return all google font's that should be loaded\n */\n public getFonts(): Font[] {\n const fontApiParser = new FontParser(this.fonts_.families);\n fontApiParser.parse();\n return fontApiParser.getFonts();\n }\n\n /**\n * Returns ParsedFont array for native font loading\n */\n public async getParsedFonts(): Promise {\n if (!this.uri_) {\n throw new Error('No uri provided. Nothing to parse.');\n }\n const fontResponse = await fetch(this.uri_).then((response) => response.text());\n const cssParser = new CssParser(fontResponse);\n cssParser.parseCSS();\n return cssParser.getParsedFonts();\n }\n\n /**\n * Generates google font api url from given array of fonts\n */\n private generateUri_(): void {\n const googleFontApi = new GoogleFontApi(this.fonts_.families);\n this.uri_ = googleFontApi.buildUri();\n }\n}\n","import type { Font, LoadingMethod } from '../types';\nimport { FontEvents } from './EventBus';\n\nexport class FontWatcher {\n private font_: Font;\n private load_: LoadingMethod;\n\n constructor(font: Font, load: LoadingMethod) {\n this.font_ = font;\n this.load_ = load;\n\n this.loading_();\n }\n\n private loading_() {\n document.dispatchEvent(\n new CustomEvent(FontEvents.FONT_LOADING, { detail: `${this.font_.family}:${this.font_.variation}` })\n );\n }\n\n public getFont(): Font {\n return this.font_;\n }\n\n public watch(): boolean {\n return document.fonts.check(`16px ${this.font_.family}`, 'BESbswy');\n }\n}\n","import type { Font, LoadingMethod } from '../types';\nimport { FontEvents } from './EventBus';\nimport { FontWatcher } from './FontWatcher';\n\nexport class Watcher {\n private fontWatchers_: FontWatcher[] = [];\n private loadedFonts_: string[] = [];\n private watched_ = false;\n\n public add(font: Font, load: LoadingMethod) {\n this.fontWatchers_.push(new FontWatcher(font, load));\n }\n\n public fontLoaded(fontName: string) {\n this.loadedFonts_.push(fontName);\n }\n\n public watchFonts() {\n if (!this.watched_) {\n this.watched_ = true;\n let atLeastOneLoaded = false;\n this.fontWatchers_.forEach((fontWatcher) => {\n const font = fontWatcher.getFont();\n const loaded = this.loadedFonts_.includes(font.family) || fontWatcher.watch();\n if (loaded) {\n atLeastOneLoaded = true;\n }\n document.dispatchEvent(\n new CustomEvent(loaded ? FontEvents.FONT_ACTIVE : FontEvents.FONT_INACTIVE, {\n detail: `${font.family}:${font.variation}`,\n })\n );\n });\n document.dispatchEvent(new CustomEvent(atLeastOneLoaded ? FontEvents.ACTIVE : FontEvents.INACTIVE, {}));\n }\n }\n}\n","import { CustomLoader } from './CustomLoader';\nimport { GoogleLoader } from './GoogleLoader';\nimport type { FontsLoaderDefaultConfig, FontsLoaderConfig, ParsedFont } from './types';\nimport { EventBus, FontEvents } from './utils/EventBus';\nimport { Watcher } from './utils/Watcher';\n\nconst DEFAULT_CONFIG: FontsLoaderDefaultConfig = {\n events: false,\n classes: false,\n timeout: 3000,\n};\n\n/**\n * Main function that loads all the fonts to tag\n * @param fontsLoaderConfig\n */\nexport const FontsLoader = async (fontsLoaderConfig: FontsLoaderConfig): Promise => {\n const config = {\n ...DEFAULT_CONFIG,\n ...fontsLoaderConfig,\n };\n const watcher = new Watcher();\n if (config.classes || config.events) {\n new EventBus(config);\n }\n if (config.google) {\n const googleLoader = new GoogleLoader(config.google);\n if (config.google.load === 'native') {\n await loadFontToBrowser_(await googleLoader.getParsedFonts());\n } else {\n googleLoader.getUris().forEach(addLinkElement_);\n }\n googleLoader.getFonts().forEach((font) => {\n watcher.add(font, config.google?.load || 'link');\n });\n }\n if (config.custom) {\n if (config.custom.load === 'native') {\n // TODO: implement native loader\n throw new Error('Native load is not implemented for custom fonts.');\n }\n const customLoader = new CustomLoader(config.custom);\n customLoader.getUris().forEach(addLinkElement_);\n customLoader.getFonts().forEach((font) => {\n watcher.add(font, 'link');\n });\n }\n if (config.classes || config.events) {\n document.dispatchEvent(new CustomEvent(FontEvents.LOADING, {}));\n document.fonts.onloadingdone = (event: Event) => {\n (event as FontFaceSetLoadEvent).fontfaces.forEach(async fontFace => {\n if (fontFace.status === 'loaded') {\n watcher.fontLoaded(fontFace.family);\n }\n });\n watcher.watchFonts();\n };\n setTimeout(() => {\n watcher.watchFonts();\n }, config.timeout);\n }\n};\n\n/**\n * Native fonts to browser insert\n * @param fonts\n */\nconst loadFontToBrowser_ = async (fonts: ParsedFont[]): Promise => {\n for (const font of fonts) {\n const fontFace = new FontFace(font.fontFamily, font.src, {\n style: font.fontStyle,\n unicodeRange: font.unicodeRange,\n weight: font.fontWeight,\n });\n await fontFace.load();\n document.fonts.add(fontFace);\n }\n};\n\n/**\n * Creates new with given href and async if needed\n * @param href\n */\nconst addLinkElement_ = (href: string): void => {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = href;\n link.media = 'all';\n document.head.appendChild(link);\n};\n","import { Tome } from 'src/class/Tome';\nimport { FontsLoader } from 'src/modules/fontLoader/FontLoader';\n\nexport class Narrator extends Tome {\n public static fonts = [\n \"Caslon\",\n \"CaslonAntique\",\n \"SignikaBold\",\n \"Riffic\",\n \"IronSans\",\n \"LinLibertine\",\n \"TimesNewRomance\",\n \"TimesNewYorker\",\n \"LPEducational\",\n \"Cardinal\",\n \"OldLondon\",\n \"StoneHenge\",\n \"SunnyDay\",\n \"PaulSignature\",\n \"LemonTuesday\",\n \"FairProsper\",\n \"BalletHarmony\",\n \"MagieraScript\",\n \"Cathallina\",\n \"Hamish\",\n \"DreamersBrush\",\n \"FastInMyCar\",\n \"ChildWriting\",\n \"Kindergarten\",\n \"FuturaHandwritten\",\n \"Fewriter\",\n \"TrashHand\",\n \"GoodBrush\",\n \"BaksoSapi\",\n \"SuplexmentaryComic\",\n \"ComicInk\",\n \"DreamyLand\",\n \"Yikes\",\n \"GangOfThree\",\n \"JianGkrik\",\n \"Yozakura\",\n \"Hiroshio\",\n \"ArabDances\",\n \"Rooters\",\n \"Subway\",\n \"Himagsikan\",\n \"MilTown\",\n \"Galactico\",\n \"Oko\",\n \"Ethnocentric\",\n \"VenusRising\",\n \"StampAct\",\n \"Kirsty\",\n \"Western\",\n \"BreakAway\",\n \"YoungerThanMe\",\n \"Underground\",\n \"VarsityTeam\",\n \"Valentino\",\n \"GlassHouses\",\n \"Makayla\",\n \"DancingVampyrish\",\n \"Codex\",\n \"DSNetStamped\",\n \"HappyFrushZero\",\n \"Shoplifter\",\n \"Stereofidelic\",\n \"Headache\",\n \"HorrorHouse\",\n \"GhostTheory2\",\n \"Syemox\",\n \"GhostChase\"\n ] as const;\n public static fontWeights = [\n \"100\",\n \"200\",\n \"300\",\n \"400\",\n \"500\",\n \"600\",\n \"700\",\n \"800\",\n \"900\"\n ] as const;\n public static fontStyles = [\n \"normal\",\n \"italic\",\n \"oblique\"\n ] as const;\n\n public get titleFont() {\n return this.getSetting(\"Title Font\") ?? \"GhostTheory2\";\n }\n public static get titleFont() {\n return game.settings?.get('wonderlost', 'narrator-title-font') as typeof Narrator['fonts'][number]\n ?? \"GhostTheory2\" as typeof Narrator['fonts'][number];\n }\n public static set titleFont(value: typeof Narrator['fonts'][number]) {\n game.settings?.set('wonderlost', 'narrator-title-font', value);\n }\n\n public get textFont() {\n return this.getSetting(\"Text Font\") ?? \"GhostTheory2\";\n }\n public static get textFont() {\n return game.settings?.get('wonderlost', 'narrator-text-font') as typeof Narrator['fonts'][number]\n ?? \"GhostTheory2\";\n }\n public static set textFont(value: typeof Narrator['fonts'][number]) {\n game.settings?.set('wonderlost', 'narrator-text-font', value);\n }\n\n public get titleWeight() {\n return this.getSetting(\"Title Weight\") ?? \"400\";\n }\n public static get titleWeight() {\n return game.settings?.get('wonderlost', 'narrator-title-weight') as typeof Narrator['fontWeights'][number]\n ?? \"400\";\n }\n public static set titleWeight(value: typeof Narrator['fontWeights'][number]) {\n game.settings?.set('wonderlost', 'narrator-title-weight', value);\n }\n\n constructor(DEBUG = false) {\n super({\n moduleName: \"Narrator\",\n moduleDescription: \"An extremely customizable on screen narrator system\",\n settings: {\n globalSettings: [\n {\n name: \"Title Font\",\n hint: \"The font used for the title text\",\n type: String,\n defaultValue: \"GhostTheory2\",\n choices: Object.fromEntries(Narrator.fonts.map((font) => [font, font])),\n onChange: (value) => {\n Narrator.titleFont = value as typeof Narrator['fonts'][number];\n }\n },\n {\n name: \"Text Font\",\n hint: \"The font used for the text body\",\n type: String,\n defaultValue: \"GhostTheory2\",\n choices: Object.fromEntries(Narrator.fonts.map((font) => [font, font])),\n onChange: (value) => {\n Narrator.textFont = value as typeof Narrator['fonts'][number];\n }\n },\n {\n name: \"Title Weight\",\n hint: \"The weight of the title font\",\n type: String,\n defaultValue: \"400\",\n choices: Object.fromEntries(Narrator.fontWeights.map((weight) => [weight, weight])),\n onChange: (value) => {\n Narrator.titleWeight = value as typeof Narrator['fontWeights'][number];\n }\n }\n ]\n },\n hooks: new Map([\n ['ready', (app, data) => {\n // Load some essential fonts we use in PIXI\n FontsLoader({\n custom: {\n families: [Narrator.titleFont, Narrator.textFont],\n },\n });\n // async load everything else\n let oFonts = [];\n for (let idx = Narrator.fonts.length - 1; idx >= 0; --idx) {\n if (Narrator.fonts[idx] === Narrator.titleFont || Narrator.fonts[idx] === Narrator.textFont) {\n continue;\n }\n oFonts.push(Narrator.fonts[idx]);\n }\n const aLoader = async function (fonts: string[]) {\n FontsLoader({\n custom: {\n families: fonts,\n },\n });\n };\n\n aLoader(oFonts);\n }]\n ]),\n socketFns: new Map([]),\n DEBUG\n })\n }\n}\n","import consola from 'consola';\nimport { Toasted } from \"./submodules/toasted/Toasted\";\nimport { Narrator } from './submodules/narrator/Narrator';\n\ntype ToastedTuple = ['Toasted', Toasted];\ntype NarratorTuple = ['Narrator', Narrator];\n\nclass Wonderlost {\n public tomes = new Map<'Toasted' | 'Narrator', Toasted | Narrator>([\n ['Toasted', new Toasted()] as ToastedTuple,\n ['Narrator', new Narrator()] as NarratorTuple,\n ])\n\n constructor(public DEBUG = false) {\n consola.info(\"Wonderlost | Initialized\", this);\n }\n\n initializeTomes() {\n for (const [tomeName, tome] of this.tomes) {\n tome.initialize();\n\n if (this.DEBUG) {\n consola.info(`Wonderlost | Initialized ${tomeName}`, tome);\n }\n }\n }\n}\n\nHooks.once(\"init\", async function () {\n consola.start(\"Wonderlost | Initialized\");\n new Wonderlost(true).initializeTomes();\n consola.success(\"Wonderlost | Ready\");\n});\n\nHooks.once(\"ready\", async function () { });\n\n"],"names":["LogLevels","silent","Number","NEGATIVE_INFINITY","fatal","error","warn","log","info","success","fail","ready","start","box","debug","trace","verbose","POSITIVE_INFINITY","LogTypes","level","isObject","value","_defu","baseObject","defaults","namespace","merger","object","Object","assign","key","Array","isArray","toString","defu","arguments_","reduce","p","c","isLogObj","arg","obj","prototype","call","message","args","stack","paused","queue","Consola","constructor","options","types","this","_normalizeLogLevel","reporters","throttle","throttleMin","formatOptions","date","colors","compact","type","_wrapLogFn","raw","mockFn","mockTypes","_lastLog","prompt","opts","Error","create","instance","_mockFn","withDefaults","withTag","tag","addReporter","reporter","push","removeReporter","i","indexOf","splice","setReporters","wrapAll","wrapConsole","wrapStd","restoreAll","restoreConsole","restoreStd","console","_wrapStream","stdout","stderr","stream","__write","write","data","String","trim","_restoreStream","pauseLogs","resumeLogs","_queue","item","_logFn","isRaw","logObj","Date","length","unshift","additional","split","join","toLowerCase","resolveLog","newLog","repeated","count","args2","_log","clearTimeout","timeout","diffTime","time","getTime","serializedLog","JSON","stringify","isSameLog","serialized","setTimeout","input","defaultLevel","add","remove","clear","withScope","mock","pause","resume","BrowserReporter","defaultColor","levelColorMap","typeColorMap","_getLogFn","__error","__warn","__log","consoleLogFn","style","badge","filter","Boolean","slice","consola","createConsola$1","options2","Promise","resolve","confirm","createConsola","FontEvents","__defProp","defineProperty","__publicField","enumerable","configurable","writable","__defNormalProp","isAElement","selector","HTMLElement","El","element","t","element2","document","querySelector","self","toggleClass","className","includes","forEach","classList","toggle","addClass","singleClass","removeClass","hasClass","contains","replaceWith","string","outerHTML","replaceWithElement","tagName","idForNewElement","newEl","createElement","id","parentNode","replaceChild","html","innerHTML","empty","check","trueOrFalse","HTMLInputElement","checked","TypeError","click","dispatchEvent","MouseEvent","view","window","bubbles","cancelable","expression","wrap","classForDiv","wrapper","insertBefore","removeChild","appendChild","src","srcString","HTMLImageElement","alt","altString","parent","parentElement","unset","properties","removeAttribute","set","setObj","entries","setAttribute","firstChild","firstElementChild","child","insertAt","insertAdjacentHTML","append","prepend","children","childNodes","text","txt","textContent","content","textChild","s","textEl","createTextNode","_type","name","_name","htmlFor","elementTheLabelIsFor","idForEl","val","newVal","HTMLSelectElement","HTMLTextAreaElement","HTMLOptionElement","HTMLProgressElement","getFullYear","getMonth","getDate","dataSuffix","getAttribute","dataset","on","event","listener","addEventListener","once","eventName","eventHandler","now","detail","CustomEvent","off","removeEventListener","trigger","triggerChange","createEvent","initEvent","find","querySelectorAll","Event","nestFrom","cb","Tome","moduleName","moduleDescription","settings","hooks","Map","socketFns","DEBUG","lowercaseName","hasHooks","size","hasSettings","hasSocketFns","needsEarlyInitialization","has","pTome","globalSettings","map","scope","clientSettings","addHook","callback","overwrite","initializeHooks","title","Hooks","registerSetting","rule","Color","registerSettings","rules","initializeSettings","setting","game","register","kabob","hint","config","default","defaultValue","choices","range","onChange","requiresReload","getSetting","settingName","get","setSetting","registerSettingSubmenu","menu","registerMenu","label","icon","restricted","FormApplication","super","defaultOptions","foundry","utils","mergeObject","width","height","popOut","closeOnSubmit","template","getData","isEmpty","_updateObject","_event","formData","initializeSocketListeners","fn","socket","initialize","expandObject","acc","parse","e","str","Toasted","maxMessagesOnScreen","alwaysShowNotifications","fadeOutDelay","async","app","body","div","cloneNode","ev","handleMouseEvent","_app","_options","addMessage","ui","notifications","min","max","step","expandSidebarInstant","sidebar","sideB","_collapsed","callAll","findTarget","card","messageID","cardRect","getBoundingClientRect","popupRect","x","clientX","left","y","clientY","top","target","elementFromPoint","closestMessage","closest","closestMessageID","targetRect","dx","Math","dy","vert","bottom","hor","right","delegateEvent","n","node","scrollIntoView","shiftKey","metaKey","ctrlKey","targetElement","tabBtn","getElementById","messageId","oldNode","updateMessage","TweenMax","from","onComplete","removeMessage","delay","to","opacity","newNode","CustomLoader","fonts_","uris_","urls","parseFamilyConfig_","families","getUris","getFonts","getParsedFonts","family","variation","url","font","fontName","fontVariants","fontVariant","CssParser","css_","rules_","fontFaceResponseText","parseCSS","removeNewLines_","blocks","pop","block","pair","parsed","parseCSSBlock_","fontFamily","fontStyle","fontWeight","unicodeRange","css","declarations","declaration","loc","property","substring","replace","FontParser","fontFamilies","parsedFonts","fontTestStrings","INT_FONTS","latin","cyrillic","greek","khmer","Hanuman","WEIGHTS","thin","extralight","ultralight","light","regular","book","medium","semibold","demibold","bold","extrabold","ultrabold","black","heavy","l","r","b","STYLES","italic","normal","VARIATION_MATCH","RegExp","fontFamilyString","elements","variations","fvds","parseVariations","subsets","parseSubsets","fontTestString","hanumanTestString","generateFontVariationDescription","match","normalizedVariation","groups","exec","normalizeStyle","normalizeWeight","parsedStyle","parsedWeight","weight","isNaN","substr","finalVariations","providedVariations","fvd","finalSubsets","getFontTestStrings","GoogleFontApi","apiUrl_","version_","fonts","version","buildUri","fontApiParser","requestString","GoogleLoader","uri_","generateUri_","fontResponse","fetch","then","response","cssParser","googleFontApi","EventBus","namespace_","classSeparator_","event_","config_","htmlElement_","documentElement","LOADING","handleLoading_","ACTIVE","handleActive_","INACTIVE","handleInactive_","FONT_LOADING","handleFontLoading_","FONT_ACTIVE","handleFontActive_","FONT_INACTIVE","handleFontInactive_","events","loading","addClassToHtml_","removeClassFromHtml_","active","inactive","fontloading","fontArray","fontactive","fontinactive","prefix","concat","sanitizeClassName_","FontWatcher","font_","load_","load","loading_","getFont","watch","Watcher","fontWatchers_","loadedFonts_","watched_","fontLoaded","watchFonts","atLeastOneLoaded","fontWatcher","loaded","DEFAULT_CONFIG","classes","FontsLoader","fontsLoaderConfig","watcher","google","googleLoader","loadFontToBrowser_","addLinkElement_","custom","customLoader","onloadingdone","fontfaces","fontFace","status","FontFace","href","link","rel","media","head","Narrator","static","titleFont","textFont","titleWeight","fromEntries","fontWeights","oFonts","idx","aLoader","Wonderlost","tomes","initializeTomes","tomeName","tome"],"mappings":"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","x_google_ignoreList":[0,1,2]} \ No newline at end of file diff --git a/src/class/Tome.ts b/src/class/Tome.ts index c53cb21..6a35b44 100644 --- a/src/class/Tome.ts +++ b/src/class/Tome.ts @@ -3,7 +3,9 @@ import type ApplicationV2 from 'src/types/foundry/client-esm/applications/api/ap import type { DataModel } from "src/types/foundry/common/abstract/module.mjs"; import type { MaybePromise } from 'src/types/types/utils.mjs'; -type HookableEvents = "renderChatLog" | "renderChatMessage"; +type CoreLifeCycleHooks = 'init' | 'ready' | 'error' | 'setup' | 'i18nInit' + +type HookableEvents = "renderChatLog" | "renderChatMessage" | 'renderApplication' | CoreLifeCycleHooks type HookEvent = ( app: Application, html: JQuery, @@ -26,6 +28,7 @@ interface Rule { * @comment false if you dont want it to show in module config */ config?: boolean; + choices?: Record; } // Define rule-specific types @@ -77,6 +80,24 @@ export abstract class Tome { return this.moduleName.toLowerCase(); } + get hasHooks() { + return this.hooks.size > 0; + } + + get hasSettings() { + return this.settings.length > 0; + } + + get hasSocketFns() { + return this.socketFns.size > 0; + } + + get needsEarlyInitialization() { + return (this.hasSettings + || (this.hasHooks && this.hooks.has('init') || this.hasHooks && this.hooks.has('ready')) + || this.hasSocketFns) + } + constructor( pTome: Pick & { settings?: TomeRuleConstructor; @@ -286,12 +307,19 @@ export abstract class Tome { } public initialize() { - this.initializeSettings() - .initializeHooks() - .initializeSocketListeners(); + if (this.hasSettings) { + this.initializeSettings() + } - this.ready = true; + if (this.hasHooks) { + this.initializeHooks(); + } + if (this.hasSocketFns) { + this.initializeSocketListeners(); + } + + this.ready = true; return this; } diff --git a/src/modules/fontLoader/CustomLoader.ts b/src/modules/fontLoader/CustomLoader.ts new file mode 100644 index 0000000..70027eb --- /dev/null +++ b/src/modules/fontLoader/CustomLoader.ts @@ -0,0 +1,61 @@ +import type { FontLoader, Font, CustomFamilies, ParsedFont, CustomFamily } from './types'; + +export class CustomLoader implements FontLoader { + private readonly fonts_: Font[]; + private readonly uris_: string[]; + + constructor(config: CustomFamilies) { + this.fonts_ = []; + this.uris_ = config.urls || []; + this.parseFamilyConfig_(config.families); + } + + /** + * Returns parsed uris strings + */ + getUris(): string[] { + return this.uris_ || []; + } + + /** + * Return all font's that should be loaded + */ + getFonts(): Font[] { + return this.fonts_; + } + + /** + * Returns font object array + */ + getParsedFonts(): ParsedFont[] { + // TODO: implement with native font loader + return []; + } + + /** + * Parsing config to separate string and object families + * @param families + * @private + */ + private parseFamilyConfig_(families: (string | CustomFamily)[]): void { + families.forEach((family) => { + if (typeof family !== 'string') { + this.fonts_.push({ family: family.name, variation: 'n4' }); + this.uris_?.push(family.url); + } else { + const font = family.split(':'); + const fontName = font[0]; + let fontVariants = font[1]?.split(','); + if (!fontVariants || fontVariants.length < 1) { + fontVariants = ['n4']; + } + fontVariants.forEach((fontVariant) => { + this.fonts_.push({ + family: fontName, + variation: fontVariant, + }); + }); + } + }); + } +} diff --git a/src/modules/fontLoader/FontLoader.ts b/src/modules/fontLoader/FontLoader.ts new file mode 100644 index 0000000..137e1e7 --- /dev/null +++ b/src/modules/fontLoader/FontLoader.ts @@ -0,0 +1,90 @@ +import { CustomLoader } from './CustomLoader'; +import { GoogleLoader } from './GoogleLoader'; +import type { FontsLoaderDefaultConfig, FontsLoaderConfig, ParsedFont } from './types'; +import { EventBus, FontEvents } from './utils/EventBus'; +import { Watcher } from './utils/Watcher'; + +const DEFAULT_CONFIG: FontsLoaderDefaultConfig = { + events: false, + classes: false, + timeout: 3000, +}; + +/** + * Main function that loads all the fonts to tag + * @param fontsLoaderConfig + */ +export const FontsLoader = async (fontsLoaderConfig: FontsLoaderConfig): Promise => { + const config = { + ...DEFAULT_CONFIG, + ...fontsLoaderConfig, + }; + const watcher = new Watcher(); + if (config.classes || config.events) { + new EventBus(config); + } + if (config.google) { + const googleLoader = new GoogleLoader(config.google); + if (config.google.load === 'native') { + await loadFontToBrowser_(await googleLoader.getParsedFonts()); + } else { + googleLoader.getUris().forEach(addLinkElement_); + } + googleLoader.getFonts().forEach((font) => { + watcher.add(font, config.google?.load || 'link'); + }); + } + if (config.custom) { + if (config.custom.load === 'native') { + // TODO: implement native loader + throw new Error('Native load is not implemented for custom fonts.'); + } + const customLoader = new CustomLoader(config.custom); + customLoader.getUris().forEach(addLinkElement_); + customLoader.getFonts().forEach((font) => { + watcher.add(font, 'link'); + }); + } + if (config.classes || config.events) { + document.dispatchEvent(new CustomEvent(FontEvents.LOADING, {})); + document.fonts.onloadingdone = (event: Event) => { + (event as FontFaceSetLoadEvent).fontfaces.forEach(async fontFace => { + if (fontFace.status === 'loaded') { + watcher.fontLoaded(fontFace.family); + } + }); + watcher.watchFonts(); + }; + setTimeout(() => { + watcher.watchFonts(); + }, config.timeout); + } +}; + +/** + * Native fonts to browser insert + * @param fonts + */ +const loadFontToBrowser_ = async (fonts: ParsedFont[]): Promise => { + for (const font of fonts) { + const fontFace = new FontFace(font.fontFamily, font.src, { + style: font.fontStyle, + unicodeRange: font.unicodeRange, + weight: font.fontWeight, + }); + await fontFace.load(); + document.fonts.add(fontFace); + } +}; + +/** + * Creates new with given href and async if needed + * @param href + */ +const addLinkElement_ = (href: string): void => { + const link = document.createElement('link'); + link.rel = 'stylesheet'; + link.href = href; + link.media = 'all'; + document.head.appendChild(link); +}; diff --git a/src/modules/fontLoader/GoogleLoader.ts b/src/modules/fontLoader/GoogleLoader.ts new file mode 100644 index 0000000..0d71812 --- /dev/null +++ b/src/modules/fontLoader/GoogleLoader.ts @@ -0,0 +1,82 @@ +import type { FontLoader, FontFamilies, Font, ParsedFont } from './types'; +import { CssParser } from './utils/CSSParser'; +import { FontParser } from './utils/FontParser'; + +export class GoogleFontApi { + private apiUrl_ = 'https://fonts.googleapis.com/css'; + // TODO: implement google v2 api query + // private apiUrlV2_ = 'https://fonts.googleapis.com/css2'; + private fonts_: string[]; + private version_: 1 | 2; + + /** + * @param fonts + * @param version + */ + constructor(fonts: string[], version: 1 | 2 = 1) { + this.fonts_ = fonts; + this.version_ = version; + } + + /** + * Builds font googleapis url from given fonts in constructor + * @return string + */ + public buildUri(): string { + const fontApiParser = new FontParser(this.fonts_); + fontApiParser.parse(); + const request = fontApiParser.getFonts().map((font) => { + const fontString = `${font.family}:${font.variation}`; + return fontString.replace(/\s/g, '+'); + }); + const requestString: string = request.join('|'); + return `${this.apiUrl_}?family=${requestString}`; + } +} + +export class GoogleLoader implements FontLoader { + private fonts_: FontFamilies; + private uri_: string | undefined; + + constructor(fonts: FontFamilies) { + this.fonts_ = fonts; + this.generateUri_(); + } + + /** + * Returns google uri to get all the fonts + */ + public getUris(): string[] { + return this.uri_ ? [this.uri_] : []; + } + + /** + * Return all google font's that should be loaded + */ + public getFonts(): Font[] { + const fontApiParser = new FontParser(this.fonts_.families); + fontApiParser.parse(); + return fontApiParser.getFonts(); + } + + /** + * Returns ParsedFont array for native font loading + */ + public async getParsedFonts(): Promise { + if (!this.uri_) { + throw new Error('No uri provided. Nothing to parse.'); + } + const fontResponse = await fetch(this.uri_).then((response) => response.text()); + const cssParser = new CssParser(fontResponse); + cssParser.parseCSS(); + return cssParser.getParsedFonts(); + } + + /** + * Generates google font api url from given array of fonts + */ + private generateUri_(): void { + const googleFontApi = new GoogleFontApi(this.fonts_.families); + this.uri_ = googleFontApi.buildUri(); + } +} diff --git a/src/modules/fontLoader/types/index.d.ts b/src/modules/fontLoader/types/index.d.ts new file mode 100644 index 0000000..6ae5a97 --- /dev/null +++ b/src/modules/fontLoader/types/index.d.ts @@ -0,0 +1,57 @@ +type EmptyFunction = () => void; +type FamilyFunction = (familyName: string, fvd) => void; +export type LoadingMethod = 'native' | 'link'; +export type Font = { + family: string; + variation: string; +}; +export type FontFamilies = { + families: string[]; + load?: LoadingMethod; +}; +export type CustomFamily = { + name: string; + url: string; +}; +export type CustomFamilies = { + families: (string | CustomFamily)[]; + urls?: string[]; + load?: LoadingMethod; +}; +export type FontsLoaderConfig = { + google?: FontFamilies; + custom?: CustomFamilies; + classes?: boolean; + events?: boolean; + context?: string[]; + timeout?: number; + loading?: EmptyFunction; + active?: EmptyFunction; + inactive?: EmptyFunction; + fontloading?: FamilyFunction; + fontactive?: FamilyFunction; + fontinactive?: FamilyFunction; +}; +export type FontsLoaderDefaultConfig = { + events: boolean; + classes: boolean; + timeout: number; +}; + +// API +export type FontRequest = { + family: string; + style?: string | string[]; +}; +export type ParsedFont = { + fontFamily: string; + fontStyle?: string; + fontWeight?: string; + src: string; + unicodeRange?: string; +}; +export interface FontLoader { + getFonts(): Font[] | Promise; + getParsedFonts(): ParsedFont[] | Promise; + getUris(): string[]; +} diff --git a/src/modules/fontLoader/utils/CSSParser.ts b/src/modules/fontLoader/utils/CSSParser.ts new file mode 100644 index 0000000..c23eb99 --- /dev/null +++ b/src/modules/fontLoader/utils/CSSParser.ts @@ -0,0 +1,75 @@ +import type { ParsedFont } from '../types'; + +export class CssParser { + private css_: string; + private rules_: ParsedFont[] = []; + + constructor(fontFaceResponseText: string) { + this.css_ = fontFaceResponseText; + } + + /** + * Returns ParsedFont array of parsed CSS + */ + public getParsedFonts(): ParsedFont[] { + return this.rules_; + } + + /** + * Parses CSS into array of ParsedFont object + */ + public parseCSS() { + this.css_ = this.removeNewLines_(this.css_); + const blocks = this.css_.split('}'); + blocks.pop(); + blocks.forEach((block) => { + const pair = block.split('{'); + const parsed = this.parseCSSBlock_(pair[1]); + + this.rules_.push({ + fontFamily: parsed['font-family'], + fontStyle: parsed['font-style'], + fontWeight: parsed['font-weight'], + src: parsed.src, + unicodeRange: parsed['font-range'], + }); + }); + } + + /** + * Parsing css block + * @param css + * @private + */ + private parseCSSBlock_(css: string): { + 'font-family': string; + 'font-style': string; + 'font-weight': string; + src: string; + 'font-range': string; + } { + const rule: any = {}; + const declarations = css.split(';'); + declarations.pop(); + declarations.forEach((declaration) => { + const loc = declaration.indexOf(':'); + const property = declaration.substring(0, loc).trim(); + let value = declaration.substring(loc + 1).trim(); + if (value[0] === "'" && value[value.length - 1] === "'") { + value = value.replace(/'/g, ''); + } + + if (property != '' && value != '') rule[property] = value; + }); + return rule; + } + + /** + * Removes all empty lines from CSS + * @param css + * @private + */ + private removeNewLines_(css: string) { + return css.replace(/\n/g, ''); + } +} diff --git a/src/modules/fontLoader/utils/EventBus.ts b/src/modules/fontLoader/utils/EventBus.ts new file mode 100644 index 0000000..602d8ff --- /dev/null +++ b/src/modules/fontLoader/utils/EventBus.ts @@ -0,0 +1,142 @@ +import type { FontsLoaderConfig } from '../types'; + +export enum FontEvents { + LOADING = 'loading', + ACTIVE = 'active', + INACTIVE = 'inactive', + FONT_LOADING = 'fontloading', + FONT_ACTIVE = 'fontactive', + FONT_INACTIVE = 'fontinactive', +} + +export class EventBus { + private namespace_ = 'wf'; + private classSeparator_ = '-'; + private event_: Event; + private config_: FontsLoaderConfig; + private htmlElement_; + + constructor(config: FontsLoaderConfig) { + this.config_ = config; + this.event_ = document.createEvent('CustomEvent'); + this.htmlElement_ = document.documentElement; + document.addEventListener( + FontEvents.LOADING, + () => { + this.handleLoading_(); + }, + false + ); + document.addEventListener( + FontEvents.ACTIVE, + () => { + this.handleActive_(); + }, + false + ); + document.addEventListener( + FontEvents.INACTIVE, + () => { + this.handleInactive_(); + }, + false + ); + document.addEventListener( + FontEvents.FONT_LOADING, + (event) => { + const { detail } = event as CustomEvent; + this.handleFontLoading_(detail); + }, + false + ); + document.addEventListener( + FontEvents.FONT_ACTIVE, + (event) => { + const { detail } = event as CustomEvent; + this.handleFontActive_(detail); + }, + false + ); + document.addEventListener( + FontEvents.FONT_INACTIVE, + (event) => { + const { detail } = event as CustomEvent; + this.handleFontInactive_(detail); + }, + false + ); + } + + private handleLoading_() { + if (this.config_.events && this.config_.loading) { + this.config_.loading.call(null); + this.addClassToHtml_(FontEvents.LOADING); + this.removeClassFromHtml_(FontEvents.ACTIVE); + this.removeClassFromHtml_(FontEvents.INACTIVE); + } + } + + private handleActive_() { + if (this.config_.events && this.config_.active) { + this.config_.active.call(null); + this.removeClassFromHtml_(FontEvents.LOADING); + this.addClassToHtml_(FontEvents.ACTIVE); + this.removeClassFromHtml_(FontEvents.INACTIVE); + } + } + + private handleInactive_() { + if (this.config_.events && this.config_.inactive) { + this.config_.inactive.call(null); + this.removeClassFromHtml_(FontEvents.LOADING); + this.removeClassFromHtml_(FontEvents.ACTIVE); + this.addClassToHtml_(FontEvents.INACTIVE); + } + } + + private handleFontLoading_(font: string) { + if (this.config_.events && this.config_.fontloading) { + const fontArray = font.split(':'); + this.config_.fontloading.call(null, fontArray[0], fontArray[1]); + this.addClassToHtml_(FontEvents.LOADING, [fontArray[0], fontArray[1]]); + this.removeClassFromHtml_(FontEvents.ACTIVE, [fontArray[0], fontArray[1]]); + this.removeClassFromHtml_(FontEvents.INACTIVE, [fontArray[0], fontArray[1]]); + } + } + + private handleFontActive_(font: string) { + if (this.config_.events && this.config_.fontactive) { + const fontArray = font.split(':'); + this.config_.fontactive.call(null, fontArray[0], fontArray[1]); + this.removeClassFromHtml_(FontEvents.LOADING, [fontArray[0], fontArray[1]]); + this.addClassToHtml_(FontEvents.ACTIVE, [fontArray[0], fontArray[1]]); + this.removeClassFromHtml_(FontEvents.INACTIVE, [fontArray[0], fontArray[1]]); + } + } + + private handleFontInactive_(font: string) { + if (this.config_.events && this.config_.fontinactive) { + const fontArray = font.split(':'); + this.config_.fontinactive.call(null, fontArray[0], fontArray[1]); + this.removeClassFromHtml_(FontEvents.LOADING, [fontArray[0], fontArray[1]]); + this.removeClassFromHtml_(FontEvents.ACTIVE, [fontArray[0], fontArray[1]]); + this.addClassToHtml_(FontEvents.INACTIVE, [fontArray[0], fontArray[1]]); + } + } + + private addClassToHtml_(className: string, prefix: string[] = []) { + this.htmlElement_.classList.add( + [this.namespace_].concat(prefix.map(this.sanitizeClassName_), className).join(this.classSeparator_) + ); + } + + private removeClassFromHtml_(className: string, prefix: string[] = []) { + this.htmlElement_.classList.remove( + [this.namespace_].concat(prefix.map(this.sanitizeClassName_), className).join(this.classSeparator_) + ); + } + + private sanitizeClassName_(className: string) { + return className.replace(/[\W_]+/g, '').toLowerCase(); + } +} diff --git a/src/modules/fontLoader/utils/FontParser.ts b/src/modules/fontLoader/utils/FontParser.ts new file mode 100644 index 0000000..432c1bf --- /dev/null +++ b/src/modules/fontLoader/utils/FontParser.ts @@ -0,0 +1,177 @@ +/** Source: https://github.com/typekit/webfontloader/blob/master/src/modules/google/fontapiparser.js */ + +import type { Font } from '../types'; + + +export class FontParser { + private fontFamilies: string[]; + private parsedFonts: Font[]; + private fontTestStrings: Record; + + private INT_FONTS = { + latin: 'BESbswy', + 'latin-ext': '\u00E7\u00F6\u00FC\u011F\u015F', + cyrillic: '\u0439\u044f\u0416', + greek: '\u03b1\u03b2\u03a3', + khmer: '\u1780\u1781\u1782', + Hanuman: '\u1780\u1781\u1782', // For backward compatibility + }; + private WEIGHTS = { + thin: '1', + extralight: '2', + 'extra-light': '2', + ultralight: '2', + 'ultra-light': '2', + light: '3', + regular: '4', + book: '4', + medium: '5', + 'semi-bold': '6', + semibold: '6', + 'demi-bold': '6', + demibold: '6', + bold: '7', + 'extra-bold': '8', + extrabold: '8', + 'ultra-bold': '8', + ultrabold: '8', + black: '9', + heavy: '9', + l: '3', + r: '4', + b: '7', + }; + private STYLES = { + i: 'i', + italic: 'i', + n: 'n', + normal: 'n', + }; + private VARIATION_MATCH = new RegExp( + '^(thin|(?:(?:extra|ultra)-?)?light|regular|book|medium|' + + '(?:(?:semi|demi|extra|ultra)-?)?bold|black|heavy|l|r|b|[1-9]00)?(n|i' + + '|normal|italic)?$' + ); + + constructor(fontFamilies: string[]) { + this.fontFamilies = fontFamilies; + this.parsedFonts = []; + this.fontTestStrings = {}; + } + + public parse(): void { + for (const fontFamilyString of this.fontFamilies) { + const elements = fontFamilyString.split(':'); + const fontFamily = elements[0].replace(/\+/g, ' '); + let variations = ['n4']; + + if (elements.length >= 2) { + const fvds = this.parseVariations(elements[1]); + if (fvds.length > 0) { + variations = fvds; + } + if (elements.length === 3) { + const subsets = this.parseSubsets(elements[2]); + if (subsets.length > 0) { + const fontTestString = this.INT_FONTS[subsets[0] as keyof typeof this.INT_FONTS]; + if (fontTestString) { + this.fontTestStrings[fontFamily] = fontTestString; + } + } + } + } + + // For backward compatibility + if (!this.fontTestStrings[fontFamily]) { + const hanumanTestString = this.INT_FONTS[fontFamily as keyof typeof this.INT_FONTS]; + if (hanumanTestString) { + this.fontTestStrings[fontFamily] = hanumanTestString; + } + } + + for (const variation of variations) { + this.parsedFonts.push({ + family: fontFamily, + variation, + }); + } + } + } + + private generateFontVariationDescription(variation: string) { + if (!variation.match(/^[\w-]+$/)) { + return ''; + } + const normalizedVariation = variation.toLowerCase(); + const groups = this.VARIATION_MATCH.exec(normalizedVariation); + if (groups == null) { + return ''; + } + const styleMatch = this.normalizeStyle(groups[2] as keyof typeof this.STYLES); + const weightMatch = this.normalizeWeight(groups[1] as keyof typeof this.WEIGHTS); + return [styleMatch, weightMatch].join(''); + } + + private normalizeStyle(parsedStyle: keyof typeof this.STYLES | '' | null) { + if (parsedStyle == null || parsedStyle == '') { + return 'n'; + } + return this.STYLES[parsedStyle]; + } + + private normalizeWeight(parsedWeight?: keyof typeof this.WEIGHTS | '' | number) { + if (parsedWeight == null || parsedWeight == '') { + return '4'; + } + if (typeof parsedWeight === 'string') { + const weight = this.WEIGHTS[parsedWeight]; + if (weight) { + return weight; + } + } + if (typeof parsedWeight === 'number') { + if (isNaN(parsedWeight)) { + return '4'; + } + + } + return parsedWeight.toString().substr(0, 1); + } + + private parseVariations(variations: string) { + const finalVariations: string[] = []; + + if (!variations) { + return finalVariations; + } + const providedVariations = variations.split(','); + const length = providedVariations.length; + + for (let i = 0; i < length; i++) { + const variation = providedVariations[i]; + const fvd = this.generateFontVariationDescription(variation); + + if (fvd) { + finalVariations.push(fvd); + } + } + return finalVariations; + } + + public parseSubsets(subsets: T): T[] { + const finalSubsets: T[] = []; + + if (!subsets) { + return finalSubsets; + } + return subsets.split(',') as T[]; + } + + public getFonts() { + return this.parsedFonts; + } + + public getFontTestStrings() { + return this.fontTestStrings; + } +} diff --git a/src/modules/fontLoader/utils/FontWatcher.ts b/src/modules/fontLoader/utils/FontWatcher.ts new file mode 100644 index 0000000..30808da --- /dev/null +++ b/src/modules/fontLoader/utils/FontWatcher.ts @@ -0,0 +1,28 @@ +import type { Font, LoadingMethod } from '../types'; +import { FontEvents } from './EventBus'; + +export class FontWatcher { + private font_: Font; + private load_: LoadingMethod; + + constructor(font: Font, load: LoadingMethod) { + this.font_ = font; + this.load_ = load; + + this.loading_(); + } + + private loading_() { + document.dispatchEvent( + new CustomEvent(FontEvents.FONT_LOADING, { detail: `${this.font_.family}:${this.font_.variation}` }) + ); + } + + public getFont(): Font { + return this.font_; + } + + public watch(): boolean { + return document.fonts.check(`16px ${this.font_.family}`, 'BESbswy'); + } +} diff --git a/src/modules/fontLoader/utils/Watcher.ts b/src/modules/fontLoader/utils/Watcher.ts new file mode 100644 index 0000000..e333f29 --- /dev/null +++ b/src/modules/fontLoader/utils/Watcher.ts @@ -0,0 +1,37 @@ +import type { Font, LoadingMethod } from '../types'; +import { FontEvents } from './EventBus'; +import { FontWatcher } from './FontWatcher'; + +export class Watcher { + private fontWatchers_: FontWatcher[] = []; + private loadedFonts_: string[] = []; + private watched_ = false; + + public add(font: Font, load: LoadingMethod) { + this.fontWatchers_.push(new FontWatcher(font, load)); + } + + public fontLoaded(fontName: string) { + this.loadedFonts_.push(fontName); + } + + public watchFonts() { + if (!this.watched_) { + this.watched_ = true; + let atLeastOneLoaded = false; + this.fontWatchers_.forEach((fontWatcher) => { + const font = fontWatcher.getFont(); + const loaded = this.loadedFonts_.includes(font.family) || fontWatcher.watch(); + if (loaded) { + atLeastOneLoaded = true; + } + document.dispatchEvent( + new CustomEvent(loaded ? FontEvents.FONT_ACTIVE : FontEvents.FONT_INACTIVE, { + detail: `${font.family}:${font.variation}`, + }) + ); + }); + document.dispatchEvent(new CustomEvent(atLeastOneLoaded ? FontEvents.ACTIVE : FontEvents.INACTIVE, {})); + } + } +} diff --git a/src/submodules/narrator/Narrator.ts b/src/submodules/narrator/Narrator.ts index 4a3203c..4abdba3 100644 --- a/src/submodules/narrator/Narrator.ts +++ b/src/submodules/narrator/Narrator.ts @@ -1,11 +1,191 @@ import { Tome } from 'src/class/Tome'; +import { FontsLoader } from 'src/modules/fontLoader/FontLoader'; export class Narrator extends Tome { + public static fonts = [ + "Caslon", + "CaslonAntique", + "SignikaBold", + "Riffic", + "IronSans", + "LinLibertine", + "TimesNewRomance", + "TimesNewYorker", + "LPEducational", + "Cardinal", + "OldLondon", + "StoneHenge", + "SunnyDay", + "PaulSignature", + "LemonTuesday", + "FairProsper", + "BalletHarmony", + "MagieraScript", + "Cathallina", + "Hamish", + "DreamersBrush", + "FastInMyCar", + "ChildWriting", + "Kindergarten", + "FuturaHandwritten", + "Fewriter", + "TrashHand", + "GoodBrush", + "BaksoSapi", + "SuplexmentaryComic", + "ComicInk", + "DreamyLand", + "Yikes", + "GangOfThree", + "JianGkrik", + "Yozakura", + "Hiroshio", + "ArabDances", + "Rooters", + "Subway", + "Himagsikan", + "MilTown", + "Galactico", + "Oko", + "Ethnocentric", + "VenusRising", + "StampAct", + "Kirsty", + "Western", + "BreakAway", + "YoungerThanMe", + "Underground", + "VarsityTeam", + "Valentino", + "GlassHouses", + "Makayla", + "DancingVampyrish", + "Codex", + "DSNetStamped", + "HappyFrushZero", + "Shoplifter", + "Stereofidelic", + "Headache", + "HorrorHouse", + "GhostTheory2", + "Syemox", + "GhostChase" + ] as const; + public static fontWeights = [ + "100", + "200", + "300", + "400", + "500", + "600", + "700", + "800", + "900" + ] as const; + public static fontStyles = [ + "normal", + "italic", + "oblique" + ] as const; + + public get titleFont() { + return this.getSetting("Title Font") ?? "GhostTheory2"; + } + public static get titleFont() { + return game.settings?.get('wonderlost', 'narrator-title-font') as typeof Narrator['fonts'][number] + ?? "GhostTheory2" as typeof Narrator['fonts'][number]; + } + public static set titleFont(value: typeof Narrator['fonts'][number]) { + game.settings?.set('wonderlost', 'narrator-title-font', value); + } + + public get textFont() { + return this.getSetting("Text Font") ?? "GhostTheory2"; + } + public static get textFont() { + return game.settings?.get('wonderlost', 'narrator-text-font') as typeof Narrator['fonts'][number] + ?? "GhostTheory2"; + } + public static set textFont(value: typeof Narrator['fonts'][number]) { + game.settings?.set('wonderlost', 'narrator-text-font', value); + } + + public get titleWeight() { + return this.getSetting("Title Weight") ?? "400"; + } + public static get titleWeight() { + return game.settings?.get('wonderlost', 'narrator-title-weight') as typeof Narrator['fontWeights'][number] + ?? "400"; + } + public static set titleWeight(value: typeof Narrator['fontWeights'][number]) { + game.settings?.set('wonderlost', 'narrator-title-weight', value); + } + constructor(DEBUG = false) { super({ moduleName: "Narrator", moduleDescription: "An extremely customizable on screen narrator system", - hooks: new Map([]), + settings: { + globalSettings: [ + { + name: "Title Font", + hint: "The font used for the title text", + type: String, + defaultValue: "GhostTheory2", + choices: Object.fromEntries(Narrator.fonts.map((font) => [font, font])), + onChange: (value) => { + Narrator.titleFont = value as typeof Narrator['fonts'][number]; + } + }, + { + name: "Text Font", + hint: "The font used for the text body", + type: String, + defaultValue: "GhostTheory2", + choices: Object.fromEntries(Narrator.fonts.map((font) => [font, font])), + onChange: (value) => { + Narrator.textFont = value as typeof Narrator['fonts'][number]; + } + }, + { + name: "Title Weight", + hint: "The weight of the title font", + type: String, + defaultValue: "400", + choices: Object.fromEntries(Narrator.fontWeights.map((weight) => [weight, weight])), + onChange: (value) => { + Narrator.titleWeight = value as typeof Narrator['fontWeights'][number]; + } + } + ] + }, + hooks: new Map([ + ['ready', (app, data) => { + // Load some essential fonts we use in PIXI + FontsLoader({ + custom: { + families: [Narrator.titleFont, Narrator.textFont], + }, + }); + // async load everything else + let oFonts = []; + for (let idx = Narrator.fonts.length - 1; idx >= 0; --idx) { + if (Narrator.fonts[idx] === Narrator.titleFont || Narrator.fonts[idx] === Narrator.textFont) { + continue; + } + oFonts.push(Narrator.fonts[idx]); + } + const aLoader = async function (fonts: string[]) { + FontsLoader({ + custom: { + families: fonts, + }, + }); + }; + + aLoader(oFonts); + }] + ]), socketFns: new Map([]), DEBUG }) diff --git a/src/wonderlost.ts b/src/wonderlost.ts index 0f2fd21..f2fde12 100644 --- a/src/wonderlost.ts +++ b/src/wonderlost.ts @@ -2,31 +2,33 @@ import consola from 'consola'; import { Toasted } from "./submodules/toasted/Toasted"; import { Narrator } from './submodules/narrator/Narrator'; +type ToastedTuple = ['Toasted', Toasted]; +type NarratorTuple = ['Narrator', Narrator]; + class Wonderlost { - public tomes = new Map([ - ['Toasted', Toasted], - ['Narrator', Narrator], + public tomes = new Map<'Toasted' | 'Narrator', Toasted | Narrator>([ + ['Toasted', new Toasted()] as ToastedTuple, + ['Narrator', new Narrator()] as NarratorTuple, ]) constructor(public DEBUG = false) { - consola.info("Wonderlost | Initializing"); - this.initializeTomes(); + consola.info("Wonderlost | Initialized", this); } initializeTomes() { - this.tomes.forEach((tome, tomeName) => { - new tome(this.DEBUG).initialize(); + for (const [tomeName, tome] of this.tomes) { + tome.initialize(); if (this.DEBUG) { - consola.info(`Wonderlost | Initialized ${tomeName}`); + consola.info(`Wonderlost | Initialized ${tomeName}`, tome); } - }) + } } } Hooks.once("init", async function () { consola.start("Wonderlost | Initialized"); - new Wonderlost(true); + new Wonderlost(true).initializeTomes(); consola.success("Wonderlost | Ready"); }); diff --git a/styles/narrator.css b/styles/narrator.css new file mode 100644 index 0000000..d4b8217 --- /dev/null +++ b/styles/narrator.css @@ -0,0 +1,1718 @@ +@charset "UTF-8"; + +@font-face { + font-family: "Caslon"; + src: url("../dist/submodules/narrator/assets/ACaslonPro-Bold.otf"); +} + +@font-face { + font-family: "CaslonAntique"; + src: url("../dist/submodules/narrator/assets/CaslonAntique-Bold.ttf"); +} + +@font-face { + font-family: "SignikaBold"; + src: url("../dist/submodules/narrator/assets/Signika-Bold.ttf"); +} + +@font-face { + font-family: "Riffic"; + src: url("../dist/submodules/narrator/assets/RifficFree-Bold.ttf"); +} + +@font-face { + font-family: "LinLibertine"; + src: url("../dist/submodules/narrator/assets/LinLibertine_RB.ttf"); +} + +@font-face { + font-family: "GODOFWAR"; + src: url("../dist/submodules/narrator/assets/GODOFWAR.ttf"); +} + +@font-face { + font-family: "OldLondon"; + src: url("../dist/submodules/narrator/assets/OldLondon.ttf"); +} + +@font-face { + font-family: "Ethnocentric"; + src: url("../dist/submodules/narrator/assets/ethnocentric-rg.ttf"); +} + +@font-face { + font-family: "Cardinal"; + src: url("../dist/submodules/narrator/assets/Cardinal.ttf"); +} + +@font-face { + font-family: "Western"; + src: url("../dist/submodules/narrator/assets/WEST.ttf"); +} + +@font-face { + font-family: "Luna"; + src: url("../dist/submodules/narrator/assets/Luna.ttf"); +} + +@font-face { + font-family: "FastInMyCar"; + src: url("../dist/submodules/narrator/assets/Fast-In-My-Car.ttf"); +} + +@font-face { + font-family: "StoneHenge"; + src: url("../dist/submodules/narrator/assets/stonehen.ttf"); +} + +@font-face { + font-family: "Dungeon"; + src: url("../dist/submodules/narrator/assets/DUNGRG.ttf"); +} + +@font-face { + font-family: "LemonTuesday"; + src: url("../dist/submodules/narrator/assets/Lemon-Tuesday.otf"); +} + +@font-face { + font-family: "ChildWriting"; + src: url("../dist/submodules/narrator/assets/ChildWriting-Regular.ttf"); +} + +@font-face { + font-family: "Subscriber"; + src: url("../dist/submodules/narrator/assets/SUBSCRIBER-Regular.otf"); +} + +@font-face { + font-family: "PaulSignature"; + src: url("../dist/submodules/narrator/assets/Paul-Signature.ttf"); +} + +@font-face { + font-family: "TrashHand"; + src: url("../dist/submodules/narrator/assets/TrashHand.ttf"); +} + +@font-face { + font-family: "Kindergarten"; + src: url("../dist/submodules/narrator/assets/kindergarten.ttf"); +} + +@font-face { + font-family: "HoneyScript"; + src: url("../dist/submodules/narrator/assets/HoneyScript-SemiBold.ttf"); +} + +@font-face { + font-family: "GhostTheory2"; + src: url("../dist/submodules/narrator/assets/Ghost-theory-2.ttf"); +} + +@font-face { + font-family: "GhostChase"; + src: url("../dist/submodules/narrator/assets/GhostChase.ttf"); +} + +@font-face { + font-family: "Alamain"; + src: url("../dist/submodules/narrator/assets/alamain1.ttf"); +} + +@font-face { + font-family: "SunnyDay"; + src: url("../dist/submodules/narrator/assets/fontopoSunnyDay-Regular.otf"); +} + +@font-face { + font-family: "Subway"; + src: url("../dist/submodules/narrator/assets/fontopoSUBWAY-Regular.otf"); +} + +@font-face { + font-family: "MagieraScript"; + src: url("../dist/submodules/narrator/assets/Magiera_Script.ttf"); +} + +@font-face { + font-family: "Cathallina"; + src: url("../dist/submodules/narrator/assets/Cathallina.ttf"); +} + +@font-face { + font-family: "BalletHarmony"; + src: url("../dist/submodules/narrator/assets/BalletHarmony.ttf"); +} + +@font-face { + font-family: "FairProsper"; + src: url("../dist/submodules/narrator/assets/FairProsper.ttf"); +} + +@font-face { + font-family: "Megadeth"; + src: url("../dist/submodules/narrator/assets/Megadeth.ttf"); +} + +@font-face { + font-family: "Rooters"; + src: url("../dist/submodules/narrator/assets/Rooters.otf"); +} + +@font-face { + font-family: "BadManners"; + src: url("../dist/submodules/narrator/assets/MCF_bad_manners_ww.ttf"); +} + +@font-face { + font-family: "BaksoSapi"; + src: url("../dist/submodules/narrator/assets/BaksoSapi.otf"); +} + +@font-face { + font-family: "Yikes"; + src: url("../dist/submodules/narrator/assets/YIKES!.ttf"); +} + +@font-face { + font-family: "FuturaHandwritten"; + src: url("../dist/submodules/narrator/assets/FuturaHandwritten.ttf"); +} + +@font-face { + font-family: "SuplexmentaryComic"; + src: url("../dist/submodules/narrator/assets/Suplexmentary_Comic_NC.ttf"); +} + +@font-face { + font-family: "ComicInk"; + src: url("../dist/submodules/narrator/assets/Comic-ink.otf"); +} + +@font-face { + font-family: "VarsityTeam"; + src: url("../dist/submodules/narrator/assets/VarsityTeam-Bold.otf"); +} + +@font-face { + font-family: "Tiza"; + src: url("../dist/submodules/narrator/assets/tiza.ttf"); +} + +@font-face { + font-family: "TimesNewYorker"; + src: url("../dist/submodules/narrator/assets/times_new_yorker.ttf"); +} + +@font-face { + font-family: "RomanNewTimes"; + src: url("../dist/submodules/narrator/assets/Roman_New_Times.otf"); +} + +@font-face { + font-family: "GangOfThree"; + src: url("../dist/submodules/narrator/assets/go3v2.ttf"); +} + +@font-face { + font-family: "Yozakura"; + src: url("../dist/submodules/narrator/assets/YOZAKURA-Regular.otf"); +} + +@font-face { + font-family: "ArabDances"; + src: url("../dist/submodules/narrator/assets/ArabDances.ttf"); +} + +@font-face { + font-family: "BreakAway"; + src: url("../dist/submodules/narrator/assets/breakaway.ttf"); +} + +@font-face { + font-family: "BrentonScrawlType"; + src: url("../dist/submodules/narrator/assets/bwptype.ttf"); +} + +@font-face { + font-family: "DancingVampyrish"; + src: url("../dist/submodules/narrator/assets/DancingVampyrish.ttf"); +} + +@font-face { + font-family: "Codex"; + src: url("../dist/submodules/narrator/assets/codex.ttf"); +} + +@font-face { + font-family: "DSNetStamped"; + src: url("../dist/submodules/narrator/assets/DSnet_Stamped.ttf"); +} + +@font-face { + font-family: "GlassHouses"; + src: url("../dist/submodules/narrator/assets/glashou.ttf"); +} + +@font-face { + font-family: "MilTown"; + src: url("../dist/submodules/narrator/assets/MLTWNII_.ttf"); +} + +@font-face { + font-family: "Shoplifter"; + src: url("../dist/submodules/narrator/assets/shoplift.ttf"); +} + +@font-face { + font-family: "Lumos"; + src: url("../dist/submodules/narrator/assets/LUMOS.ttf"); +} + +@font-face { + font-family: "IronSans"; + src: url("../dist/submodules/narrator/assets/IronSans.ttf"); +} + +@font-face { + font-family: "StampAct"; + src: url("../dist/submodules/narrator/assets/STAMPACT.ttf"); +} + +@font-face { + font-family: "TimesNewRomance"; + src: url("../dist/submodules/narrator/assets/Times-New-Romance.ttf"); +} + +@font-face { + font-family: "DreamersBrush"; + src: url("../dist/submodules/narrator/assets/DREAMERS-BRUSH.ttf"); +} + +@font-face { + font-family: "Hamish"; + src: url("../dist/submodules/narrator/assets/Hamish.otf"); +} + +@font-face { + font-family: "Syemox"; + src: url("../dist/submodules/narrator/assets/Syemox-italic.ttf"); +} + +@font-face { + font-family: "Himagsikan"; + src: url("../dist/submodules/narrator/assets/himagsikan.otf"); +} + +@font-face { + font-family: "GoodBrush"; + src: url("../dist/submodules/narrator/assets/Good-Brush.ttf"); +} + +@font-face { + font-family: "Fewriter"; + src: url("../dist/submodules/narrator/assets/fewriter_memesbruh03.ttf"); +} + +@font-face { + font-family: "DreamyLand"; + src: url("../dist/submodules/narrator/assets/Dreamy-Land-Medium.ttf"); +} + +@font-face { + font-family: "JianGkrik"; + src: url("../dist/submodules/narrator/assets/JIANGKRIK.otf"); +} + +@font-face { + font-family: "Valentino"; + src: url("../dist/submodules/narrator/assets/Valentino.ttf"); +} + +@font-face { + font-family: "Galactico"; + src: url("../dist/submodules/narrator/assets/Galactico-Basic.otf"); +} + +@font-face { + font-family: "Hiroshio"; + src: url("../dist/submodules/narrator/assets/Hiroshio.otf"); +} + +@font-face { + font-family: "Makayla"; + src: url("../dist/submodules/narrator/assets/makayla.ttf"); +} + +@font-face { + font-family: "HappyFrushZero"; + src: url("../dist/submodules/narrator/assets/happyfrushzero.ttf"); +} + +@font-face { + font-family: "Oko"; + src: url("../dist/submodules/narrator/assets/oko.ttf"); +} + +@font-face { + font-family: "Stereofidelic"; + src: url("../dist/submodules/narrator/assets/stereofidelic.ttf"); +} + +@font-face { + font-family: "Headache"; + src: url("../dist/submodules/narrator/assets/Headache.ttf"); +} + +@font-face { + font-family: "YoungerThanMe"; + src: url("../dist/submodules/narrator/assets/Younger-than-me.ttf"); +} + +@font-face { + font-family: "LPEducational"; + src: url("../dist/submodules/narrator/assets/LPEducational.ttf"); +} + +@font-face { + font-family: "Kirsty"; + src: url("../dist/submodules/narrator/assets/kirsty-rg.ttf"); +} + +@font-face { + font-family: "VenusRising"; + src: url("../dist/submodules/narrator/assets/venus-rising-rg.ttf"); +} + +@font-face { + font-family: "NotoSansJPBold"; + src: url("../assets/graphics/fonts/ja/NotoSansJP-Bold.otf"); +} + +@font-face { + font-family: "CorporateLogoBold"; + src: url("../assets/graphics/fonts/ja/logotypejp.ttf"); +} + +@font-face { + font-family: "RiiPopkk"; + src: url("../assets/graphics/fonts/ja/RiiPopkkR.otf"); +} + +@font-face { + font-family: "PopRumCute"; + src: url("../assets/graphics/fonts/ja/PopRumCute.otf"); +} + +@font-face { + font-family: "ChikaraYowaku"; + src: url("../assets/graphics/fonts/ja/851CHIKARA-YOWAKU.ttf"); +} + +@font-face { + font-family: "Otsutome"; + src: url("../assets/graphics/fonts/ja/OtsutomeFont_Ver3.ttf"); +} + +@font-face { + font-family: "MaleCharacters"; + src: url("../assets/graphics/fonts/ja/male-characters.ttf"); +} + +@font-face { + font-family: "TanukiPermanentMarker"; + src: url("../assets/graphics/fonts/ja/TanukiMagic.ttf"); +} + +@font-face { + font-family: "CineCaption"; + src: url("../assets/graphics/fonts/ja/cinecaption.ttf"); +} + +@font-face { + font-family: "GenEiLateMin_v2"; + src: url("../assets/graphics/fonts/ja/GenEiLateMin_v2.ttc"); +} + +@font-face { + font-family: "ReallyScaryMinchotai"; + src: url("../assets/graphics/fonts/ja/ReallyScaryMinchotai.otf"); +} + +@font-face { + font-family: "Zomzi"; + src: url("../assets/graphics/fonts/ja/Zomzi.ttf"); +} + +@font-face { + font-family: "ComicHorror"; + src: url("../assets/graphics/fonts/ja/ComicHorror.ttf"); +} + +@font-face { + font-family: "GenkaiMincho"; + src: url("../assets/graphics/fonts/ja/genkai-mincho.ttf"); +} + +@font-face { + font-family: "Togalite"; + src: url("../assets/graphics/fonts/ja/togalite-heavy.otf"); +} + +@font-face { + font-family: "HannariMincho"; + src: url("../assets/graphics/fonts/ja/Hannari.otf"); +} + +@font-face { + font-family: "TogoshiMincho"; + src: url("../assets/graphics/fonts/ja/togoshi-mincho.ttf"); +} + +@font-face { + font-family: "NagurigakiCrayon"; + src: url("../assets/graphics/fonts/ja/Nagurigaki_Crayon.ttf"); +} + +@font-face { + font-family: "TegakiKakutto"; + src: url("../assets/graphics/fonts/ja/851_Tegaki_Kakutto.ttf"); +} + +@font-face { + font-family: "ArmedLemon"; + src: url("../assets/graphics/fonts/ja/ArmedLemon.ttf"); +} + +@font-face { + font-family: "AsobiMemogaki"; + src: url("../assets/graphics/fonts/ja/AsobiMemogaki-Regular-1-01.ttf"); +} + +@font-face { + font-family: "KohichiFeltPen"; + src: url("../assets/graphics/fonts/ja/KS-Kohichi-FeltPen.ttf"); +} + +@font-face { + font-family: "NicoMojiPlus"; + src: url("../assets/graphics/fonts/ja/nicomoji-plus_1.11.ttf"); +} + +@font-face { + font-family: "AppliMincho"; + src: url("../assets/graphics/fonts/ja/AppliMincho.otf"); +} + +@font-face { + font-family: "KaisoNextB"; + src: url("../assets/graphics/fonts/ja/Kaiso-Next-B.otf"); +} + +@font-face { + font-family: "MikaChan"; + src: url("../assets/graphics/fonts/ja/mikachan-P.ttf"); +} + +@font-face { + font-family: "Pigmo01"; + src: url("../assets/graphics/fonts/ja/Pigmo-01.otf"); +} + +@font-face { + font-family: "ZinHenaBokuryu"; + src: url("../assets/graphics/fonts/ja/ZinHenaBokuryu-RCF.otf"); +} + +@font-face { + font-family: "MinaMoji"; + src: url("../assets/graphics/fonts/ja/minamoji.ttf"); +} + +@font-face { + font-family: "Nikukyu-カタカナ"; + src: url("../assets/graphics/fonts/ja/FontopoNIKUKYU.otf"); +} + +@font-face { + font-family: "Oriental-カタカナ"; + src: url("../assets/graphics/fonts/ja/FontopoORIENTAL.otf"); +} + +@font-face { + font-family: "NotoSansKRBold"; + src: url("../assets/graphics/fonts/ko/NotoSansKR-Bold.otf"); +} + +@font-face { + font-family: "BMDohyeon"; + src: url("../assets/graphics/fonts/ko/BMDOHYEON.ttf"); +} + +@font-face { + font-family: "BMYeonSung"; + src: url("../assets/graphics/fonts/ko/BMYEONSUNG.ttf"); +} + +@font-face { + font-family: "BMHannaPro"; + src: url("../assets/graphics/fonts/ko/BMHANNAPro.ttf"); +} + +@font-face { + font-family: "Sunflower"; + src: url("../assets/graphics/fonts/ko/Sunflower-Bold.ttf"); +} + +@font-face { + font-family: "JejuHallasan"; + src: url("../assets/graphics/fonts/ko/JejuHallasan-Regular.ttf"); +} + +@font-face { + font-family: "BlackHanSans"; + src: url("../assets/graphics/fonts/ko/BlackHanSans-Regular.ttf"); +} + +@font-face { + font-family: "KirangHaerang"; + src: url("../assets/graphics/fonts/ko/KirangHaerang-Regular.ttf"); +} + +@font-face { + font-family: "HiMelody"; + src: url("../assets/graphics/fonts/ko/HiMelody-Regular.ttf"); +} + +@font-face { + font-family: "UhBeeSeHyun"; + src: url("../assets/graphics/fonts/ko/UhBee_Se_hyun_Bold.ttf"); +} + +@font-face { + font-family: "UhBeeJisyuk"; + src: url("../assets/graphics/fonts/ko/UhBee_Jisyuk_jisyuk_BOLD.ttf"); +} + +@font-face { + font-family: "Daraehand"; + src: url("../assets/graphics/fonts/ko/drfont_daraehand_Basic.ttf"); +} + +@font-face { + font-family: "GabiaSolmee"; + src: url("../assets/graphics/fonts/ko/gabia_solmee.ttf"); +} + +@font-face { + font-family: "NanumBrush"; + src: url("../assets/graphics/fonts/ko/NanumBrush.ttf"); +} + +@font-face { + font-family: "SSShinRegular"; + src: url("../assets/graphics/fonts/ko/SSShinRegular.ttf"); +} + +@font-face { + font-family: "SSShinB7Regular"; + src: url("../assets/graphics/fonts/ko/SSShinb7Regular.ttf"); +} + +@font-face { + font-family: "TvNEnjoyStories"; + src: url("../assets/graphics/fonts/ko/tvN_즐거운이야기_Bold.ttf"); +} + +@font-face { + font-family: "K2DBold"; + src: url("../assets/graphics/fonts/th/K2D-Bold.ttf"); +} + +@font-face { + font-family: "NotoSansThaiBold"; + src: url("../assets/graphics/fonts/th/NotoSansThai-Bold.ttf"); +} + +@font-face { + font-family: "Athiti"; + src: url("../assets/graphics/fonts/th/Athiti-Medium.ttf"); +} + +@font-face { + font-family: "BaiJamjuree"; + src: url("../assets/graphics/fonts/th/BaiJamjuree-Medium.ttf"); +} + +@font-face { + font-family: "ChakraPetch"; + src: url("../assets/graphics/fonts/th/ChakraPetch-Medium.ttf"); +} + +@font-face { + font-family: "Charm"; + src: url("../assets/graphics/fonts/th/Charm-Bold.ttf"); +} + +@font-face { + font-family: "Charmonman"; + src: url("../assets/graphics/fonts/th/Charmonman-Bold.ttf"); +} + +@font-face { + font-family: "Chonburi"; + src: url("../assets/graphics/fonts/th/Chonburi-Regular.ttf"); +} + +@font-face { + font-family: "Fahkwang"; + src: url("../assets/graphics/fonts/th/Fahkwang-Medium.ttf"); +} + +@font-face { + font-family: "Itim"; + src: url("../assets/graphics/fonts/th/Itim-Regular.ttf"); +} + +@font-face { + font-family: "Kanit"; + src: url("../assets/graphics/fonts/th/Kanit-Medium.ttf"); +} + +@font-face { + font-family: "Kodchasan"; + src: url("../assets/graphics/fonts/th/Kodchasan-Medium.ttf"); +} + +@font-face { + font-family: "KoHo"; + src: url("../assets/graphics/fonts/th/KoHo-Medium.ttf"); +} + +@font-face { + font-family: "Srisakdi"; + src: url("../assets/graphics/fonts/th/Srisakdi-Bold.ttf"); +} + +@font-face { + font-family: "Krub"; + src: url("../assets/graphics/fonts/th/Krub-Medium.ttf"); +} + +@font-face { + font-family: "Maitree"; + src: url("../assets/graphics/fonts/th/Maitree-Medium.ttf"); +} + +@font-face { + font-family: "Mali"; + src: url("../assets/graphics/fonts/th/Mali-Medium.ttf"); +} + +@font-face { + font-family: "Mitr"; + src: url("../assets/graphics/fonts/th/Mitr-Medium.ttf"); +} + +@font-face { + font-family: "Niramit"; + src: url("../assets/graphics/fonts/th/Niramit-Medium.ttf"); +} + +@font-face { + font-family: "Pattaya"; + src: url("../assets/graphics/fonts/th/Pattaya-Regular.ttf"); +} + +@font-face { + font-family: "Pridi"; + src: url("../assets/graphics/fonts/th/Pridi-Medium.ttf"); +} + +@font-face { + font-family: "Prompt"; + src: url("../assets/graphics/fonts/th/Prompt-Bold.ttf"); +} + +@font-face { + font-family: "Sarabun"; + src: url("../assets/graphics/fonts/th/Sarabun-Medium.ttf"); +} + +@font-face { + font-family: "Sriracha"; + src: url("../assets/graphics/fonts/th/Sriracha-Regular.ttf"); +} + +@font-face { + font-family: "Taviraj"; + src: url("../assets/graphics/fonts/th/Taviraj-Medium.ttf"); +} + +@font-face { + font-family: "Thasadith"; + src: url("../assets/graphics/fonts/th/Thasadith-Bold.ttf"); +} + +@font-face { + font-family: "BianHeiti"; + src: url("../assets/graphics/fonts/cn/BianHeiti.ttf"); +} + +@font-face { + font-family: "SourceHanSerifSC-Medium"; + src: url("../assets/graphics/fonts/cn/SourceHanSerifSC-Medium.otf"); +} + +.no-scrollbar { + overflow-y: scroll; + overflow-x: scroll; + overflow-y: -moz-scrollbars-none; + overflow-x: -moz-scrollbars-none; + scrollbar-width: none; + -ms-overflow-style: none; +} + +.no-scrollbar::-webkit-scrollbar { + display: none; +} + +@keyframes speakingas-item-pulse { + 0% { + border: 1px solid red; + } + + 100% { + border: 1px solid white; + } +} + +@keyframes speakingas-name-pulse { + 0% { + color: white; + } + + 100% { + color: #ff6400; + } +} + +@keyframes typing-wiggle { + 0% { + transform: rotate(-20deg); + } + + 100% { + transform: rotate(20deg); + } +} + +.theatre-group { + pointer-events: none; + transition: opacity 0.5s ease; +} + +.theatre-bar { + display: block; + position: absolute; + width: calc(100% - 302px); + height: 160px; + top: calc(100% - 160px - 0.5vh); + left: 0px; + z-index: 30; + transition: opacity 0.5s ease; + opacity: 0; + pointer-events: none; +} + +.theatre-bar-left { + display: flex; + position: absolute; + top: 0px; + left: -100%; + width: 750px; + border-radius: 0px 5px 5px 0px; + margin: 0px; + padding: 0px; + height: 160px; + z-index: 1; + background: url("../assets/graphics/denim95.png"); + box-shadow: 0 0 20px #000; + transition: width 0.5s ease, left 0.5s ease, opacity 0.5s ease; + opacity: 0; +} + +.theatre-bar-right { + display: flex; + position: absolute; + top: 0px; + left: 200%; + width: 750px; + border-radius: 5px 0px 0px 5px; + margin: 0px; + padding: 0px; + height: 160px; + z-index: 1; + background: url("../assets/graphics/denim95.png"); + box-shadow: 0 0 20px #000; + transition: width 0.5s ease, left 0.5s ease, opacity 0.5s ease; + opacity: 0; +} + +.theatre-bar-lightleft { + display: flex; + position: absolute; + top: 0px; + left: -100%; + width: 750px; + margin: 0px; + padding: 0px; + height: 170px; + z-index: 1; + transition: width 0.5s ease, left 0.5s ease, opacity 0.5s ease; + opacity: 0; +} + +.theatre-bar-lightright { + display: flex; + position: absolute; + top: 0px; + left: 200%; + width: 750px; + margin: 0px; + padding: 0px; + height: 160px; + z-index: 1; + transition: width 0.5s ease, left 0.5s ease, opacity 0.5s ease; + opacity: 0; +} + +.theatre-bar-clearleft { + display: flex; + position: absolute; + top: 0px; + left: -100%; + width: 750px; + margin: 0px; + padding: 0px; + height: 170px; + z-index: 1; + transition: width 0.5s ease, left 0.5s ease, opacity 0.5s ease; + opacity: 0; +} + +.theatre-bar-clearright { + display: flex; + position: absolute; + top: 0px; + left: 200%; + width: 750px; + margin: 0px; + padding: 0px; + height: 170px; + z-index: 1; + transition: width 0.5s ease, left 0.5s ease, opacity 0.5s ease; + opacity: 0; +} + +.theatre-dock { + display: flex; + position: absolute; + top: 0px; + left: 0px; + width: 100%; + height: 99.5vh; + z-index: 30; + overflow-y: hidden; + pointer-events: none; + transition: opacity 0.5s ease; +} + +.theatre-dock-left-top { + display: flex; + position: absolute; + top: 0px; + left: 0px; + width: 100%; + height: calc(99vh - 158px); + pointer-events: none; +} + +.theatre-dock-left { + display: flex; + position: absolute; + top: 0px; + left: 0px; + width: 100%; + height: 99.5vh; + pointer-events: none; +} + +.theatre-dock-right-top { + display: flex; + position: absolute; + top: 0px; + left: calc(100% - 300px - 950px); + width: 100%; + height: calc(99vh - 158px); + pointer-events: none; +} + +.theatre-dock-right { + display: flex; + position: absolute; + top: 0px; + left: calc(100% - 300px - 950px); + width: 100%; + height: 99.5vh; + pointer-events: none; +} + +.theatre-portrait-dock { + display: block; + position: absolute; + top: 0px; + left: 0px; + transition: left 1s ease, opacity 1s ease; +} + +.theatre-portrait-left, +.theatre-portrait-right { + position: absolute; + border: none; + top: 0px; + left: 0px; + transition: top 0.5s ease, left 0.5s ease, transform 0.5s ease; +} + +.theatre-portrait-load { + display: none; +} + +.theatre-mirror { + -webkit-transform: scaleX(-1); + transform: scaleX(-1); +} + +.theatre-portrait-name-right, +.theatre-portrait-name-left, +.theatre-portrait-name { + display: block; + position: absolute; + top: calc(100% - 215px); + width: 750px; + height: 55px; + font-size: 44px; + font-weight: bold; + font-family: "Riffic", "Signika", "LinLibertine", serif; + color: white; + -webkit-text-stroke-width: 1px; + -webkit-text-stroke-color: black; + text-shadow: 2px 2px #000; + pointer-events: none; + transition: left 0.5s ease; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.theatre-portrait-name-left { + text-indent: 0.5em; + left: 0; +} + +.theatre-portrait-name-right { + direction: rtl; + text-align: right; + text-indent: 0.5em; + left: 0; +} + +.theatre-portrait-name-align-top { + top: calc(100% - 55px); +} + +.theatre-portrait-name-speakingas { + animation: speakingas-name-pulse 1s linear 0.2s infinite alternate; +} + +.theatre-portrait-namespan { + vertical-align: top; +} + +.theatre-portrait-namebubble { + flex: 0 0 55px; + position: relative; + height: 55px; + border: none; + padding: 0px; + margin: 0px; + opacity: 0px; + top: 100%; + animation: typing-wiggle 0.5s linear 0.2s infinite alternate; + transition: opacity 0.5s ease-in-out, top 0.5s ease-in-out; +} + +.theatre-container-row { + flex: 1; + display: flex; + flex-direction: row; +} + +.theatre-container-tiles { + flex-wrap: wrap; + align-content: flex-start; + align-items: center; + justify-content: center; +} + +.theatre-container-column { + flex: 1; + display: flex; + flex-direction: column; + overflow: hidden; +} + +.theatre-command-group { + flex: 0 0 50px; + height: 100%; +} + +.theatre-content-box { + display: flex; + flex: 1; +} + +.theatre-text-box { + flex: 1; + position: relative; + display: flex; + font-size: 32px; + text-shadow: 2px 2px #000; + margin: 10px 0px 10px 0px; + padding-left: 10px; + align-content: flex-start; + font-family: "Signika", "Palatino Linotype", serif; + border-left: 4px double #333; + transition: opacity 1s ease-in-out; + flex-wrap: wrap; +} + +.theatre-text-box-light { + flex: 1; + position: relative; + display: flex; + font-size: 32px; + text-shadow: 2px 2px #000; + margin: 10px 0px 10px 0px; + padding-left: 10px; + align-content: flex-start; + font-family: "Signika", "Palatino Linotype", serif; + border-left: 1px dashed rgba(255, 255, 255, 0.1); + border-right: 1px dashed rgba(255, 255, 255, 0.1); + transition: opacity 1s ease-in-out; + flex-wrap: wrap; +} + +.theatre-text-box-clear { + flex: 1; + position: relative; + display: flex; + font-size: 32px; + text-shadow: 1px 1px 3px #000; + margin: 10px 0px 10px 0px; + padding-left: 10px; + border-radius: 5px; + align-content: flex-start; + font-family: "Signika", "Palatino Linotype", serif; + transition: opacity 1s ease-in-out, box-shadow 0.5s ease-in-out; + flex-wrap: wrap; +} + +.theatre-text-box-clear:hover { + box-shadow: inset 0px 0px 20px 2px white; +} + +.theatre-narrator-content div, +.theatre-text-box-light div, +.theatre-text-box-clear div, +.theatre-text-box div { + display: flex; + align-content: flex-start; +} + +.theatre-narrator-content hr, +.theatre-text-box-light hr, +.theatre-text-box-clear hr, +.theatre-text-box hr { + border: 0; + margin: 0; + padding: 0; + width: 100%; +} + +.darkapp { + background: url("../assets/graphics/denim95.png"); +} + +.theatre-narrator { + position: absolute; + top: calc(25% - 50px); + left: 0px; + display: flex; + width: calc(100% - 300px); + height: 200px; + pointer-events: none; + z-index: 1; + align-content: center; + justify-content: center; + align-items: center; + transition: opacity 0.5s ease-in-out; +} + +.theatre-narrator-backdrop { + position: relative; + display: flex; + width: 0%; + height: 100%; + align-content: center; + justify-content: center; + overflow: hidden; + transition: width 0.5s ease-in-out, opacity 0.5s ease-in-out; + background: linear-gradient(transparent 0%, rgba(0, 0, 0, 0.7) 40%, rgba(0, 0, 0, 0.7) 60%, transparent 100%); +} + +.theatre-narrator-content { + position: absolute; + top: 0px; + left: 0px; + width: calc(100% - 5em); + height: 100%; + display: flex; + margin: 0px 1em 0px 4em; + align-items: center; + justify-content: center; + z-index: 1; + font-family: "Signika", "Palatino Linotype", serif; + font-size: 28px; + font-weight: bold; + text-shadow: 3px 3px 2px black; + flex-wrap: wrap; + align-content: center; + color: white; + overflow-y: scroll; +} + +.theatre-control-group { + flex: 0 0 40px; + height: 40px; + display: flex; + margin: 2px 8px; +} + +.theatre-control-nav-bar { + flex: 1; + display: flex; + margin-right: 2px; + background: url("../../../../ui/denim065.png"); + border-radius: 5px; + border: 1px solid #212121; + overflow-y: hidden; +} + +.theatre-control-nav-bar-item { + flex: 0 0 36px; + width: 36px; + height: 36px; + object-fit: cover; + object-position: 50% 0; + box-sizing: content-box; + box-shadow: 0 0 10px #000; + border: 1px solid #000; + border-radius: 5px; + cursor: pointer; + transition: all 0.3s ease-in-out; +} + +.theatre-control-nav-bar-item:hover { + background: radial-gradient(closest-side at 50%, red 1%, transparent 99%); +} + +.theatre-control-nav-bar-item-active { + border: 1px solid red; + box-shadow: 0 0 6px inset #ff6400; + background: radial-gradient(closest-side at 50%, red 1%, transparent 99%); +} + +.theatre-control-nav-bar-item-active:hover, +.theatre-control-nav-bar-item:hover { + transform: scale(1.2, 1.2); +} + +.theatre-control-nav-bar-item-speakingas { + animation: speakingas-item-pulse 1s linear 0.2s infinite alternate; + background: radial-gradient(closest-side at 50%, #ff6400 1%, transparent 99%); +} + +.theatre-control-btn { + flex: 0 0 36px; + width: 36px; + height: 36px; + border-radius: 3px; +} + +.theatre-control-btn-down { + border: 1px solid red; + box-shadow: 0 0 6px inset #ff6400; + background: radial-gradient(closest-side at 50%, red 1%, transparent 99%); +} + +.theatre-control-small-btn-down { + border-left: 1px solid red; + border-right: 1px solid red; + box-shadow: 0 0 6px inset #ff6400; + background: radial-gradient(closest-side at 50%, red 1%, transparent 99%); +} + +.theatre-icon-suppress { + width: 100%; + height: 100%; + background-image: url("../assets/graphics/btn_suppress.png"); +} + +.theatre-icon-emote { + width: 100%; + height: 100%; + background-image: url("../assets/graphics/btn_emote.png"); +} + +.theatre-icon-fontsize-small { + width: 100%; + height: 100%; + background-image: url("../assets/graphics/btn_font_size_small.png"); +} + +.theatre-icon-fontsize-medium { + width: 100%; + height: 100%; + background-image: url("../assets/graphics/btn_font_size_medium.png"); +} + +.theatre-icon-fontsize-large { + width: 100%; + height: 100%; + background-image: url("../assets/graphics/btn_font_size_large.png"); +} + +.theatre-icon-cinema { + width: 100%; + height: 100%; + background-image: url("../assets/graphics/btn_cinema.png"); +} + +.theatre-icon-narrator { + width: 100%; + height: 100%; + background-image: url("../assets/graphics/btn_narrator.png"); +} + +.theatre-icon-live { + width: 100%; + height: 100%; + background-image: url("../assets/graphics/btn_live.png"); +} + +.theatre-control-btn:hover { + background: radial-gradient(closest-side at 50%, red 1%, transparent 99%); +} + +.theatre-control-chat-cover { + position: absolute; + top: 0px; + left: 0px; + height: 100%; + width: 100%; + pointer-events: none; +} + +.theatre-control-chat-cover img { + position: absolute; + top: 0px; + left: 0px; + height: 100%; + border: 0px; + margin: 0px; + padding: 0px; + object-fit: cover; + object-position: 50% 0; + opacity: 0.25; +} + +.theatre-control-chat-cover-ooc { + background-image: url("../assets/graphics/ooc.png"); + box-shadow: inset 0px 0px 10px 2px blue; +} + +.theatre-emote-menu { + display: none; + position: absolute; + top: 0px; + width: 300px; + height: 400px; +} + +.theatre-emote-menu .emote-box { + padding: 2px; + border-top: 4px double #222; + overflow: hidden; +} + +.theatre-emote-menu .textanims-box { + overflow: hidden; +} + +.theatre-emote-menu .textflyin-box { + padding: 2px; + margin-right: 1px; + border-right: 1px solid #222; + overflow: hidden; +} + +.theatre-emote-menu .textstanding-box { + padding: 2px; + margin-left: 1px; + border-left: 1px solid #222; + overflow: hidden; +} + +.theatre-emote-menu h2 { + color: #ffbb8e; + font-size: 26px; + font-family: "Riffic", "Signika", "Palatino Linotype", serif; + -webkit-text-stroke-width: 1px; + -webkit-text-stroke-color: black; + text-shadow: 2px 2px #000; + border-bottom: 2px dashed #888; +} + +.theatre-emote-menu .emote { + flex: 0 0 30px; + display: flex; + height: 30px; + width: 30px; + border-radius: 5px; + padding: 2px; + margin: 1px; + font-size: 26px; + align-items: center; + justify-content: center; + box-sizing: border-box; + text-align: center; + cursor: default; + font-family: "Signika"; + color: white; + cursor: pointer; + transition: all 0.3s ease-in-out; +} + +.theatre-emote-menu .emote-imgavail { + background: radial-gradient(closest-side at 50%, rgba(255, 100, 0, 0.75) 1%, transparent 99%); +} + +.theatre-emote-menu .textflyin-active, +.theatre-emote-menu .textstanding-active, +.theatre-emote-menu .emote-active { + border: 1px solid red; + box-shadow: 0 0 6px inset #ff6400; + background: radial-gradient(closest-side at 50%, red 1%, transparent 99%); +} + +.theatre-emote-menu .textanim:hover, +.theatre-emote-menu .emote:hover { + background: radial-gradient(closest-side at 50%, red 1%, transparent 99%); +} + +.theatre-emote-menu img { + width: 100%; + height: 100%; + border: 0; + padding: 0; + margin: 0; +} + +.theatre-emote-menu .textanim { + flex: 0 0 40px; + display: flex; + margin: 2px; + padding-left: 0; + border-left: 0; + font-family: "Signika", "Palatino Linotype", serif; + font-size: 18px; + text-shadow: 2px 2px #000; + align-items: center; + align-content: center; + justify-content: center; +} + +.theatre-emote-menu .textanim div, +.theatre-emote-menu .textanim span { + pointer-events: none; +} + +.emote-box .emotebar { + display: flex; + align-items: center; + justify-content: center; + border-bottom: 2px dashed #888; +} + +.emote-box h2 { + flex: 1; + border-bottom: none; + margin: 0; +} + +.emote-box .emotebar .fontselect { + flex: 2; + max-width: 120px; + color: white; + font-weight: bold; + padding: 0; + margin-left: 2px; + border: 1px solid #333; + background: url("../../../../ui/denim-light.png"); +} + +.emote-box .emotebar .fontselect option { + font-size: 20px; + background-color: rgba(0, 0, 0, 0.7); +} + +.emote-box .emotebar .sizeselect { + flex: 0 0 34px; + width: 34px; + height: 34px; + margin: 0; + padding: 0; +} + +.emote-box .emotebar .colorselect { + flex: 0 0 34px; + width: 34px; + height: 34px; + display: flex; + margin: 0; + padding: 0; + font-size: 22px; + background: none; + text-shadow: none; + align-items: center; + justify-content: center; + border: 1px solid #222; +} + +.theatre-tooltip { + display: flex; + position: absolute; + top: 0px; + left: 0px; + width: 150px; + height: 150px; + opacity: 0; + margin: 0; + padding: 0; + box-shadow: 0 0 20px #ff6400; + pointer-events: none; + transition: opacity 0.3s ease-in-out; + align-items: center; + justify-content: center; +} + +.theatre-tooltip canvas { + flex: 0 0 140px; + width: 140px; + height: 140px; + border-radius: 3px; +} + +.theatre-config-form-group { + position: relative; + height: 30px; + clear: both; + display: flex; + flex-direction: row; + flex-wrap: wrap; + margin: 3px 0; + transition: all 0.5s ease-in-out; +} + +.theatre-config-form-group>* { + flex: 3; +} + +.theatre-config-form-group>label { + flex: 2; + display: flex; + line-height: 24px; + align-items: center; +} + +.theatre-form-group .notes { + flex: 0 0 100%; + margin-top: 0; +} + +.theatre-config-tab-pane { + flex: 1; + height: 220px; + display: flex; + flex-direction: column; +} + +.theatre-emote-icon { + flex: 0 0 30px; + display: flex; + height: 30px; + width: 30px; + padding: 2px; + margin: 1px; + font-size: 26px; + align-items: center; + justify-content: center; + box-sizing: border-box; + text-align: center; + cursor: default; + font-family: "Signika"; + color: white; + background: url("../assets/graphics/denim95.png"); + border-radius: 3px; +} + +.theatre-config-form-group img { + width: 100%; + height: 100%; + border: 0; + padding: 0; + margin: 0; +} + +.theatre-config-emote-label { + position: relative; +} + +.theatre-config-emote-label-dock { + display: none; + position: absolute; + height: 30px; + width: 30px; + top: 0px; + left: calc(100% - 35px); + color: black; + border: 1px solid #aaa; + border-radius: 3px; + padding: 1px 6px; + align-items: center; + justify-content: center; + background: rgba(255, 255, 255, 0.75); +} + +.theatre-config-form-group[todelete="true"] { + border-radius: 3px; + margin: 2px; + background: rgba(255, 0, 0, 0.75); +} + +.theatre-config-form-group[todelete="true"] * { + pointer-events: none; +} + +.theatre-config-btn-add-emote { + width: 50%; + height: 30px; + margin: 2px 2px; + background: rgba(255, 255, 255, 0.75); + box-sizing: border-box; + border: 1px solid #aaa; + border-radius: 3px; + padding: 1px 6px; + align-items: flex-start; + text-align: center; + cursor: default; + font-size: 14px; + line-height: 28px; + font-family: "Signika"; +} + +.theatre-config-btn-add-emote:hover { + box-shadow: 0 0 5px red; +} + +.theatre-config-btn-edit-emote { + order: 100; + flex: 0; + width: 30px; + height: 30px; +} + +.theatre-config-tabs { + border-bottom: 1px solid #aaa; + height: 30px; +} + +.theatre-config-tab { + max-height: 650px; +} + +#chat-log { + height: calc(100% - 130px - 40px); +} + +#chat-form { + position: relative; +} + +/* BUG https://gitlab.com/foundrynet/foundryvtt/-/issues/3200#note_374466454*/ +/* #notifications { + pointer-events: none; } */ + +#pause { + transition: bottom 500ms ease 0ms; +} + +#pause.theatre-centered { + bottom: calc(50% - 50px); +} + +#players, +#hotbar { + transition: opacity 500ms ease 0ms; +} + +/* id.class is utilized to gain priority over styling rules of the "Minimal UI" module */ +#players.theatre-invisible, +#hotbar.theatre-invisible { + opacity: 0; + pointer-events: none; +} + +#hotbar.theatre-invisible #hotbar-directory-controls, +#hotbar.theatre-invisible #action-bar, +#hotbar.theatre-invisible #hotbar-page-controls { + pointer-events: none; +} + +#ui-left.z-higher, +#ui-middle.z-higher { + z-index: calc(var(--z-index-app) + 1); +} + +@-moz-document url-prefix() { + .emote-box .emotebar .colorselect { + padding: 3px; + } + + .emote-box .emotebar .fontselect option { + font-size: 16px; + } +}