From 5584730df2341898b60165608b4f6ed01adb8275 Mon Sep 17 00:00:00 2001 From: Jiminy Panoz Date: Mon, 24 Nov 2025 19:03:10 +0100 Subject: [PATCH 1/5] Update ReadiumCSS dep --- navigator/package.json | 2 +- pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/navigator/package.json b/navigator/package.json index 89b739d6..36ddf546 100644 --- a/navigator/package.json +++ b/navigator/package.json @@ -49,7 +49,7 @@ }, "devDependencies": { "@laynezh/vite-plugin-lib-assets": "^2.1.0", - "@readium/css": "2.0.0-beta.22", + "@readium/css": "2.0.0-beta.23", "@readium/navigator-html-injectables": "workspace:*", "@readium/shared": "workspace:*", "@types/path-browserify": "^1.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 46351d78..bafe7c71 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,8 +24,8 @@ importers: specifier: ^2.1.0 version: 2.1.0(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(less@4.4.1)(sass@1.91.0)(stylus@0.62.0)) '@readium/css': - specifier: 2.0.0-beta.22 - version: 2.0.0-beta.22 + specifier: 2.0.0-beta.23 + version: 2.0.0-beta.23 '@readium/navigator-html-injectables': specifier: workspace:* version: link:../navigator-html-injectables @@ -1264,8 +1264,8 @@ packages: '@readium/css@1.1.0': resolution: {integrity: sha512-vcUx/+UYlWXuG6ioZNVBFDlKCuyH+65x9dNJM9jLlA8yT5ReH0k2UR9DN8cwx5/BgJhoQLUsA9s2DPhGaMhX6A==} - '@readium/css@2.0.0-beta.22': - resolution: {integrity: sha512-mWQ5Rl7n74EofItTo+nKXHUjCMK57H+UYMtiuCX9PHED8wwaanmnQpNyWx9QL6a25iOMF4efg4+LKGrS8rIJjg==} + '@readium/css@2.0.0-beta.23': + resolution: {integrity: sha512-EzNSLA6y6Ng2WbCRY5gfoF/3pt6MYNjpMAeTp918zmxCZ8+nH1IvsrF6juz2ebJGO5sRG20nI3kE/waX6CknSA==} '@rollup/rollup-android-arm-eabi@4.50.1': resolution: {integrity: sha512-HJXwzoZN4eYTdD8bVV22DN8gsPCAj3V20NHKOs8ezfXanGpmVPR7kalUHd+Y31IJp9stdB87VKPFbsGY3H/2ag==} @@ -4086,7 +4086,7 @@ snapshots: '@readium/css@1.1.0': {} - '@readium/css@2.0.0-beta.22': {} + '@readium/css@2.0.0-beta.23': {} '@rollup/rollup-android-arm-eabi@4.50.1': optional: true From b021776a3303734ee1198dff20a5eac0e0b1e15e Mon Sep 17 00:00:00 2001 From: Jiminy Panoz Date: Mon, 24 Nov 2025 19:24:47 +0100 Subject: [PATCH 2/5] Implement experiments property in EPUB settings --- navigator/src/epub/css/Properties.ts | 12 +++++++++++- navigator/src/epub/css/ReadiumCSS.ts | 3 +++ navigator/src/epub/preferences/EpubDefaults.ts | 10 ++++++++-- navigator/src/epub/preferences/EpubSettings.ts | 8 ++++++-- navigator/src/preferences/Types.ts | 4 ++++ navigator/src/preferences/guards.ts | 15 +++++++++++++++ 6 files changed, 47 insertions(+), 5 deletions(-) diff --git a/navigator/src/epub/css/Properties.ts b/navigator/src/epub/css/Properties.ts index 4d7c1258..80a8dc3e 100644 --- a/navigator/src/epub/css/Properties.ts +++ b/navigator/src/epub/css/Properties.ts @@ -1,4 +1,4 @@ -import { TextAlignment } from "../../preferences/Types"; +import { ExperimentKey, TextAlignment } from "../../preferences/Types"; import { BodyHyphens, BoxSizing, @@ -214,6 +214,7 @@ export interface IRSProperties { textColor?: string | null; typeScale?: TypeScale | null; visitedColor?: string | null; + experiments?: Array | null; } export class RSProperties extends Properties { @@ -258,6 +259,7 @@ export class RSProperties extends Properties { textColor: string | null; typeScale: TypeScale | null; visitedColor: string | null; + experiments: Array | null; constructor(props: IRSProperties) { super(); @@ -302,6 +304,7 @@ export class RSProperties extends Properties { this.textColor = props.textColor ?? null; this.typeScale = props.typeScale ?? null; this.visitedColor = props.visitedColor ?? null; + this.experiments = props.experiments ?? null; } toCSSProperties(): { [key: string]: string; } { @@ -349,6 +352,13 @@ export class RSProperties extends Properties { if (this.typeScale) cssProperties["--RS__typeScale"] = this.toUnitless(this.typeScale); if (this.visitedColor) cssProperties["--RS__visitedColor"] = this.visitedColor; + if (this.experiments) { + this.experiments.forEach((experiment) => { + // Shortcut as we know it is the RS scope and can use toFlag + cssProperties["--RS__" + experiment] = this.toFlag(experiment); + }); + }; + return cssProperties; } } \ No newline at end of file diff --git a/navigator/src/epub/css/ReadiumCSS.ts b/navigator/src/epub/css/ReadiumCSS.ts index 9b14b9a1..a03bd777 100644 --- a/navigator/src/epub/css/ReadiumCSS.ts +++ b/navigator/src/epub/css/ReadiumCSS.ts @@ -54,6 +54,9 @@ export class ReadiumCSS { if (settings.scrollPaddingTop !== this.rsProperties.scrollPaddingTop) this.rsProperties.scrollPaddingTop = settings.scrollPaddingTop; + if (settings.experiments !== this.rsProperties.experiments) + this.rsProperties.experiments = settings.experiments; + // This has to be updated before pagination // otherwise the metrics won’t be correct for line length this.lineLengths.update({ diff --git a/navigator/src/epub/preferences/EpubDefaults.ts b/navigator/src/epub/preferences/EpubDefaults.ts index 7170a0ff..e2495942 100644 --- a/navigator/src/epub/preferences/EpubDefaults.ts +++ b/navigator/src/epub/preferences/EpubDefaults.ts @@ -1,4 +1,5 @@ import { + ExperimentKey, fontSizeRangeConfig, fontWeightRangeConfig, fontWidthRangeConfig, @@ -8,13 +9,14 @@ import { import { ensureBoolean, ensureEnumValue, + ensureExperiment, ensureFilter, ensureLessThanOrEqual, ensureMoreThanOrEqual, ensureNonNegative, ensureString, ensureValueInRange, - withFallback + withFallback } from "../../preferences/guards"; import { sMLWithRequest } from "../../helpers"; @@ -59,7 +61,8 @@ export interface IEpubDefaults { textColor?: string | null, textNormalization?: boolean | null, visitedColor?: string | null, - wordSpacing?: number | null + wordSpacing?: number | null, + experiments?: Array | null } export class EpubDefaults { @@ -103,6 +106,7 @@ export class EpubDefaults { textNormalization: boolean | null; visitedColor: string | null; wordSpacing: number | null; + experiments: Array | null; constructor(defaults: IEpubDefaults) { this.backgroundColor = ensureString(defaults.backgroundColor) || null; @@ -153,5 +157,7 @@ export class EpubDefaults { this.optimalLineLength = ensureNonNegative(defaults.optimalLineLength) || 65; this.maximalLineLength = withFallback(ensureMoreThanOrEqual(defaults.maximalLineLength, this.optimalLineLength), 80); this.minimalLineLength = withFallback(ensureLessThanOrEqual(defaults.minimalLineLength, this.optimalLineLength), 40); + + this.experiments = ensureExperiment(defaults.experiments) || null; } } \ No newline at end of file diff --git a/navigator/src/epub/preferences/EpubSettings.ts b/navigator/src/epub/preferences/EpubSettings.ts index 92676b38..4bd843a8 100644 --- a/navigator/src/epub/preferences/EpubSettings.ts +++ b/navigator/src/epub/preferences/EpubSettings.ts @@ -1,5 +1,5 @@ import { ConfigurableSettings } from "../../preferences/Configurable"; -import { TextAlignment } from "../../preferences/Types"; +import { ExperimentKey, TextAlignment } from "../../preferences/Types"; import { EpubDefaults } from "./EpubDefaults"; import { EpubPreferences } from "./EpubPreferences"; @@ -45,7 +45,8 @@ export interface IEpubSettings { textColor?: string | null, textNormalization?: boolean | null, visitedColor?: string | null, - wordSpacing?: number | null + wordSpacing?: number | null, + experiments?: Array | null } export class EpubSettings implements ConfigurableSettings { @@ -89,6 +90,7 @@ export class EpubSettings implements ConfigurableSettings { textNormalization: boolean | null; visitedColor: string | null; wordSpacing: number | null; + experiments: Array | null; constructor(preferences: EpubPreferences, defaults: EpubDefaults) { this.backgroundColor = preferences.backgroundColor || defaults.backgroundColor || null; @@ -229,5 +231,7 @@ export class EpubSettings implements ConfigurableSettings { : defaults.wordSpacing !== undefined ? defaults.wordSpacing : null; + + this.experiments = defaults.experiments || null; } } \ No newline at end of file diff --git a/navigator/src/preferences/Types.ts b/navigator/src/preferences/Types.ts index aec35048..acd2c167 100644 --- a/navigator/src/preferences/Types.ts +++ b/navigator/src/preferences/Types.ts @@ -1,3 +1,7 @@ +import experiments from "@readium/css/css/vars/experiments.json"; + +export type ExperimentKey = keyof typeof experiments; + export enum TextAlignment { start = "start", left = "left", diff --git a/navigator/src/preferences/guards.ts b/navigator/src/preferences/guards.ts index 1bd2ed52..51e200e5 100644 --- a/navigator/src/preferences/guards.ts +++ b/navigator/src/preferences/guards.ts @@ -1,3 +1,6 @@ +import experiments from "@readium/css/css/vars/experiments.json"; +import { ExperimentKey } from './Types'; + export function ensureLessThanOrEqual(value: T, compareTo: T): T | undefined { if (value === undefined || value === null) { return value; @@ -83,3 +86,15 @@ export function ensureValueInRange(value: number | null | undefined, range: [num export function withFallback(value: T | null | undefined, defaultValue: T | null): T | null { return value === undefined ? defaultValue : value; } + +export function ensureExperiment( + experimentsInput: ExperimentKey[] | null | undefined +): ExperimentKey[] | null | undefined { + if (experimentsInput === undefined) { + return undefined; + } + if (experimentsInput === null) { + return null; + } + return experimentsInput.filter(exp => exp in experiments); +} \ No newline at end of file From 3af9d8aefe39fd7d512c6f6d9da92dfde9dd93ec Mon Sep 17 00:00:00 2001 From: Jiminy Panoz Date: Mon, 24 Nov 2025 19:36:19 +0100 Subject: [PATCH 3/5] Add experiments + RSProps to WebPub --- navigator/src/webpub/WebPubNavigator.ts | 10 ++++++- navigator/src/webpub/css/Properties.ts | 28 ++++++++++++++++++- navigator/src/webpub/css/WebPubCSS.ts | 9 +++++- .../src/webpub/preferences/WebPubDefaults.ts | 9 ++++-- .../src/webpub/preferences/WebPubSettings.ts | 8 ++++-- 5 files changed, 57 insertions(+), 7 deletions(-) diff --git a/navigator/src/webpub/WebPubNavigator.ts b/navigator/src/webpub/WebPubNavigator.ts index aaddd62f..ffacb534 100644 --- a/navigator/src/webpub/WebPubNavigator.ts +++ b/navigator/src/webpub/WebPubNavigator.ts @@ -8,12 +8,13 @@ import { WebPubFrameManager } from "./WebPubFrameManager"; import { ManagerEventKey } from "../epub/EpubNavigator"; import { WebPubCSS } from "./css/WebPubCSS"; -import { WebUserProperties } from "./css/Properties"; +import { WebUserProperties, WebRSProperties } from "./css/Properties"; import { IWebPubPreferences, WebPubPreferences } from "./preferences/WebPubPreferences"; import { IWebPubDefaults, WebPubDefaults } from "./preferences/WebPubDefaults"; import { WebPubSettings } from "./preferences/WebPubSettings"; import { IPreferencesEditor } from "../preferences/PreferencesEditor"; import { WebPubPreferencesEditor } from "./preferences/WebPubPreferencesEditor"; + export interface WebPubNavigatorConfiguration { preferences: IWebPubPreferences; defaults: IWebPubDefaults; @@ -74,6 +75,7 @@ export class WebPubNavigator extends VisualNavigator implements Configurable | null; +} + +export class WebRSProperties extends Properties { + experiments: Array | null; + + constructor(props: IWebRSProperties) { + super(); + this.experiments = props.experiments ?? null; + } + + toCSSProperties() { + const cssProperties: { [key: string]: string } = {}; + + if (this.experiments) { + this.experiments.forEach((experiment) => { + // Shortcut as we know it is the RS scope and can use toFlag + cssProperties["--RS__" + experiment] = this.toFlag(experiment); + }); + }; + + return cssProperties; + } +} \ No newline at end of file diff --git a/navigator/src/webpub/css/WebPubCSS.ts b/navigator/src/webpub/css/WebPubCSS.ts index 754caa13..a9f38d19 100644 --- a/navigator/src/webpub/css/WebPubCSS.ts +++ b/navigator/src/webpub/css/WebPubCSS.ts @@ -1,18 +1,25 @@ import { WebPubSettings } from "../preferences/WebPubSettings"; -import { IWebUserProperties, WebUserProperties } from "./Properties"; +import { IWebUserProperties, WebRSProperties, WebUserProperties } from "./Properties"; export interface IWebPubCSS { + rsProperties: WebRSProperties; userProperties: WebUserProperties; } export class WebPubCSS { + rsProperties: WebRSProperties; userProperties: WebUserProperties; constructor(props: IWebPubCSS) { + this.rsProperties = props.rsProperties; this.userProperties = props.userProperties; } update(settings: WebPubSettings) { + if (settings.experiments) { + this.rsProperties.experiments = settings.experiments; + } + const updated: IWebUserProperties = { a11yNormalize: settings.textNormalization, bodyHyphens: typeof settings.hyphens !== "boolean" diff --git a/navigator/src/webpub/preferences/WebPubDefaults.ts b/navigator/src/webpub/preferences/WebPubDefaults.ts index f299d441..153b13e4 100644 --- a/navigator/src/webpub/preferences/WebPubDefaults.ts +++ b/navigator/src/webpub/preferences/WebPubDefaults.ts @@ -1,4 +1,5 @@ import { + ExperimentKey, fontWeightRangeConfig, TextAlignment, zoomRangeConfig @@ -9,7 +10,8 @@ import { ensureEnumValue, ensureNonNegative, ensureValueInRange, - ensureString + ensureString, + ensureExperiment } from "../../preferences/guards"; import { sMLWithRequest } from "../../helpers"; @@ -29,7 +31,8 @@ export interface IWebPubDefaults { textAlign?: TextAlignment | null, textNormalization?: boolean | null, wordSpacing?: number | null, - zoom?: number | null + zoom?: number | null, + experiments?: Array | null, } export class WebPubDefaults { @@ -48,6 +51,7 @@ export class WebPubDefaults { textNormalization: boolean | null; wordSpacing: number | null; zoom: number; + experiments: Array | null; constructor(defaults: IWebPubDefaults) { this.fontFamily = ensureString(defaults.fontFamily) || null; @@ -69,5 +73,6 @@ export class WebPubDefaults { this.textNormalization = ensureBoolean(defaults.textNormalization) ?? false; this.wordSpacing = ensureNonNegative(defaults.wordSpacing) || null; this.zoom = ensureValueInRange(defaults.zoom, zoomRangeConfig.range) || 1; + this.experiments = ensureExperiment(defaults.experiments) ?? null; } } \ No newline at end of file diff --git a/navigator/src/webpub/preferences/WebPubSettings.ts b/navigator/src/webpub/preferences/WebPubSettings.ts index 1214b2a7..15b4da1e 100644 --- a/navigator/src/webpub/preferences/WebPubSettings.ts +++ b/navigator/src/webpub/preferences/WebPubSettings.ts @@ -1,5 +1,5 @@ import { ConfigurableSettings } from "../../preferences/Configurable"; -import { TextAlignment } from "../../preferences/Types"; +import { ExperimentKey, TextAlignment } from "../../preferences/Types"; import { WebPubDefaults } from "./WebPubDefaults"; import { WebPubPreferences } from "./WebPubPreferences"; @@ -20,7 +20,8 @@ export interface IWebPubSettings { textAlign?: TextAlignment | null, textNormalization?: boolean | null, wordSpacing?: number | null, - zoom?: number | null; + zoom?: number | null, + experiments?: Array | null, } export class WebPubSettings implements ConfigurableSettings { @@ -39,6 +40,7 @@ export class WebPubSettings implements ConfigurableSettings { textNormalization: boolean | null = null; wordSpacing: number | null = null; zoom: number | null; + experiments: Array | null; constructor(preferences: WebPubPreferences, defaults: WebPubDefaults, hasDisplayTransformability: boolean) { if (hasDisplayTransformability) { @@ -103,5 +105,7 @@ export class WebPubSettings implements ConfigurableSettings { : defaults.zoom !== undefined ? defaults.zoom : null; + + this.experiments = defaults.experiments || null; } } \ No newline at end of file From 4c237948f9c9f5773d4a391ffde3860e175c1f72 Mon Sep 17 00:00:00 2001 From: Jiminy Panoz Date: Tue, 25 Nov 2025 07:52:12 +0100 Subject: [PATCH 4/5] Use experiments value --- navigator/src/epub/css/Properties.ts | 7 +++---- navigator/src/preferences/Types.ts | 6 ++++-- navigator/src/preferences/guards.ts | 7 ++----- navigator/src/webpub/css/Properties.ts | 7 +++---- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/navigator/src/epub/css/Properties.ts b/navigator/src/epub/css/Properties.ts index 80a8dc3e..4d2e8db5 100644 --- a/navigator/src/epub/css/Properties.ts +++ b/navigator/src/epub/css/Properties.ts @@ -1,4 +1,4 @@ -import { ExperimentKey, TextAlignment } from "../../preferences/Types"; +import { ExperimentKey, experiments, TextAlignment } from "../../preferences/Types"; import { BodyHyphens, BoxSizing, @@ -353,9 +353,8 @@ export class RSProperties extends Properties { if (this.visitedColor) cssProperties["--RS__visitedColor"] = this.visitedColor; if (this.experiments) { - this.experiments.forEach((experiment) => { - // Shortcut as we know it is the RS scope and can use toFlag - cssProperties["--RS__" + experiment] = this.toFlag(experiment); + this.experiments.forEach((exp) => { + cssProperties["--RS__" + exp] = experiments[exp].value; }); }; diff --git a/navigator/src/preferences/Types.ts b/navigator/src/preferences/Types.ts index acd2c167..7e1a3140 100644 --- a/navigator/src/preferences/Types.ts +++ b/navigator/src/preferences/Types.ts @@ -1,6 +1,8 @@ -import experiments from "@readium/css/css/vars/experiments.json"; +import RCSSExperiments from "@readium/css/css/vars/experiments.json"; -export type ExperimentKey = keyof typeof experiments; +export type ExperimentKey = keyof typeof RCSSExperiments; + +export const experiments = RCSSExperiments; export enum TextAlignment { start = "start", diff --git a/navigator/src/preferences/guards.ts b/navigator/src/preferences/guards.ts index 51e200e5..eb960335 100644 --- a/navigator/src/preferences/guards.ts +++ b/navigator/src/preferences/guards.ts @@ -1,5 +1,4 @@ -import experiments from "@readium/css/css/vars/experiments.json"; -import { ExperimentKey } from './Types'; +import { ExperimentKey, experiments } from './Types'; export function ensureLessThanOrEqual(value: T, compareTo: T): T | undefined { if (value === undefined || value === null) { @@ -87,9 +86,7 @@ export function withFallback(value: T | null | undefined, defaultValue: T | n return value === undefined ? defaultValue : value; } -export function ensureExperiment( - experimentsInput: ExperimentKey[] | null | undefined -): ExperimentKey[] | null | undefined { +export function ensureExperiment(experimentsInput: ExperimentKey[] | null | undefined): ExperimentKey[] | null | undefined { if (experimentsInput === undefined) { return undefined; } diff --git a/navigator/src/webpub/css/Properties.ts b/navigator/src/webpub/css/Properties.ts index 7b2fcdd3..c701c12c 100644 --- a/navigator/src/webpub/css/Properties.ts +++ b/navigator/src/webpub/css/Properties.ts @@ -1,4 +1,4 @@ -import { ExperimentKey, TextAlignment } from "../../preferences/Types"; +import { ExperimentKey, experiments, TextAlignment } from "../../preferences/Types"; import { BodyHyphens, Ligatures, Properties } from "../../css/Properties"; export interface IWebUserProperties { @@ -94,9 +94,8 @@ export class WebRSProperties extends Properties { const cssProperties: { [key: string]: string } = {}; if (this.experiments) { - this.experiments.forEach((experiment) => { - // Shortcut as we know it is the RS scope and can use toFlag - cssProperties["--RS__" + experiment] = this.toFlag(experiment); + this.experiments.forEach((exp) => { + cssProperties["--RS__" + exp] = experiments[exp].value; }); }; From ff9e13de791799036e46abd988e133dcf6f1c63f Mon Sep 17 00:00:00 2001 From: Jiminy Panoz Date: Tue, 25 Nov 2025 10:35:06 +0100 Subject: [PATCH 5/5] Update ReadiumCSS --- navigator/package.json | 2 +- pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/navigator/package.json b/navigator/package.json index 36ddf546..d8c1b39a 100644 --- a/navigator/package.json +++ b/navigator/package.json @@ -49,7 +49,7 @@ }, "devDependencies": { "@laynezh/vite-plugin-lib-assets": "^2.1.0", - "@readium/css": "2.0.0-beta.23", + "@readium/css": "2.0.0-beta.24", "@readium/navigator-html-injectables": "workspace:*", "@readium/shared": "workspace:*", "@types/path-browserify": "^1.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bafe7c71..f72238a7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,8 +24,8 @@ importers: specifier: ^2.1.0 version: 2.1.0(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(less@4.4.1)(sass@1.91.0)(stylus@0.62.0)) '@readium/css': - specifier: 2.0.0-beta.23 - version: 2.0.0-beta.23 + specifier: 2.0.0-beta.24 + version: 2.0.0-beta.24 '@readium/navigator-html-injectables': specifier: workspace:* version: link:../navigator-html-injectables @@ -1264,8 +1264,8 @@ packages: '@readium/css@1.1.0': resolution: {integrity: sha512-vcUx/+UYlWXuG6ioZNVBFDlKCuyH+65x9dNJM9jLlA8yT5ReH0k2UR9DN8cwx5/BgJhoQLUsA9s2DPhGaMhX6A==} - '@readium/css@2.0.0-beta.23': - resolution: {integrity: sha512-EzNSLA6y6Ng2WbCRY5gfoF/3pt6MYNjpMAeTp918zmxCZ8+nH1IvsrF6juz2ebJGO5sRG20nI3kE/waX6CknSA==} + '@readium/css@2.0.0-beta.24': + resolution: {integrity: sha512-vBI5Sw6JwlbTuDBvcD/ahJZqw2NGe1CDGQ7msAByc/491Q8V76baCkYIMFWyj5gPS1GS9oltlmIAWZAzxx3djg==} '@rollup/rollup-android-arm-eabi@4.50.1': resolution: {integrity: sha512-HJXwzoZN4eYTdD8bVV22DN8gsPCAj3V20NHKOs8ezfXanGpmVPR7kalUHd+Y31IJp9stdB87VKPFbsGY3H/2ag==} @@ -4086,7 +4086,7 @@ snapshots: '@readium/css@1.1.0': {} - '@readium/css@2.0.0-beta.23': {} + '@readium/css@2.0.0-beta.24': {} '@rollup/rollup-android-arm-eabi@4.50.1': optional: true