@readium/navigator 2.4.0-beta.9 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/dist/index.js +597 -451
  2. package/dist/index.umd.cjs +190 -127
  3. package/package.json +2 -2
  4. package/src/audio/AudioNavigator.ts +155 -42
  5. package/src/audio/AudioPoolManager.ts +27 -14
  6. package/src/audio/engine/AudioEngine.ts +4 -3
  7. package/src/audio/engine/PreservePitchProcessor.js +166 -101
  8. package/src/audio/engine/PreservePitchWorklet.ts +2 -17
  9. package/src/audio/engine/WebAudioEngine.ts +138 -160
  10. package/src/audio/engine/index.ts +2 -2
  11. package/src/audio/index.ts +3 -3
  12. package/src/audio/preferences/AudioDefaults.ts +2 -2
  13. package/src/audio/preferences/AudioPreferences.ts +11 -11
  14. package/src/audio/preferences/AudioPreferencesEditor.ts +13 -13
  15. package/src/audio/preferences/AudioSettings.ts +3 -3
  16. package/src/audio/preferences/index.ts +4 -4
  17. package/src/audio/protection/AudioNavigatorProtector.ts +4 -4
  18. package/src/css/index.ts +1 -1
  19. package/src/epub/EpubNavigator.ts +52 -52
  20. package/src/epub/css/Properties.ts +15 -15
  21. package/src/epub/css/ReadiumCSS.ts +43 -43
  22. package/src/epub/css/index.ts +2 -2
  23. package/src/epub/frame/FrameBlobBuilder.ts +10 -11
  24. package/src/epub/frame/FrameComms.ts +1 -1
  25. package/src/epub/frame/FrameManager.ts +9 -9
  26. package/src/epub/frame/FramePoolManager.ts +13 -13
  27. package/src/epub/frame/index.ts +4 -4
  28. package/src/epub/fxl/FXLCoordinator.ts +3 -3
  29. package/src/epub/fxl/FXLFrameManager.ts +8 -8
  30. package/src/epub/fxl/FXLFramePoolManager.ts +13 -13
  31. package/src/epub/fxl/FXLPeripherals.ts +4 -4
  32. package/src/epub/fxl/index.ts +5 -5
  33. package/src/epub/index.ts +5 -5
  34. package/src/epub/preferences/EpubDefaults.ts +23 -23
  35. package/src/epub/preferences/EpubPreferences.ts +16 -16
  36. package/src/epub/preferences/EpubPreferencesEditor.ts +53 -53
  37. package/src/epub/preferences/EpubSettings.ts +101 -101
  38. package/src/epub/preferences/index.ts +4 -4
  39. package/src/helpers/index.ts +2 -2
  40. package/src/index.ts +8 -8
  41. package/src/injection/Injector.ts +42 -42
  42. package/src/injection/epubInjectables.ts +8 -8
  43. package/src/injection/index.ts +2 -2
  44. package/src/injection/webpubInjectables.ts +1 -1
  45. package/src/preferences/Configurable.ts +2 -2
  46. package/src/preferences/PreferencesEditor.ts +2 -2
  47. package/src/preferences/guards.ts +2 -2
  48. package/src/preferences/index.ts +5 -5
  49. package/src/protection/CopyProtector.ts +5 -1
  50. package/src/protection/DevToolsDetector.ts +16 -16
  51. package/src/protection/DragAndDropProtector.ts +14 -1
  52. package/src/protection/NavigatorProtector.ts +6 -6
  53. package/src/webpub/WebPubBlobBuilder.ts +1 -1
  54. package/src/webpub/WebPubFrameManager.ts +8 -8
  55. package/src/webpub/WebPubFramePoolManager.ts +7 -7
  56. package/src/webpub/WebPubNavigator.ts +27 -27
  57. package/src/webpub/css/Properties.ts +3 -3
  58. package/src/webpub/css/WebPubCSS.ts +11 -11
  59. package/src/webpub/css/index.ts +2 -2
  60. package/src/webpub/index.ts +6 -6
  61. package/src/webpub/preferences/WebPubDefaults.ts +12 -12
  62. package/src/webpub/preferences/WebPubPreferences.ts +8 -8
  63. package/src/webpub/preferences/WebPubPreferencesEditor.ts +31 -31
  64. package/src/webpub/preferences/WebPubSettings.ts +45 -45
  65. package/src/webpub/preferences/index.ts +4 -4
  66. package/types/src/audio/AudioNavigator.d.ts +34 -5
  67. package/types/src/audio/AudioPoolManager.d.ts +7 -4
  68. package/types/src/audio/engine/AudioEngine.d.ts +4 -3
  69. package/types/src/audio/engine/PreservePitchWorklet.d.ts +1 -4
  70. package/types/src/audio/engine/WebAudioEngine.d.ts +15 -9
  71. package/types/src/audio/engine/index.d.ts +2 -2
  72. package/types/src/audio/index.d.ts +3 -3
  73. package/types/src/audio/preferences/AudioPreferences.d.ts +9 -9
  74. package/types/src/audio/preferences/AudioPreferencesEditor.d.ts +4 -4
  75. package/types/src/audio/preferences/AudioSettings.d.ts +3 -3
  76. package/types/src/audio/preferences/index.d.ts +4 -4
  77. package/types/src/audio/protection/AudioNavigatorProtector.d.ts +2 -2
  78. package/types/src/css/index.d.ts +1 -1
  79. package/types/src/epub/EpubNavigator.d.ts +11 -11
  80. package/types/src/epub/css/Properties.d.ts +2 -2
  81. package/types/src/epub/css/ReadiumCSS.d.ts +3 -3
  82. package/types/src/epub/css/index.d.ts +2 -2
  83. package/types/src/epub/frame/FrameBlobBuilder.d.ts +1 -1
  84. package/types/src/epub/frame/FrameComms.d.ts +1 -1
  85. package/types/src/epub/frame/FrameManager.d.ts +2 -2
  86. package/types/src/epub/frame/FramePoolManager.d.ts +3 -3
  87. package/types/src/epub/frame/index.d.ts +4 -4
  88. package/types/src/epub/fxl/FXLFrameManager.d.ts +3 -3
  89. package/types/src/epub/fxl/FXLFramePoolManager.d.ts +5 -5
  90. package/types/src/epub/fxl/FXLPeripherals.d.ts +2 -2
  91. package/types/src/epub/fxl/index.d.ts +5 -5
  92. package/types/src/epub/index.d.ts +5 -5
  93. package/types/src/epub/preferences/EpubDefaults.d.ts +1 -1
  94. package/types/src/epub/preferences/EpubPreferences.d.ts +2 -2
  95. package/types/src/epub/preferences/EpubPreferencesEditor.d.ts +5 -5
  96. package/types/src/epub/preferences/EpubSettings.d.ts +4 -4
  97. package/types/src/epub/preferences/index.d.ts +4 -4
  98. package/types/src/helpers/index.d.ts +2 -2
  99. package/types/src/index.d.ts +8 -8
  100. package/types/src/injection/Injector.d.ts +1 -1
  101. package/types/src/injection/epubInjectables.d.ts +1 -1
  102. package/types/src/injection/index.d.ts +2 -2
  103. package/types/src/preferences/Configurable.d.ts +1 -1
  104. package/types/src/preferences/PreferencesEditor.d.ts +1 -1
  105. package/types/src/preferences/guards.d.ts +1 -1
  106. package/types/src/preferences/index.d.ts +5 -5
  107. package/types/src/protection/CopyProtector.d.ts +1 -0
  108. package/types/src/protection/DragAndDropProtector.d.ts +2 -0
  109. package/types/src/protection/NavigatorProtector.d.ts +1 -1
  110. package/types/src/webpub/WebPubBlobBuilder.d.ts +1 -1
  111. package/types/src/webpub/WebPubFrameManager.d.ts +2 -2
  112. package/types/src/webpub/WebPubFramePoolManager.d.ts +3 -3
  113. package/types/src/webpub/WebPubNavigator.d.ts +10 -10
  114. package/types/src/webpub/css/Properties.d.ts +2 -2
  115. package/types/src/webpub/css/WebPubCSS.d.ts +2 -2
  116. package/types/src/webpub/css/index.d.ts +2 -2
  117. package/types/src/webpub/index.d.ts +6 -6
  118. package/types/src/webpub/preferences/WebPubDefaults.d.ts +1 -1
  119. package/types/src/webpub/preferences/WebPubPreferences.d.ts +2 -2
  120. package/types/src/webpub/preferences/WebPubPreferencesEditor.d.ts +5 -5
  121. package/types/src/webpub/preferences/WebPubSettings.d.ts +4 -4
  122. package/types/src/webpub/preferences/index.d.ts +4 -4
package/dist/index.js CHANGED
@@ -56,15 +56,15 @@ const C = class C {
56
56
  };
57
57
  C.AUDITORY = new C("auditory"), C.CHART_ON_VISUAL = new C("chartOnVisual"), C.CHEM_ON_VISUAL = new C("chemOnVisual"), C.COLOR_DEPENDENT = new C("colorDependent"), C.DIAGRAM_ON_VISUAL = new C("diagramOnVisual"), C.MATH_ON_VISUAL = new C("mathOnVisual"), C.MUSIC_ON_VISUAL = new C("musicOnVisual"), C.TACTILE = new C("tactile"), C.TEXT_ON_VISUAL = new C("textOnVisual"), C.TEXTUAL = new C("textual"), C.VISUAL = new C("visual");
58
58
  let $e = C;
59
- const F = class F {
59
+ const N = class N {
60
60
  constructor(t) {
61
61
  if (typeof t == "string") {
62
- if (!F.VALID_MODES.has(t.toLowerCase()))
62
+ if (!N.VALID_MODES.has(t.toLowerCase()))
63
63
  return;
64
64
  this.value = t.toLowerCase();
65
65
  } else {
66
66
  const e = t.filter(
67
- (i) => F.VALID_MODES.has(i.toLowerCase())
67
+ (i) => N.VALID_MODES.has(i.toLowerCase())
68
68
  );
69
69
  if (e.length === 0)
70
70
  return;
@@ -77,11 +77,11 @@ const F = class F {
77
77
  static deserialize(t) {
78
78
  if (!t) return;
79
79
  if (typeof t == "string")
80
- return new F(t);
80
+ return new N(t);
81
81
  if (!Array.isArray(t)) return;
82
- const e = t.filter((i) => i ? F.VALID_MODES.has(i.toLowerCase()) : !1);
82
+ const e = t.filter((i) => i ? N.VALID_MODES.has(i.toLowerCase()) : !1);
83
83
  if (e.length !== 0)
84
- return new F(e);
84
+ return new N(e);
85
85
  }
86
86
  /**
87
87
  * Serializes a [PrimaryAccessMode] to its RWPM JSON representation.
@@ -90,8 +90,8 @@ const F = class F {
90
90
  return this.value;
91
91
  }
92
92
  };
93
- F.VALID_MODES = /* @__PURE__ */ new Set(["auditory", "tactile", "textual", "visual"]), F.AUDITORY = new F("auditory"), F.TACTILE = new F("tactile"), F.TEXTUAL = new F("textual"), F.VISUAL = new F("visual");
94
- let Xe = F;
93
+ N.VALID_MODES = /* @__PURE__ */ new Set(["auditory", "tactile", "textual", "visual"]), N.AUDITORY = new N("auditory"), N.TACTILE = new N("tactile"), N.TEXTUAL = new N("textual"), N.VISUAL = new N("visual");
94
+ let Xe = N;
95
95
  const f = class f {
96
96
  constructor(t) {
97
97
  this.value = t;
@@ -111,8 +111,8 @@ const f = class f {
111
111
  }
112
112
  };
113
113
  f.NONE = new f("none"), f.ANNOTATIONS = new f("annotations"), f.ARIA = new f("ARIA"), f.INDEX = new f("index"), f.PAGE_BREAK_MARKERS = new f("pageBreakMarkers"), f.PAGE_NAVIGATION = new f("pageNavigation"), f.PRINT_PAGE_NUMBERS = new f("printPageNumbers"), f.READING_ORDER = new f("readingOrder"), f.STRUCTURAL_NAVIGATION = new f("structuralNavigation"), f.TABLE_OF_CONTENTS = new f("tableOfContents"), f.TAGGED_PDF = new f("taggedPDF"), f.ALTERNATIVE_TEXT = new f("alternativeText"), f.AUDIO_DESCRIPTION = new f("audioDescription"), f.CAPTIONS = new f("captions"), f.CLOSED_CAPTIONS = new f("closedCaptions"), f.DESCRIBED_MATH = new f("describedMath"), f.LONG_DESCRIPTION = new f("longDescription"), f.OPEN_CAPTIONS = new f("openCaptions"), f.SIGN_LANGUAGE = new f("signLanguage"), f.TRANSCRIPT = new f("transcript"), f.DISPLAY_TRANSFORMABILITY = new f("displayTransformability"), f.SYNCHRONIZED_AUDIO_TEXT = new f("synchronizedAudioText"), f.TIMING_CONTROL = new f("timingControl"), f.UNLOCKED = new f("unlocked"), f.CHEM_ML = new f("ChemML"), f.LATEX = new f("latex"), f.LATEX_CHEMISTRY = new f("latex-chemistry"), f.MATH_ML = new f("MathML"), f.MATH_ML_CHEMISTRY = new f("MathML-chemistry"), f.TTS_MARKUP = new f("ttsMarkup"), f.HIGH_CONTRAST_AUDIO = new f("highContrastAudio"), f.HIGH_CONTRAST_DISPLAY = new f("highContrastDisplay"), f.LARGE_PRINT = new f("largePrint"), f.BRAILLE = new f("braille"), f.TACTILE_GRAPHIC = new f("tactileGraphic"), f.TACTILE_OBJECT = new f("tactileObject"), f.FULL_RUBY_ANNOTATIONS = new f("fullRubyAnnotations"), f.HORIZONTAL_WRITING = new f("horizontalWriting"), f.RUBY_ANNOTATIONS = new f("rubyAnnotations"), f.VERTICAL_WRITING = new f("verticalWriting"), f.WITH_ADDITIONAL_WORD_SEGMENTATION = new f("withAdditionalWordSegmentation"), f.WITHOUT_ADDITIONAL_WORD_SEGMENTATION = new f("withoutAdditionalWordSegmentation");
114
- let Ut = f;
115
- const x = class x {
114
+ let It = f;
115
+ const R = class R {
116
116
  constructor(t) {
117
117
  this.value = t;
118
118
  }
@@ -121,7 +121,7 @@ const x = class x {
121
121
  */
122
122
  static deserialize(t) {
123
123
  if (!(!t || typeof t != "string"))
124
- return new x(t);
124
+ return new R(t);
125
125
  }
126
126
  /**
127
127
  * Serializes a [Hazard] to its RWPM JSON representation.
@@ -130,8 +130,8 @@ const x = class x {
130
130
  return this.value;
131
131
  }
132
132
  };
133
- x.FLASHING = new x("flashing"), x.NO_FLASHING_HAZARD = new x("noFlashingHazard"), x.UNKNOWN_FLASHING_HAZARD = new x("unknownFlashingHazard"), x.MOTION_SIMULATION = new x("motionSimulation"), x.NO_MOTION_SIMULATION_HAZARD = new x("noMotionSimulationHazard"), x.UNKNOWN_MOTION_SIMULATION_HAZARD = new x("unknownMotionSimulationHazard"), x.SOUND = new x("sound"), x.NO_SOUND_HAZARD = new x("noSoundHazard"), x.UNKNOWN_SOUND_HAZARD = new x("unknownSoundHazard"), x.UNKNOWN = new x("unknown"), x.NONE = new x("none");
134
- let Ye = x;
133
+ R.FLASHING = new R("flashing"), R.NO_FLASHING_HAZARD = new R("noFlashingHazard"), R.UNKNOWN_FLASHING_HAZARD = new R("unknownFlashingHazard"), R.MOTION_SIMULATION = new R("motionSimulation"), R.NO_MOTION_SIMULATION_HAZARD = new R("noMotionSimulationHazard"), R.UNKNOWN_MOTION_SIMULATION_HAZARD = new R("unknownMotionSimulationHazard"), R.SOUND = new R("sound"), R.NO_SOUND_HAZARD = new R("noSoundHazard"), R.UNKNOWN_SOUND_HAZARD = new R("unknownSoundHazard"), R.UNKNOWN = new R("unknown"), R.NONE = new R("none");
134
+ let Ye = R;
135
135
  const L = class L {
136
136
  constructor(t) {
137
137
  this.value = t;
@@ -877,7 +877,7 @@ class at {
877
877
  return this.after !== void 0 && (t.after = this.after), this.before !== void 0 && (t.before = this.before), this.highlight !== void 0 && (t.highlight = this.highlight), t;
878
878
  }
879
879
  }
880
- class N {
880
+ class F {
881
881
  /**
882
882
  * Creates a [Locator].
883
883
  */
@@ -889,7 +889,7 @@ class N {
889
889
  */
890
890
  static deserialize(t) {
891
891
  if (t && t.href && t.type)
892
- return new N({
892
+ return new F({
893
893
  href: t.href,
894
894
  type: t.type,
895
895
  title: t.title,
@@ -908,7 +908,7 @@ class N {
908
908
  * Shortcut to get a copy of the [Locator] with different [Locations] sub-properties.
909
909
  */
910
910
  copyWithLocations(t) {
911
- return new N({
911
+ return new F({
912
912
  href: this.href,
913
913
  type: this.type,
914
914
  title: this.title,
@@ -942,8 +942,8 @@ class j {
942
942
  duration: B(t.duration),
943
943
  bitrate: B(t.bitrate),
944
944
  languages: Di(t.language),
945
- alternates: It.deserialize(t.alternate),
946
- children: It.deserialize(t.children)
945
+ alternates: Ut.deserialize(t.alternate),
946
+ children: Ut.deserialize(t.children)
947
947
  });
948
948
  }
949
949
  /**
@@ -991,7 +991,7 @@ class j {
991
991
  */
992
992
  get locator() {
993
993
  let t = this.href.split("#");
994
- return new N({
994
+ return new F({
995
995
  href: t.length > 0 && t[0] !== void 0 ? t[0] : this.href,
996
996
  type: this.type ?? "",
997
997
  title: this.title,
@@ -1001,7 +1001,7 @@ class j {
1001
1001
  });
1002
1002
  }
1003
1003
  }
1004
- class It {
1004
+ class Ut {
1005
1005
  /**
1006
1006
  * Creates a [Links].
1007
1007
  */
@@ -1013,7 +1013,7 @@ class It {
1013
1013
  */
1014
1014
  static deserialize(t) {
1015
1015
  if (t && Array.isArray(t))
1016
- return new It(
1016
+ return new Ut(
1017
1017
  t.map((e) => j.deserialize(e)).filter((e) => e !== void 0)
1018
1018
  );
1019
1019
  }
@@ -1343,11 +1343,11 @@ $.prototype.getAvailability = function() {
1343
1343
  $.prototype.getAuthenticate = function() {
1344
1344
  return j.deserialize(this.otherProperties.authenticate);
1345
1345
  };
1346
- const xn = "CssSelectorGenerator";
1346
+ const Rn = "CssSelectorGenerator";
1347
1347
  function ei(s = "unknown problem", ...t) {
1348
- console.warn(`${xn}: ${s}`, ...t);
1348
+ console.warn(`${Rn}: ${s}`, ...t);
1349
1349
  }
1350
- function Rn(s) {
1350
+ function xn(s) {
1351
1351
  return s instanceof RegExp;
1352
1352
  }
1353
1353
  function Ln(s) {
@@ -1355,7 +1355,7 @@ function Ln(s) {
1355
1355
  }
1356
1356
  function kn(s) {
1357
1357
  const t = s.map((e) => {
1358
- if (Rn(e))
1358
+ if (xn(e))
1359
1359
  return (i) => e.test(i);
1360
1360
  if (typeof e == "function")
1361
1361
  return (i) => {
@@ -1632,7 +1632,7 @@ function oi(s, t) {
1632
1632
  return { node: r, offset: o };
1633
1633
  throw new RangeError("No text nodes with non-whitespace text found in range");
1634
1634
  }
1635
- function Nn(s) {
1635
+ function Fn(s) {
1636
1636
  if (!s.toString().trim().length)
1637
1637
  throw new RangeError("Range contains no non-whitespace text");
1638
1638
  if (s.startContainer.nodeType !== Node.TEXT_NODE)
@@ -1868,7 +1868,7 @@ class tt {
1868
1868
  * whitespace
1869
1869
  */
1870
1870
  static trimmedRange(t) {
1871
- return Nn(tt.fromRange(t).toRange());
1871
+ return Fn(tt.fromRange(t).toRange());
1872
1872
  }
1873
1873
  }
1874
1874
  class Wt {
@@ -1941,7 +1941,7 @@ class Ht {
1941
1941
  return new Wt(this.root, i.start, i.end);
1942
1942
  }
1943
1943
  }
1944
- function Fn(s) {
1944
+ function Nn(s) {
1945
1945
  const t = s.tagName.toUpperCase();
1946
1946
  return t === "IMG" || t === "VIDEO" || t === "AUDIO" || t === "IFRAME" || t === "OBJECT" || t === "EMBED" || t === "CANVAS";
1947
1947
  }
@@ -1970,7 +1970,7 @@ function ie(s, t) {
1970
1970
  }
1971
1971
  if (n) {
1972
1972
  const r = s.createRange();
1973
- return n.childNodes.length === 0 || Fn(n) ? (r.selectNode(n), r) : (r.setStartBefore(n), r.setEndAfter(n), r);
1973
+ return n.childNodes.length === 0 || Nn(n) ? (r.selectNode(n), r) : (r.setStartBefore(n), r.setEndAfter(n), r);
1974
1974
  }
1975
1975
  }
1976
1976
  } catch (e) {
@@ -1978,7 +1978,7 @@ function ie(s, t) {
1978
1978
  }
1979
1979
  return null;
1980
1980
  }
1981
- function Un(s, t) {
1981
+ function In(s, t) {
1982
1982
  let e = s.getClientRects();
1983
1983
  e.length || s.commonAncestorContainer.nodeType === Node.ELEMENT_NODE && (e = s.commonAncestorContainer.getClientRects());
1984
1984
  const i = 1, n = [];
@@ -2013,7 +2013,7 @@ function Gi(s, t, e) {
2013
2013
  continue;
2014
2014
  const a = V(r.top, o.top, t) && V(r.bottom, o.bottom, t), l = V(r.left, o.left, t) && V(r.right, o.right, t);
2015
2015
  if (a && !l && Xi(r, o, t)) {
2016
- const u = s.filter((y) => y !== r && y !== o), m = In(r, o);
2016
+ const u = s.filter((y) => y !== r && y !== o), m = Un(r, o);
2017
2017
  return u.push(m), Gi(
2018
2018
  u,
2019
2019
  t
@@ -2022,7 +2022,7 @@ function Gi(s, t, e) {
2022
2022
  }
2023
2023
  return s;
2024
2024
  }
2025
- function In(s, t) {
2025
+ function Un(s, t) {
2026
2026
  const e = Math.min(s.left, t.left), i = Math.max(s.right, t.right), n = Math.min(s.top, t.top), r = Math.max(s.bottom, t.bottom);
2027
2027
  return {
2028
2028
  bottom: r,
@@ -2141,24 +2141,24 @@ function Xi(s, t, e) {
2141
2141
  function V(s, t, e) {
2142
2142
  return Math.abs(s - t) <= e;
2143
2143
  }
2144
- function Ne(s) {
2144
+ function Fe(s) {
2145
2145
  const t = {}, e = s.document.documentElement.style;
2146
2146
  for (const i in s.document.documentElement.style)
2147
2147
  Object.hasOwn(e, i) && !Number.isNaN(Number.parseInt(i)) && (t[e[i]] = e.getPropertyValue(e[i]));
2148
2148
  return t;
2149
2149
  }
2150
2150
  function Yi(s, t) {
2151
- const e = Ne(s);
2151
+ const e = Fe(s);
2152
2152
  Object.keys(e).forEach((i) => {
2153
2153
  t.hasOwnProperty(i) || ne(s, i);
2154
2154
  }), Object.entries(t).forEach(([i, n]) => {
2155
- e[i] !== n && xt(s, i, n);
2155
+ e[i] !== n && Rt(s, i, n);
2156
2156
  });
2157
2157
  }
2158
2158
  function le(s, t) {
2159
2159
  return s.document.documentElement.style.getPropertyValue(t);
2160
2160
  }
2161
- function xt(s, t, e) {
2161
+ function Rt(s, t, e) {
2162
2162
  s.document.documentElement.style.setProperty(t, e);
2163
2163
  }
2164
2164
  function ne(s, t) {
@@ -2315,7 +2315,7 @@ class $n {
2315
2315
  }
2316
2316
  /**
2317
2317
  * Layouts a single DecorationItem.
2318
- * @param item
2318
+ * @param item
2319
2319
  */
2320
2320
  layout(t) {
2321
2321
  if (this.experimentalHighlights && !this.notTextFlag?.has(t.id))
@@ -2344,7 +2344,7 @@ class $n {
2344
2344
  const m = this.getCurrentDarkMode();
2345
2345
  u.innerHTML = `
2346
2346
  <div
2347
- data-readium="true"
2347
+ data-readium="true"
2348
2348
  class="readium-highlight"
2349
2349
  style="${[
2350
2350
  `background-color: ${t.decoration?.style?.tint ?? di} !important`,
@@ -2361,7 +2361,7 @@ class $n {
2361
2361
  const d = y.cloneNode(!0);
2362
2362
  d.style.setProperty("pointer-events", "none"), h(d, c, c), e.append(d);
2363
2363
  } else {
2364
- let d = Un(
2364
+ let d = In(
2365
2365
  t.range
2366
2366
  );
2367
2367
  d = d.sort((p, b) => p.top < b.top ? -1 : p.top > b.top ? 1 : 0);
@@ -2430,7 +2430,7 @@ const Pt = class Pt extends bt {
2430
2430
  mount(t, e) {
2431
2431
  return this.wnd = t, e.register("decorate", Pt.moduleName, (i, n) => {
2432
2432
  const r = i;
2433
- r.decoration && r.decoration.locator && (r.decoration.locator = N.deserialize(r.decoration.locator)), this.groups.has(r.group) || this.groups.set(r.group, new $n(
2433
+ r.decoration && r.decoration.locator && (r.decoration.locator = F.deserialize(r.decoration.locator)), this.groups.has(r.group) || this.groups.set(r.group, new $n(
2434
2434
  t,
2435
2435
  e,
2436
2436
  `readium-decoration-${this.lastGroupId++}`,
@@ -2497,7 +2497,7 @@ const pi = "readium-snapper-style", Et = class Et extends bt {
2497
2497
  }
2498
2498
  };
2499
2499
  Et.moduleName = "snapper";
2500
- let Rt = Et;
2500
+ let xt = Et;
2501
2501
  function rt(s) {
2502
2502
  return s.document.body.dir.toLowerCase() === "rtl";
2503
2503
  }
@@ -2555,11 +2555,11 @@ const Yn = [
2555
2555
  function Zi(s) {
2556
2556
  return Yn.indexOf(s.nodeName.toLowerCase()) !== -1 || s.hasAttribute("contenteditable") && s.getAttribute("contenteditable")?.toLowerCase() !== "false" ? s : s.parentElement ? Zi(s.parentElement) : null;
2557
2557
  }
2558
- function Fe(s, t) {
2558
+ function Ne(s, t) {
2559
2559
  const e = Ji(s, s.document.body, t), i = s._readium_cssSelectorGenerator.getCssSelector(e, {
2560
2560
  selectors: ["tag", "id", "class", "nthchild", "nthoftype", "attribute"]
2561
2561
  });
2562
- return new N({
2562
+ return new F({
2563
2563
  href: "#",
2564
2564
  type: "application/xhtml+xml",
2565
2565
  locations: new E({
@@ -2634,7 +2634,7 @@ const Jn = {
2634
2634
  absoluteMaxChars: 5e3,
2635
2635
  historySize: 20
2636
2636
  };
2637
- class Ue {
2637
+ class Ie {
2638
2638
  constructor(t = {}) {
2639
2639
  this.history = [], this.consistentScrollCount = 0, this.options = { ...Jn, ...t };
2640
2640
  }
@@ -2667,7 +2667,7 @@ class Ue {
2667
2667
  this.history = [], this.consistentScrollCount = 0;
2668
2668
  }
2669
2669
  }
2670
- const fi = "readium-column-snapper-style", tr = 200, U = class U extends Rt {
2670
+ const fi = "readium-column-snapper-style", tr = 200, I = class I extends xt {
2671
2671
  constructor() {
2672
2672
  super(...arguments), this.isSnapProtectionEnabled = !1, this.patternAnalyzer = null, this.lastTurnTime = 0, this.shakeTimeout = 0, this.snappingCancelled = !1, this.alreadyScrollLeft = 0, this.overscroll = 0, this.cachedScrollWidth = 0, this.touchState = 0, this.startingX = void 0, this.endingX = void 0, this.onTouchStarter = this.onTouchStart.bind(this), this.onTouchEnder = this.onTouchEnd.bind(this), this.onWidthChanger = this.onWidthChange.bind(this), this.onTouchMover = this.onTouchMove.bind(this);
2673
2673
  }
@@ -2765,7 +2765,7 @@ const fi = "readium-column-snapper-style", tr = 200, U = class U extends Rt {
2765
2765
  i < 0 ? (this.overscroll = i, this.doc().style.transform = `translate3d(${-this.overscroll}px, 0px, 0px)`) : i + this.wnd.innerWidth > this.cachedScrollWidth ? (this.overscroll = i, this.doc().style.transform = `translate3d(${-i}px, 0px, 0px)`) : (this.overscroll = 0, this.doc().style.removeProperty("transform"), this.doc().scrollLeft = this.alreadyScrollLeft + e);
2766
2766
  }
2767
2767
  enableSnapProtection() {
2768
- this.patternAnalyzer || (this.patternAnalyzer = new Ue({
2768
+ this.patternAnalyzer || (this.patternAnalyzer = new Ie({
2769
2769
  maxVelocity: this.wnd.innerWidth,
2770
2770
  // page width
2771
2771
  minVariance: 0.1,
@@ -2821,7 +2821,7 @@ const fi = "readium-column-snapper-style", tr = 200, U = class U extends Rt {
2821
2821
  * {
2822
2822
  scrollbar-width: none; /* for Firefox */
2823
2823
  }
2824
-
2824
+
2825
2825
  body::-webkit-scrollbar {
2826
2826
  display: none; /* for Chrome, Safari, and Opera */
2827
2827
  }
@@ -2838,14 +2838,14 @@ const fi = "readium-column-snapper-style", tr = 200, U = class U extends Rt {
2838
2838
  }), this.onWidthChange());
2839
2839
  } else
2840
2840
  t.requestAnimationFrame(() => this.cachedScrollWidth = this.doc().scrollWidth);
2841
- }), t.frameElement && this.mutationObserver.observe(t.frameElement, { attributes: !0, attributeFilter: ["style"] }), this.mutationObserver.observe(t.document, { attributes: !0, attributeFilter: ["style"] }), this.mutationObserver.observe(t.document.documentElement, { attributes: !0, attributeFilter: ["style"] }), e.register("scroll_protection", U.moduleName, (r, o) => {
2841
+ }), t.frameElement && this.mutationObserver.observe(t.frameElement, { attributes: !0, attributeFilter: ["style"] }), this.mutationObserver.observe(t.document, { attributes: !0, attributeFilter: ["style"] }), this.mutationObserver.observe(t.document.documentElement, { attributes: !0, attributeFilter: ["style"] }), e.register("scroll_protection", I.moduleName, (r, o) => {
2842
2842
  this.enableSnapProtection(), o(!0);
2843
2843
  });
2844
2844
  const n = (r) => {
2845
2845
  const o = this.doc().scrollLeft;
2846
2846
  return this.doc().scrollLeft = this.snapOffset(r), o !== this.doc().scrollLeft;
2847
2847
  };
2848
- return t.addEventListener("orientationchange", this.onWidthChanger), t.addEventListener("resize", this.onWidthChanger), t.requestAnimationFrame(() => this.cachedScrollWidth = this.doc().scrollWidth), e.register("go_progression", U.moduleName, (r, o) => {
2848
+ return t.addEventListener("orientationchange", this.onWidthChanger), t.addEventListener("resize", this.onWidthChanger), t.requestAnimationFrame(() => this.cachedScrollWidth = this.doc().scrollWidth), e.register("go_progression", I.moduleName, (r, o) => {
2849
2849
  const a = r;
2850
2850
  if (a < 0 || a > 1) {
2851
2851
  e.send("error", {
@@ -2858,7 +2858,7 @@ const fi = "readium-column-snapper-style", tr = 200, U = class U extends Rt {
2858
2858
  const l = this.cachedScrollWidth, h = rt(t) ? -1 : 1, c = l * a * h;
2859
2859
  this.doc().scrollLeft = this.snapOffset(c), this.reportProgress(), z(this.wnd), o(!0);
2860
2860
  });
2861
- }), e.register("go_id", U.moduleName, (r, o) => {
2861
+ }), e.register("go_id", I.moduleName, (r, o) => {
2862
2862
  const a = t.document.getElementById(r);
2863
2863
  if (!a) {
2864
2864
  o(!1);
@@ -2867,10 +2867,10 @@ const fi = "readium-column-snapper-style", tr = 200, U = class U extends Rt {
2867
2867
  this.wnd.requestAnimationFrame(() => {
2868
2868
  this.doc().scrollLeft = this.snapOffset(a.getBoundingClientRect().left + t.scrollX), this.reportProgress(), z(this.wnd), o(!0);
2869
2869
  });
2870
- }), e.register("go_text", U.moduleName, (r, o) => {
2870
+ }), e.register("go_text", I.moduleName, (r, o) => {
2871
2871
  let a;
2872
2872
  Array.isArray(r) && (r.length > 1 && (a = r[1]), r = r[0]);
2873
- const l = at.deserialize(r), h = ie(this.wnd.document, new N({
2873
+ const l = at.deserialize(r), h = ie(this.wnd.document, new F({
2874
2874
  href: t.location.href,
2875
2875
  type: "text/html",
2876
2876
  text: l,
@@ -2887,7 +2887,7 @@ const fi = "readium-column-snapper-style", tr = 200, U = class U extends Rt {
2887
2887
  this.wnd.requestAnimationFrame(() => {
2888
2888
  this.doc().scrollLeft = this.snapOffset(h.getBoundingClientRect().left + t.scrollX), this.reportProgress(), z(this.wnd), o(!0);
2889
2889
  });
2890
- }), e.register("go_end", U.moduleName, (r, o) => {
2890
+ }), e.register("go_end", I.moduleName, (r, o) => {
2891
2891
  const a = rt(t) ? -1 : 1;
2892
2892
  this.wnd.requestAnimationFrame(() => {
2893
2893
  this.cachedScrollWidth = this.doc().scrollWidth;
@@ -2895,44 +2895,44 @@ const fi = "readium-column-snapper-style", tr = 200, U = class U extends Rt {
2895
2895
  if (this.doc().scrollLeft === l) return o(!1);
2896
2896
  this.doc().scrollLeft = this.snapOffset(l), this.reportProgress(), z(this.wnd), o(!0);
2897
2897
  });
2898
- }), e.register("go_start", U.moduleName, (r, o) => {
2898
+ }), e.register("go_start", I.moduleName, (r, o) => {
2899
2899
  this.wnd.requestAnimationFrame(() => {
2900
2900
  if (this.doc().scrollLeft === 0) return o(!1);
2901
2901
  this.doc().scrollLeft = 0, this.reportProgress(), z(this.wnd), o(!0);
2902
2902
  });
2903
- }), e.register("go_prev", U.moduleName, (r, o) => {
2903
+ }), e.register("go_prev", I.moduleName, (r, o) => {
2904
2904
  this.wnd.requestAnimationFrame(() => {
2905
2905
  this.cachedScrollWidth = this.doc().scrollWidth;
2906
2906
  const a = t.scrollX - t.innerWidth, l = rt(t) ? -(this.cachedScrollWidth - t.innerWidth) : 0, h = n(Math.max(a, l));
2907
2907
  h && (this.reportProgress(), z(this.wnd), this.checkSuspiciousSnap("left", this.wnd.innerWidth)), o(h);
2908
2908
  });
2909
- }), e.register("go_next", U.moduleName, (r, o) => {
2909
+ }), e.register("go_next", I.moduleName, (r, o) => {
2910
2910
  this.wnd.requestAnimationFrame(() => {
2911
2911
  this.cachedScrollWidth = this.doc().scrollWidth;
2912
2912
  const a = t.scrollX + t.innerWidth, l = rt(t) ? 0 : this.cachedScrollWidth - t.innerWidth, h = n(Math.min(a, l));
2913
2913
  h && (this.reportProgress(), z(this.wnd), this.checkSuspiciousSnap("right", this.wnd.innerWidth)), o(h);
2914
2914
  });
2915
- }), e.register("unfocus", U.moduleName, (r, o) => {
2915
+ }), e.register("unfocus", I.moduleName, (r, o) => {
2916
2916
  this.snappingCancelled = !0, z(this.wnd), o(!0);
2917
- }), e.register("shake", U.moduleName, (r, o) => {
2917
+ }), e.register("shake", I.moduleName, (r, o) => {
2918
2918
  this.shake(), o(!0);
2919
- }), e.register("focus", U.moduleName, (r, o) => {
2919
+ }), e.register("focus", I.moduleName, (r, o) => {
2920
2920
  this.wnd.requestAnimationFrame(() => {
2921
2921
  this.cachedScrollWidth = this.doc().scrollWidth, this.snapCurrentOffset(!1, !0), this.reportProgress(), o(!0);
2922
2922
  });
2923
- }), e.register("first_visible_locator", U.moduleName, (r, o) => {
2924
- const a = Fe(t, !1);
2923
+ }), e.register("first_visible_locator", I.moduleName, (r, o) => {
2924
+ const a = Ne(t, !1);
2925
2925
  this.comms.send("first_visible_locator", a.serialize()), o(!0);
2926
2926
  }), t.addEventListener("touchstart", this.onTouchStarter, { passive: !0 }), t.addEventListener("touchend", this.onTouchEnder, { passive: !0 }), t.addEventListener("touchmove", this.onTouchMover, { passive: !0 }), t.document.addEventListener("touchstart", () => {
2927
2927
  }), e.log("ColumnSnapper Mounted"), !0;
2928
2928
  }
2929
2929
  unmount(t, e) {
2930
- return this.snappingCancelled = !0, e.unregisterAll(U.moduleName), this.resizeObserver.disconnect(), this.mutationObserver.disconnect(), this.patternAnalyzer && (this.patternAnalyzer.clear(), this.patternAnalyzer = null, this.isSnapProtectionEnabled = !1), t.removeEventListener("touchstart", this.onTouchStarter), t.removeEventListener("touchend", this.onTouchEnder), t.removeEventListener("touchmove", this.onTouchMover), t.removeEventListener("orientationchange", this.onWidthChanger), t.removeEventListener("resize", this.onWidthChanger), t.document.getElementById(fi)?.remove(), e.log("ColumnSnapper Unmounted"), super.unmount(t, e);
2930
+ return this.snappingCancelled = !0, e.unregisterAll(I.moduleName), this.resizeObserver.disconnect(), this.mutationObserver.disconnect(), this.patternAnalyzer && (this.patternAnalyzer.clear(), this.patternAnalyzer = null, this.isSnapProtectionEnabled = !1), t.removeEventListener("touchstart", this.onTouchStarter), t.removeEventListener("touchend", this.onTouchEnder), t.removeEventListener("touchmove", this.onTouchMover), t.removeEventListener("orientationchange", this.onWidthChanger), t.removeEventListener("resize", this.onWidthChanger), t.document.getElementById(fi)?.remove(), e.log("ColumnSnapper Unmounted"), super.unmount(t, e);
2931
2931
  }
2932
2932
  };
2933
- U.moduleName = "column_snapper";
2934
- let ve = U;
2935
- const yi = "readium-scroll-snapper-style", W = class W extends Rt {
2933
+ I.moduleName = "column_snapper";
2934
+ let ve = I;
2935
+ const yi = "readium-scroll-snapper-style", W = class W extends xt {
2936
2936
  constructor() {
2937
2937
  super(...arguments), this.patternAnalyzer = null, this.lastScrollTime = 0, this.isScrollProtectionEnabled = !1, this.initialScrollHandled = !1, this.isScrolling = !1, this.lastScrollTop = 0, this.isResizing = !1, this.resizeDebounce = null, this.handleScroll = (t) => {
2938
2938
  if (this.comms.ready && !this.isResizing) {
@@ -2978,7 +2978,7 @@ const yi = "readium-scroll-snapper-style", W = class W extends Rt {
2978
2978
  });
2979
2979
  }
2980
2980
  enableScrollProtection() {
2981
- this.patternAnalyzer || (this.patternAnalyzer = new Ue(Qi), this.isScrollProtectionEnabled = !0, this.comms?.log("Scroll protection enabled"));
2981
+ this.patternAnalyzer || (this.patternAnalyzer = new Ie(Qi), this.isScrollProtectionEnabled = !0, this.comms?.log("Scroll protection enabled"));
2982
2982
  }
2983
2983
  mount(t, e) {
2984
2984
  this.wnd = t, this.comms = e, this.initialScrollHandled = !1, this.lastScrollTop = 0, this.isResizing = !1, this.resizeDebounce && (this.wnd.clearTimeout(this.resizeDebounce), this.resizeDebounce = null), t.navigator.epubReadingSystem && (t.navigator.epubReadingSystem.layoutStyle = "scrolling");
@@ -2987,7 +2987,7 @@ const yi = "readium-scroll-snapper-style", W = class W extends Rt {
2987
2987
  * {
2988
2988
  scrollbar-width: none; /* for Firefox */
2989
2989
  }
2990
-
2990
+
2991
2991
  body::-webkit-scrollbar {
2992
2992
  display: none; /* for Chrome, Safari, and Opera */
2993
2993
  }
@@ -3022,7 +3022,7 @@ const yi = "readium-scroll-snapper-style", W = class W extends Rt {
3022
3022
  }), e.register("go_text", W.moduleName, (n, r) => {
3023
3023
  let o;
3024
3024
  Array.isArray(n) && (n.length > 1 && (o = n[1]), n = n[0]);
3025
- const a = at.deserialize(n), l = ie(this.wnd.document, new N({
3025
+ const a = at.deserialize(n), l = ie(this.wnd.document, new F({
3026
3026
  href: t.location.href,
3027
3027
  type: "text/html",
3028
3028
  text: a,
@@ -3055,7 +3055,7 @@ const yi = "readium-scroll-snapper-style", W = class W extends Rt {
3055
3055
  ], W.moduleName, (n, r) => r(!1)), e.register("focus", W.moduleName, (n, r) => {
3056
3056
  this.reportProgress(), r(!0);
3057
3057
  }), e.register("first_visible_locator", W.moduleName, (n, r) => {
3058
- const o = Fe(t, !0);
3058
+ const o = Ne(t, !0);
3059
3059
  this.comms.send("first_visible_locator", o.serialize()), r(!0);
3060
3060
  }), e.log("ScrollSnapper Mounted"), !0;
3061
3061
  }
@@ -3065,7 +3065,7 @@ const yi = "readium-scroll-snapper-style", W = class W extends Rt {
3065
3065
  };
3066
3066
  W.moduleName = "scroll_snapper";
3067
3067
  let we = W;
3068
- const H = class H extends Rt {
3068
+ const H = class H extends xt {
3069
3069
  constructor() {
3070
3070
  super(...arguments), this.patternAnalyzer = null, this.lastScrollTime = 0, this.isScrollProtectionEnabled = !1, this.initialScrollHandled = !1, this.isScrolling = !1, this.lastScrollTop = 0, this.isResizing = !1, this.resizeDebounce = null, this.handleScroll = (t) => {
3071
3071
  if (this.comms.ready && !this.isResizing) {
@@ -3111,7 +3111,7 @@ const H = class H extends Rt {
3111
3111
  });
3112
3112
  }
3113
3113
  enableScrollProtection() {
3114
- this.patternAnalyzer || (this.patternAnalyzer = new Ue(Qi), this.isScrollProtectionEnabled = !0, this.comms?.log("Scroll protection enabled"));
3114
+ this.patternAnalyzer || (this.patternAnalyzer = new Ie(Qi), this.isScrollProtectionEnabled = !0, this.comms?.log("Scroll protection enabled"));
3115
3115
  }
3116
3116
  mount(t, e) {
3117
3117
  return this.wnd = t, this.comms = e, this.initialScrollHandled = !1, this.lastScrollTop = 0, this.isResizing = !1, this.resizeDebounce && (this.wnd.clearTimeout(this.resizeDebounce), this.resizeDebounce = null), this.resizeObserver = new ResizeObserver(() => {
@@ -3145,7 +3145,7 @@ const H = class H extends Rt {
3145
3145
  }), e.register("go_text", H.moduleName, (i, n) => {
3146
3146
  let r;
3147
3147
  Array.isArray(i) && (i.length > 1 && (r = i[1]), i = i[0]);
3148
- const o = at.deserialize(i), a = ie(this.wnd.document, new N({
3148
+ const o = at.deserialize(i), a = ie(this.wnd.document, new F({
3149
3149
  href: t.location.href,
3150
3150
  type: "text/html",
3151
3151
  text: o,
@@ -3178,7 +3178,7 @@ const H = class H extends Rt {
3178
3178
  ], H.moduleName, (i, n) => n(!1)), e.register("focus", H.moduleName, (i, n) => {
3179
3179
  this.reportProgress(), n(!0);
3180
3180
  }), e.register("first_visible_locator", H.moduleName, (i, n) => {
3181
- const r = Fe(t, !0);
3181
+ const r = Ne(t, !0);
3182
3182
  e.send("first_visible_locator", r.serialize()), n(!0);
3183
3183
  }), e.log("WebPubSnapper Mounted"), !0;
3184
3184
  }
@@ -3396,6 +3396,8 @@ const gt = class gt extends bt {
3396
3396
  }
3397
3397
  } else
3398
3398
  this.currentSelection = null;
3399
+ }, this.onDragOver = (t) => {
3400
+ this.isDragAndDropEnabled && (t.preventDefault(), t.stopPropagation());
3399
3401
  }, this.onDragStart = (t) => {
3400
3402
  if (this.isDragAndDropEnabled) {
3401
3403
  t.preventDefault();
@@ -3450,10 +3452,10 @@ const gt = class gt extends bt {
3450
3452
  !this.isContextMenuEnabled || !this.wnd || (this.wnd.document.removeEventListener("contextmenu", this.onContext), this.isContextMenuEnabled = !1);
3451
3453
  }
3452
3454
  addDragAndDropPrevention() {
3453
- this.isDragAndDropEnabled || !this.wnd || (this.wnd.document.addEventListener("dragstart", this.onDragStart), this.wnd.document.addEventListener("drop", this.onDrop), this.isDragAndDropEnabled = !0);
3455
+ this.isDragAndDropEnabled || !this.wnd || (this.wnd.document.addEventListener("dragstart", this.onDragStart), this.wnd.document.addEventListener("dragover", this.onDragOver), this.wnd.document.addEventListener("drop", this.onDrop), this.isDragAndDropEnabled = !0);
3454
3456
  }
3455
3457
  removeDragAndDropPrevention() {
3456
- !this.isDragAndDropEnabled || !this.wnd || (this.wnd.document.removeEventListener("dragstart", this.onDragStart), this.wnd.document.removeEventListener("drop", this.onDrop), this.isDragAndDropEnabled = !1);
3458
+ !this.isDragAndDropEnabled || !this.wnd || (this.wnd.document.removeEventListener("dragstart", this.onDragStart), this.wnd.document.removeEventListener("dragover", this.onDragOver), this.wnd.document.removeEventListener("drop", this.onDrop), this.isDragAndDropEnabled = !1);
3457
3459
  }
3458
3460
  enableKeyboardPeripherals(t = []) {
3459
3461
  this.disableKeyboardPeripherals();
@@ -3622,7 +3624,7 @@ const Ct = class Ct extends bt {
3622
3624
  ), Reflect.defineProperty(t.navigator, "epubReadingSystem", {
3623
3625
  value: {
3624
3626
  name: "readium-ts-toolkit",
3625
- version: "2.4.0-beta.9",
3627
+ version: "2.4.0",
3626
3628
  hasFeature: (n, r = "") => {
3627
3629
  switch (n) {
3628
3630
  case "dom-manipulation":
@@ -3674,7 +3676,7 @@ let Bt = Ct;
3674
3676
  const Si = "readium-viewport", K = class K extends Bt {
3675
3677
  onViewportWidthChanged(t) {
3676
3678
  const e = t.target;
3677
- xt(e, "--RS__viewportWidth", `${e.innerWidth}px`);
3679
+ Rt(e, "--RS__viewportWidth", `${e.innerWidth}px`);
3678
3680
  }
3679
3681
  mount(t, e) {
3680
3682
  if (!super.mount(t, e)) return !1;
@@ -3685,12 +3687,12 @@ const Si = "readium-viewport", K = class K extends Bt {
3685
3687
  ), t.document.head.appendChild(i), t.addEventListener("orientationchange", this.onViewportWidthChanged), t.addEventListener("resize", this.onViewportWidthChanged), this.onViewportWidthChanged({
3686
3688
  target: t
3687
3689
  }), e.register("get_properties", K.moduleName, (n, r) => {
3688
- Ne(t), r(!0);
3690
+ Fe(t), r(!0);
3689
3691
  }), e.register("update_properties", K.moduleName, (n, r) => {
3690
3692
  n["--RS__viewportWidth"] = `${t.innerWidth}px`, Yi(t, n), r(!0);
3691
3693
  }), e.register("set_property", K.moduleName, (n, r) => {
3692
3694
  const o = n;
3693
- xt(t, o[0], o[1]), r(!0);
3695
+ Rt(t, o[0], o[1]), r(!0);
3694
3696
  }), e.register("remove_property", K.moduleName, (n, r) => {
3695
3697
  ne(t, n), r(!0);
3696
3698
  }), e.register("activate", K.moduleName, (n, r) => {
@@ -3722,7 +3724,7 @@ const bi = "readium-fixed-style", X = class X extends Bt {
3722
3724
  /*cursor: var() TODO*/
3723
3725
  }`, t.document.head.appendChild(i), e.register("set_property", X.moduleName, (n, r) => {
3724
3726
  const o = n;
3725
- xt(t, o[0], o[1]), r(!0);
3727
+ Rt(t, o[0], o[1]), r(!0);
3726
3728
  }), e.register("remove_property", X.moduleName, (n, r) => {
3727
3729
  ne(t, n), r(!0);
3728
3730
  }), e.register("first_visible_locator", X.moduleName, (n, r) => r(!1)), e.register("unfocus", X.moduleName, (n, r) => {
@@ -3761,12 +3763,12 @@ const Z = class Z extends bt {
3761
3763
  this.wndOnErr,
3762
3764
  !1
3763
3765
  ), e.register("get_properties", Z.moduleName, (i, n) => {
3764
- Ne(t), n(!0);
3766
+ Fe(t), n(!0);
3765
3767
  }), e.register("update_properties", Z.moduleName, (i, n) => {
3766
3768
  Yi(t, i), n(!0);
3767
3769
  }), e.register("set_property", Z.moduleName, (i, n) => {
3768
3770
  const r = i;
3769
- xt(t, r[0], r[1]), n(!0);
3771
+ Rt(t, r[0], r[1]), n(!0);
3770
3772
  }), e.register("remove_property", Z.moduleName, (i, n) => {
3771
3773
  ne(t, i), n(!0);
3772
3774
  }), e.register("activate", Z.moduleName, (i, n) => {
@@ -3778,7 +3780,7 @@ const Z = class Z extends bt {
3778
3780
  }
3779
3781
  };
3780
3782
  Z.moduleName = "webpub_setup";
3781
- let xe = Z;
3783
+ let Re = Z;
3782
3784
  var it;
3783
3785
  let nr = (it = class extends bt {
3784
3786
  constructor() {
@@ -3838,7 +3840,7 @@ const rr = [
3838
3840
  // All modules go here
3839
3841
  Ce,
3840
3842
  Ee,
3841
- xe,
3843
+ Re,
3842
3844
  _e,
3843
3845
  Pe,
3844
3846
  be,
@@ -4645,7 +4647,7 @@ var jt = vr();
4645
4647
  const wr = { description: "Attempts to filter out paragraphs that are implicitly headings or part of headers", scope: "RS", value: "readium-experimentalHeaderFiltering-on" }, _r = { description: "Attemps to filter out elements that are sized using viewport units and should not be scaled directly e.g. tables, images, iframes, etc.", scope: "RS", value: "readium-experimentalZoom-on" }, Pr = {
4646
4648
  experimentalHeaderFiltering: wr,
4647
4649
  experimentalZoom: _r
4648
- }, Ie = Pr;
4650
+ }, Ue = Pr;
4649
4651
  var J = /* @__PURE__ */ ((s) => (s.start = "start", s.left = "left", s.right = "right", s.justify = "justify", s))(J || {});
4650
4652
  const ht = {
4651
4653
  range: [0, 100],
@@ -4733,7 +4735,7 @@ class Er extends re {
4733
4735
  toCSSProperties() {
4734
4736
  const t = {};
4735
4737
  return this.experiments && this.experiments.forEach((e) => {
4736
- t["--RS__" + e] = Ie[e].value;
4738
+ t["--RS__" + e] = Ue[e].value;
4737
4739
  }), t;
4738
4740
  }
4739
4741
  }
@@ -4763,13 +4765,13 @@ class Cr {
4763
4765
  this.userProperties = new ln(e);
4764
4766
  }
4765
4767
  }
4766
- function xr(s, t) {
4768
+ function Rr(s, t) {
4767
4769
  return s == null || t == null || s <= t ? s : void 0;
4768
4770
  }
4769
- function Rr(s, t) {
4771
+ function xr(s, t) {
4770
4772
  return s == null || t == null || s >= t ? s : void 0;
4771
4773
  }
4772
- function I(s) {
4774
+ function U(s) {
4773
4775
  return typeof s == "string" ? s : s === null ? null : void 0;
4774
4776
  }
4775
4777
  function P(s) {
@@ -4799,11 +4801,11 @@ function ue(s, t) {
4799
4801
  }
4800
4802
  function hn(s) {
4801
4803
  if (s !== void 0)
4802
- return s === null ? null : s.filter((t) => t in Ie);
4804
+ return s === null ? null : s.filter((t) => t in Ue);
4803
4805
  }
4804
4806
  class kt {
4805
4807
  constructor(t = {}) {
4806
- this.fontFamily = I(t.fontFamily), this.fontWeight = M(t.fontWeight, nt.range), this.hyphens = P(t.hyphens), this.iOSPatch = P(t.iOSPatch), this.iPadOSPatch = P(t.iPadOSPatch), this.letterSpacing = w(t.letterSpacing), this.ligatures = P(t.ligatures), this.lineHeight = w(t.lineHeight), this.noRuby = P(t.noRuby), this.paragraphIndent = w(t.paragraphIndent), this.paragraphSpacing = w(t.paragraphSpacing), this.textAlign = se(t.textAlign, J), this.textNormalization = P(t.textNormalization), this.wordSpacing = w(t.wordSpacing), this.zoom = M(t.zoom, Jt.range);
4808
+ this.fontFamily = U(t.fontFamily), this.fontWeight = M(t.fontWeight, nt.range), this.hyphens = P(t.hyphens), this.iOSPatch = P(t.iOSPatch), this.iPadOSPatch = P(t.iPadOSPatch), this.letterSpacing = w(t.letterSpacing), this.ligatures = P(t.ligatures), this.lineHeight = w(t.lineHeight), this.noRuby = P(t.noRuby), this.paragraphIndent = w(t.paragraphIndent), this.paragraphSpacing = w(t.paragraphSpacing), this.textAlign = se(t.textAlign, J), this.textNormalization = P(t.textNormalization), this.wordSpacing = w(t.wordSpacing), this.zoom = M(t.zoom, Jt.range);
4807
4809
  }
4808
4810
  static serialize(t) {
4809
4811
  const { ...e } = t;
@@ -4826,7 +4828,7 @@ class kt {
4826
4828
  }
4827
4829
  class Lr {
4828
4830
  constructor(t) {
4829
- this.fontFamily = I(t.fontFamily) || null, this.fontWeight = M(t.fontWeight, nt.range) || null, this.hyphens = P(t.hyphens) ?? null, this.iOSPatch = t.iOSPatch === !1 ? !1 : (T.OS.iOS || T.OS.iPadOS) && T.iOSRequest === "mobile", this.iPadOSPatch = t.iPadOSPatch === !1 ? !1 : T.OS.iPadOS && T.iOSRequest === "desktop", this.letterSpacing = w(t.letterSpacing) || null, this.ligatures = P(t.ligatures) ?? null, this.lineHeight = w(t.lineHeight) || null, this.noRuby = P(t.noRuby) ?? !1, this.paragraphIndent = w(t.paragraphIndent) ?? null, this.paragraphSpacing = w(t.paragraphSpacing) ?? null, this.textAlign = se(t.textAlign, J) || null, this.textNormalization = P(t.textNormalization) ?? !1, this.wordSpacing = w(t.wordSpacing) || null, this.zoom = M(t.zoom, Jt.range) || 1, this.experiments = hn(t.experiments) ?? null;
4831
+ this.fontFamily = U(t.fontFamily) || null, this.fontWeight = M(t.fontWeight, nt.range) || null, this.hyphens = P(t.hyphens) ?? null, this.iOSPatch = t.iOSPatch === !1 ? !1 : (T.OS.iOS || T.OS.iPadOS) && T.iOSRequest === "mobile", this.iPadOSPatch = t.iPadOSPatch === !1 ? !1 : T.OS.iPadOS && T.iOSRequest === "desktop", this.letterSpacing = w(t.letterSpacing) || null, this.ligatures = P(t.ligatures) ?? null, this.lineHeight = w(t.lineHeight) || null, this.noRuby = P(t.noRuby) ?? !1, this.paragraphIndent = w(t.paragraphIndent) ?? null, this.paragraphSpacing = w(t.paragraphSpacing) ?? null, this.textAlign = se(t.textAlign, J) || null, this.textNormalization = P(t.textNormalization) ?? !1, this.wordSpacing = w(t.wordSpacing) || null, this.zoom = M(t.zoom, Jt.range) || 1, this.experiments = hn(t.experiments) ?? null;
4830
4832
  }
4831
4833
  }
4832
4834
  class _i {
@@ -4910,7 +4912,7 @@ class cn extends A {
4910
4912
  this._value = null;
4911
4913
  }
4912
4914
  }
4913
- class R extends A {
4915
+ class x extends A {
4914
4916
  constructor({
4915
4917
  initialValue: t = null,
4916
4918
  effectiveValue: e,
@@ -4972,7 +4974,7 @@ class Pi {
4972
4974
  }
4973
4975
  get isDisplayTransformable() {
4974
4976
  return this.metadata?.accessibility?.feature?.some(
4975
- (t) => t.value === Ut.DISPLAY_TRANSFORMABILITY.value
4977
+ (t) => t.value === It.DISPLAY_TRANSFORMABILITY.value
4976
4978
  ) ?? !1;
4977
4979
  }
4978
4980
  get fontFamily() {
@@ -4981,17 +4983,17 @@ class Pi {
4981
4983
  effectiveValue: this.settings.fontFamily || null,
4982
4984
  isEffective: this.isDisplayTransformable,
4983
4985
  onChange: (t) => {
4984
- this.updatePreference("fontFamily", t || null);
4986
+ this.updatePreference("fontFamily", t ?? null);
4985
4987
  }
4986
4988
  });
4987
4989
  }
4988
4990
  get fontWeight() {
4989
- return new R({
4991
+ return new x({
4990
4992
  initialValue: this.preferences.fontWeight,
4991
4993
  effectiveValue: this.settings.fontWeight || 400,
4992
4994
  isEffective: this.isDisplayTransformable,
4993
4995
  onChange: (t) => {
4994
- this.updatePreference("fontWeight", t || null);
4996
+ this.updatePreference("fontWeight", t ?? null);
4995
4997
  },
4996
4998
  supportedRange: nt.range,
4997
4999
  step: nt.step
@@ -5003,7 +5005,7 @@ class Pi {
5003
5005
  effectiveValue: this.settings.hyphens || !1,
5004
5006
  isEffective: this.isDisplayTransformable,
5005
5007
  onChange: (t) => {
5006
- this.updatePreference("hyphens", t || null);
5008
+ this.updatePreference("hyphens", t ?? null);
5007
5009
  }
5008
5010
  });
5009
5011
  }
@@ -5013,7 +5015,7 @@ class Pi {
5013
5015
  effectiveValue: this.settings.iOSPatch || !1,
5014
5016
  isEffective: !0,
5015
5017
  onChange: (t) => {
5016
- this.updatePreference("iOSPatch", t || null);
5018
+ this.updatePreference("iOSPatch", t ?? null);
5017
5019
  }
5018
5020
  });
5019
5021
  }
@@ -5023,17 +5025,17 @@ class Pi {
5023
5025
  effectiveValue: this.settings.iPadOSPatch || !1,
5024
5026
  isEffective: !0,
5025
5027
  onChange: (t) => {
5026
- this.updatePreference("iPadOSPatch", t || null);
5028
+ this.updatePreference("iPadOSPatch", t ?? null);
5027
5029
  }
5028
5030
  });
5029
5031
  }
5030
5032
  get letterSpacing() {
5031
- return new R({
5033
+ return new x({
5032
5034
  initialValue: this.preferences.letterSpacing,
5033
5035
  effectiveValue: this.settings.letterSpacing || 0,
5034
5036
  isEffective: this.isDisplayTransformable,
5035
5037
  onChange: (t) => {
5036
- this.updatePreference("letterSpacing", t || null);
5038
+ this.updatePreference("letterSpacing", t ?? null);
5037
5039
  },
5038
5040
  supportedRange: Xt.range,
5039
5041
  step: Xt.step
@@ -5045,17 +5047,17 @@ class Pi {
5045
5047
  effectiveValue: this.settings.ligatures || !0,
5046
5048
  isEffective: this.isDisplayTransformable,
5047
5049
  onChange: (t) => {
5048
- this.updatePreference("ligatures", t || null);
5050
+ this.updatePreference("ligatures", t ?? null);
5049
5051
  }
5050
5052
  });
5051
5053
  }
5052
5054
  get lineHeight() {
5053
- return new R({
5055
+ return new x({
5054
5056
  initialValue: this.preferences.lineHeight,
5055
5057
  effectiveValue: this.settings.lineHeight,
5056
5058
  isEffective: this.isDisplayTransformable,
5057
5059
  onChange: (t) => {
5058
- this.updatePreference("lineHeight", t || null);
5060
+ this.updatePreference("lineHeight", t ?? null);
5059
5061
  },
5060
5062
  supportedRange: Yt.range,
5061
5063
  step: Yt.step
@@ -5067,29 +5069,29 @@ class Pi {
5067
5069
  effectiveValue: this.settings.noRuby || !1,
5068
5070
  isEffective: this.isDisplayTransformable,
5069
5071
  onChange: (t) => {
5070
- this.updatePreference("noRuby", t || null);
5072
+ this.updatePreference("noRuby", t ?? null);
5071
5073
  }
5072
5074
  });
5073
5075
  }
5074
5076
  get paragraphIndent() {
5075
- return new R({
5077
+ return new x({
5076
5078
  initialValue: this.preferences.paragraphIndent,
5077
5079
  effectiveValue: this.settings.paragraphIndent || 0,
5078
5080
  isEffective: this.isDisplayTransformable,
5079
5081
  onChange: (t) => {
5080
- this.updatePreference("paragraphIndent", t || null);
5082
+ this.updatePreference("paragraphIndent", t ?? null);
5081
5083
  },
5082
5084
  supportedRange: qt.range,
5083
5085
  step: qt.step
5084
5086
  });
5085
5087
  }
5086
5088
  get paragraphSpacing() {
5087
- return new R({
5089
+ return new x({
5088
5090
  initialValue: this.preferences.paragraphSpacing,
5089
5091
  effectiveValue: this.settings.paragraphSpacing || 0,
5090
5092
  isEffective: this.isDisplayTransformable,
5091
5093
  onChange: (t) => {
5092
- this.updatePreference("paragraphSpacing", t || null);
5094
+ this.updatePreference("paragraphSpacing", t ?? null);
5093
5095
  },
5094
5096
  supportedRange: Kt.range,
5095
5097
  step: Kt.step
@@ -5101,7 +5103,7 @@ class Pi {
5101
5103
  effectiveValue: this.settings.textAlign || J.start,
5102
5104
  isEffective: this.isDisplayTransformable,
5103
5105
  onChange: (t) => {
5104
- this.updatePreference("textAlign", t || null);
5106
+ this.updatePreference("textAlign", t ?? null);
5105
5107
  },
5106
5108
  supportedValues: Object.values(J)
5107
5109
  });
@@ -5112,29 +5114,29 @@ class Pi {
5112
5114
  effectiveValue: this.settings.textNormalization || !1,
5113
5115
  isEffective: this.isDisplayTransformable,
5114
5116
  onChange: (t) => {
5115
- this.updatePreference("textNormalization", t || null);
5117
+ this.updatePreference("textNormalization", t ?? null);
5116
5118
  }
5117
5119
  });
5118
5120
  }
5119
5121
  get wordSpacing() {
5120
- return new R({
5122
+ return new x({
5121
5123
  initialValue: this.preferences.wordSpacing,
5122
5124
  effectiveValue: this.settings.wordSpacing || 0,
5123
5125
  isEffective: this.isDisplayTransformable,
5124
5126
  onChange: (t) => {
5125
- this.updatePreference("wordSpacing", t || null);
5127
+ this.updatePreference("wordSpacing", t ?? null);
5126
5128
  },
5127
5129
  supportedRange: Zt.range,
5128
5130
  step: Zt.step
5129
5131
  });
5130
5132
  }
5131
5133
  get zoom() {
5132
- return new R({
5134
+ return new x({
5133
5135
  initialValue: this.preferences.zoom,
5134
5136
  effectiveValue: this.settings.zoom || 1,
5135
5137
  isEffective: CSS.supports("zoom", "1") ?? !1,
5136
5138
  onChange: (t) => {
5137
- this.updatePreference("zoom", t || null);
5139
+ this.updatePreference("zoom", t ?? null);
5138
5140
  },
5139
5141
  supportedRange: Jt.range,
5140
5142
  step: Jt.step
@@ -5311,8 +5313,8 @@ class pn {
5311
5313
  }
5312
5314
  }
5313
5315
  }
5314
- const yt = (s) => s.replace(/\/\/.*/g, "").replace(/\/\*[\s\S]*?\*\//g, "").replace(/\n/g, "").replace(/\s+/g, " "), Nt = (s) => s.replace(/\/\*(?:(?!\*\/)[\s\S])*\*\/|[\r\n\t]+/g, "").replace(/ {2,}/g, " "), Or = `/*!
5315
- * Readium CSS v.2.0.0
5316
+ const yt = (s) => s.replace(/\/\/.*/g, "").replace(/\/\*[\s\S]*?\*\//g, "").replace(/\n/g, "").replace(/\s+/g, " "), Ft = (s) => s.replace(/\/\*(?:(?!\*\/)[\s\S])*\*\/|[\r\n\t]+/g, "").replace(/ {2,}/g, " "), Or = `/*!
5317
+ * Readium CSS v.2.0.1
5316
5318
  * Copyright (c) 2017–2026. Readium Foundation. All rights reserved.
5317
5319
  * Use of this source code is governed by a BSD-style license which is detailed in the
5318
5320
  * LICENSE file present in the project repository where this source code is maintained.
@@ -5465,8 +5467,7 @@ const yt = (s) => s.replace(/\/\/.*/g, "").replace(/\/\*[\s\S]*?\*\//g, "").repl
5465
5467
  text-indent:var(--USER__paraIndent) !important;
5466
5468
  }
5467
5469
 
5468
- :root[style*="--USER__paraIndent"] p *,
5469
- :root[style*="--USER__paraIndent"] p:first-letter{
5470
+ :root[style*="--USER__paraIndent"] p *{
5470
5471
  text-indent:0 !important;
5471
5472
  }
5472
5473
 
@@ -5633,7 +5634,7 @@ function Ar(s) {
5633
5634
  id: "readium-css-webpub",
5634
5635
  as: "link",
5635
5636
  target: "head",
5636
- blob: new Blob([Nt(Or)], { type: "text/css" }),
5637
+ blob: new Blob([Ft(Or)], { type: "text/css" }),
5637
5638
  rel: "stylesheet"
5638
5639
  }
5639
5640
  ];
@@ -5678,10 +5679,10 @@ class zr {
5678
5679
  }
5679
5680
  }
5680
5681
  let Mr = 0;
5681
- function Nr() {
5682
+ function Fr() {
5682
5683
  return ++Mr;
5683
5684
  }
5684
- const Fr = `
5685
+ const Nr = `
5685
5686
  onmessage = function(event) {
5686
5687
  var action = event.data;
5687
5688
  var startTime = performance.now()
@@ -5702,7 +5703,7 @@ onmessage = function(event) {
5702
5703
  }, this.log = (...i) => this.send("log", ...i), this.table = (...i) => this.send("table", ...i), this.clear = (...i) => this.send("clear", ...i);
5703
5704
  }
5704
5705
  async send(t, ...e) {
5705
- const i = Nr();
5706
+ const i = Fr();
5706
5707
  return new Promise((n, r) => {
5707
5708
  this.callbacks.set(i, n), this.worker.postMessage({
5708
5709
  id: i,
@@ -5717,14 +5718,14 @@ onmessage = function(event) {
5717
5718
  this.worker.terminate(), URL.revokeObjectURL(this.blobUrl);
5718
5719
  }
5719
5720
  };
5720
- Ve.workerScript = Fr;
5721
+ Ve.workerScript = Nr;
5721
5722
  let ee = Ve;
5722
5723
  function De(s) {
5723
5724
  return typeof window < "u" && console ? console[s] : (...t) => {
5724
5725
  };
5725
5726
  }
5726
- const Ur = De("log"), Ci = De("table"), Ir = De("clear");
5727
- async function xi() {
5727
+ const Ir = De("log"), Ci = De("table"), Ur = De("clear");
5728
+ async function Ri() {
5728
5729
  if (typeof navigator < "u" && navigator.brave && navigator.brave.isBrave)
5729
5730
  try {
5730
5731
  return await Promise.race([
@@ -5801,7 +5802,7 @@ class Wr {
5801
5802
  return (await this.workerConsole.log(t)).time;
5802
5803
  {
5803
5804
  const e = performance.now();
5804
- return Ur(t), performance.now() - e;
5805
+ return Ir(t), performance.now() - e;
5805
5806
  }
5806
5807
  }
5807
5808
  /**
@@ -5831,14 +5832,14 @@ class Wr {
5831
5832
  if (!this.isPerformanceDetectionEnabled())
5832
5833
  return !1;
5833
5834
  const t = await this.calcTablePrintTime(), e = Math.max(await this.calcLogPrintTime(), await this.calcLogPrintTime());
5834
- return this.maxPrintTime = Math.max(this.maxPrintTime, e), this.workerConsole ? await this.workerConsole.clear() : Ir(), t === 0 ? !1 : this.maxPrintTime === 0 ? !!await xi() : t > this.maxPrintTime * 10;
5835
+ return this.maxPrintTime = Math.max(this.maxPrintTime, e), this.workerConsole ? await this.workerConsole.clear() : Ur(), t === 0 ? !1 : this.maxPrintTime === 0 ? !!await Ri() : t > this.maxPrintTime * 10;
5835
5836
  }
5836
5837
  /**
5837
5838
  * Debugger-based detection (fallback method)
5838
5839
  * WARNING: This method impacts user experience
5839
5840
  */
5840
5841
  async checkDebuggerBased() {
5841
- if (!this.isDebuggerDetectionEnabled() || await xi())
5842
+ if (!this.isDebuggerDetectionEnabled() || await Ri())
5842
5843
  return !1;
5843
5844
  const t = performance.now();
5844
5845
  try {
@@ -6144,7 +6145,7 @@ class Gr extends rn {
6144
6145
  }
6145
6146
  get hasDisplayTransformability() {
6146
6147
  return this.pub.metadata?.accessibility?.feature?.some(
6147
- (t) => t.value === Ut.DISPLAY_TRANSFORMABILITY.value
6148
+ (t) => t.value === It.DISPLAY_TRANSFORMABILITY.value
6148
6149
  ) ?? !1;
6149
6150
  }
6150
6151
  eventListener(t, e) {
@@ -6153,9 +6154,9 @@ class Gr extends rn {
6153
6154
  this.listeners.frameLoaded(this.framePool.currentFrames[0].iframe.contentWindow), this.listeners.positionChanged(this.currentLocation);
6154
6155
  break;
6155
6156
  case "first_visible_locator":
6156
- const i = N.deserialize(e);
6157
+ const i = F.deserialize(e);
6157
6158
  if (!i) break;
6158
- this.currentLocation = new N({
6159
+ this.currentLocation = new F({
6159
6160
  href: this.currentLocation.href,
6160
6161
  type: this.currentLocation.type,
6161
6162
  title: this.currentLocation.title,
@@ -6363,7 +6364,7 @@ class Gr extends rn {
6363
6364
  if (!e)
6364
6365
  throw new Error("No current resource available");
6365
6366
  const n = this.currentLocation && this.currentLocation.href === e.href && this.currentLocation.locations.progression ? this.currentLocation.locations.progression : 0;
6366
- return this.pub.manifest.locatorFromLink(e) || new N({
6367
+ return this.pub.manifest.locatorFromLink(e) || new F({
6367
6368
  href: e.href,
6368
6369
  type: e.type || "text/html",
6369
6370
  locations: new E({
@@ -6558,7 +6559,7 @@ class Xr {
6558
6559
  return this.loader;
6559
6560
  }
6560
6561
  }
6561
- const Ri = 5, Li = 3;
6562
+ const xi = 5, Li = 3;
6562
6563
  class Yr {
6563
6564
  constructor(t, e, i, n, r, o) {
6564
6565
  this.pool = /* @__PURE__ */ new Map(), this.blobs = /* @__PURE__ */ new Map(), this.inprogress = /* @__PURE__ */ new Map(), this.pendingUpdates = /* @__PURE__ */ new Map(), this.injector = null, this.container = t, this.positions = e, this.currentCssProperties = i, this.injector = n ?? null, this.contentProtectionConfig = r || {}, this.keyboardPeripheralsConfig = o || [];
@@ -6586,7 +6587,7 @@ class Yr {
6586
6587
  const a = new Promise(async (l, h) => {
6587
6588
  const c = [], u = [];
6588
6589
  this.positions.forEach((d, p) => {
6589
- (p > r + Ri || p < r - Ri) && (c.includes(d.href) || c.push(d.href)), p < r + Li && p > r - Li && (u.includes(d.href) || u.push(d.href));
6590
+ (p > r + xi || p < r - xi) && (c.includes(d.href) || c.push(d.href)), p < r + Li && p > r - Li && (u.includes(d.href) || u.push(d.href));
6590
6591
  }), c.forEach(async (d) => {
6591
6592
  u.includes(d) || this.pool.has(d) && (await this.pool.get(d)?.destroy(), this.pool.delete(d), this.pendingUpdates.has(d) && this.pendingUpdates.set(d, { inPool: !1 }));
6592
6593
  }), this.currentBaseURL !== void 0 && t.baseURL !== this.currentBaseURL && (this.blobs.forEach((d) => {
@@ -7130,7 +7131,7 @@ Overscroll: ${this.pan.overscrollX.toFixed(2)},${this.pan.overscrollY.toFixed(2)
7130
7131
  t > 0 && e > this.manager.threshold && this.manager.slength > this.manager.perPage ? this.manager.listener("no_less", void 0) : t < 0 && e > this.manager.threshold && this.manager.slength > this.manager.perPage && this.manager.listener("no_more", void 0), this.manager.slideToCurrent(!0, !0);
7131
7132
  }
7132
7133
  }
7133
- var Re = /* @__PURE__ */ ((s) => (s.auto = "auto", s.landscape = "landscape", s.portrait = "portrait", s))(Re || {}), Le = /* @__PURE__ */ ((s) => (s.auto = "auto", s.both = "both", s.none = "none", s.landscape = "landscape", s))(Le || {});
7134
+ var xe = /* @__PURE__ */ ((s) => (s.auto = "auto", s.landscape = "landscape", s.portrait = "portrait", s))(xe || {}), Le = /* @__PURE__ */ ((s) => (s.auto = "auto", s.both = "both", s.none = "none", s.landscape = "landscape", s))(Le || {});
7134
7135
  class es {
7135
7136
  // TODO getter
7136
7137
  constructor(t) {
@@ -7183,7 +7184,7 @@ class as {
7183
7184
  throw Error("Unsupported reading progression for EPUB");
7184
7185
  this.spreader = new es(this.pub), this.containerHeightCached = t.clientHeight, this.bookElement = document.createElement("div"), this.bookElement.ariaLabel = "Book", this.bookElement.tabIndex = -1, this.updateBookStyle(!0), this.spineElement = document.createElement("div"), this.spineElement.ariaLabel = "Spine", this.bookElement.appendChild(this.spineElement), this.container.appendChild(this.bookElement), this.updateSpineStyle(!0), this.peripherals = new ts(this), this.pub.readingOrder.items.forEach((a) => {
7185
7186
  const l = new qr(this.peripherals, this.pub.metadata.effectiveReadingProgression, a.href, this.contentProtectionConfig, this.keyboardPeripheralsConfig);
7186
- this.spineElement.appendChild(l.element), this.pool.set(a.href, l), l.width = 100 / this.length * (a.properties?.otherProperties.orientation === Re.landscape || a.properties?.otherProperties.addBlank ? this.perPage : 1), l.height = this.height;
7187
+ this.spineElement.appendChild(l.element), this.pool.set(a.href, l), l.width = 100 / this.length * (a.properties?.otherProperties.orientation === xe.landscape || a.properties?.otherProperties.addBlank ? this.perPage : 1), l.height = this.height;
7187
7188
  });
7188
7189
  }
7189
7190
  set listener(t) {
@@ -7203,7 +7204,7 @@ class as {
7203
7204
  this.pool.forEach((i, n) => {
7204
7205
  let r = this.pub.readingOrder.items.findIndex((l) => l.href === n);
7205
7206
  const o = this.pub.readingOrder.items[r];
7206
- if (i.width = 100 / this.length * (o.properties?.otherProperties.orientation === Re.landscape || o.properties?.otherProperties.addBlank ? this.perPage : 1), i.height = this.height, !i.loaded) return;
7207
+ if (i.width = 100 / this.length * (o.properties?.otherProperties.orientation === xe.landscape || o.properties?.otherProperties.addBlank ? this.perPage : 1), i.height = this.height, !i.loaded) return;
7207
7208
  const a = this.spreader.findByLink(o);
7208
7209
  i.update(this.spreadPosition(a, o));
7209
7210
  });
@@ -7499,7 +7500,7 @@ class as {
7499
7500
  }
7500
7501
  class Ot {
7501
7502
  constructor(t = {}) {
7502
- this.backgroundColor = I(t.backgroundColor), this.blendFilter = P(t.blendFilter), this.constraint = w(t.constraint), this.columnCount = w(t.columnCount), this.darkenFilter = ft(t.darkenFilter), this.deprecatedFontSize = P(t.deprecatedFontSize), this.fontFamily = I(t.fontFamily), this.fontSize = M(t.fontSize, Gt.range), this.fontSizeNormalize = P(t.fontSizeNormalize), this.fontOpticalSizing = P(t.fontOpticalSizing), this.fontWeight = M(t.fontWeight, nt.range), this.fontWidth = M(t.fontWidth, $t.range), this.hyphens = P(t.hyphens), this.invertFilter = ft(t.invertFilter), this.invertGaijiFilter = ft(t.invertGaijiFilter), this.iOSPatch = P(t.iOSPatch), this.iPadOSPatch = P(t.iPadOSPatch), this.letterSpacing = w(t.letterSpacing), this.ligatures = P(t.ligatures), this.lineHeight = w(t.lineHeight), this.linkColor = I(t.linkColor), this.noRuby = P(t.noRuby), this.pageGutter = w(t.pageGutter), this.paragraphIndent = w(t.paragraphIndent), this.paragraphSpacing = w(t.paragraphSpacing), this.scroll = P(t.scroll), this.scrollPaddingTop = w(t.scrollPaddingTop), this.scrollPaddingBottom = w(t.scrollPaddingBottom), this.scrollPaddingLeft = w(t.scrollPaddingLeft), this.scrollPaddingRight = w(t.scrollPaddingRight), this.selectionBackgroundColor = I(t.selectionBackgroundColor), this.selectionTextColor = I(t.selectionTextColor), this.textAlign = se(t.textAlign, J), this.textColor = I(t.textColor), this.textNormalization = P(t.textNormalization), this.visitedColor = I(t.visitedColor), this.wordSpacing = w(t.wordSpacing), this.optimalLineLength = w(t.optimalLineLength), this.maximalLineLength = w(t.maximalLineLength), this.minimalLineLength = w(t.minimalLineLength);
7503
+ this.backgroundColor = U(t.backgroundColor), this.blendFilter = P(t.blendFilter), this.constraint = w(t.constraint), this.columnCount = w(t.columnCount), this.darkenFilter = ft(t.darkenFilter), this.deprecatedFontSize = P(t.deprecatedFontSize), this.fontFamily = U(t.fontFamily), this.fontSize = M(t.fontSize, Gt.range), this.fontSizeNormalize = P(t.fontSizeNormalize), this.fontOpticalSizing = P(t.fontOpticalSizing), this.fontWeight = M(t.fontWeight, nt.range), this.fontWidth = M(t.fontWidth, $t.range), this.hyphens = P(t.hyphens), this.invertFilter = ft(t.invertFilter), this.invertGaijiFilter = ft(t.invertGaijiFilter), this.iOSPatch = P(t.iOSPatch), this.iPadOSPatch = P(t.iPadOSPatch), this.letterSpacing = w(t.letterSpacing), this.ligatures = P(t.ligatures), this.lineHeight = w(t.lineHeight), this.linkColor = U(t.linkColor), this.noRuby = P(t.noRuby), this.pageGutter = w(t.pageGutter), this.paragraphIndent = w(t.paragraphIndent), this.paragraphSpacing = w(t.paragraphSpacing), this.scroll = P(t.scroll), this.scrollPaddingTop = w(t.scrollPaddingTop), this.scrollPaddingBottom = w(t.scrollPaddingBottom), this.scrollPaddingLeft = w(t.scrollPaddingLeft), this.scrollPaddingRight = w(t.scrollPaddingRight), this.selectionBackgroundColor = U(t.selectionBackgroundColor), this.selectionTextColor = U(t.selectionTextColor), this.textAlign = se(t.textAlign, J), this.textColor = U(t.textColor), this.textNormalization = P(t.textNormalization), this.visitedColor = U(t.visitedColor), this.wordSpacing = w(t.wordSpacing), this.optimalLineLength = w(t.optimalLineLength), this.maximalLineLength = w(t.maximalLineLength), this.minimalLineLength = w(t.minimalLineLength);
7503
7504
  }
7504
7505
  static serialize(t) {
7505
7506
  const { ...e } = t;
@@ -7522,7 +7523,7 @@ class Ot {
7522
7523
  }
7523
7524
  class ls {
7524
7525
  constructor(t) {
7525
- this.backgroundColor = I(t.backgroundColor) || null, this.blendFilter = P(t.blendFilter) ?? !1, this.constraint = w(t.constraint) || 0, this.columnCount = w(t.columnCount) || null, this.darkenFilter = ft(t.darkenFilter) ?? !1, this.deprecatedFontSize = P(t.deprecatedFontSize), (this.deprecatedFontSize === !1 || this.deprecatedFontSize === null) && (this.deprecatedFontSize = !CSS.supports("zoom", "1")), this.fontFamily = I(t.fontFamily) || null, this.fontSize = M(t.fontSize, Gt.range) || 1, this.fontSizeNormalize = P(t.fontSizeNormalize) ?? !1, this.fontOpticalSizing = P(t.fontOpticalSizing) ?? null, this.fontWeight = M(t.fontWeight, nt.range) || null, this.fontWidth = M(t.fontWidth, $t.range) || null, this.hyphens = P(t.hyphens) ?? null, this.invertFilter = ft(t.invertFilter) ?? !1, this.invertGaijiFilter = ft(t.invertGaijiFilter) ?? !1, this.iOSPatch = t.iOSPatch === !1 ? !1 : (T.OS.iOS || T.OS.iPadOS) && T.iOSRequest === "mobile", this.iPadOSPatch = t.iPadOSPatch === !1 ? !1 : T.OS.iPadOS && T.iOSRequest === "desktop", this.letterSpacing = w(t.letterSpacing) || null, this.ligatures = P(t.ligatures) ?? null, this.lineHeight = w(t.lineHeight) || null, this.linkColor = I(t.linkColor) || null, this.noRuby = P(t.noRuby) ?? !1, this.pageGutter = ue(w(t.pageGutter), 20), this.paragraphIndent = w(t.paragraphIndent) ?? null, this.paragraphSpacing = w(t.paragraphSpacing) ?? null, this.scroll = P(t.scroll) ?? !1, this.scrollPaddingTop = w(t.scrollPaddingTop) ?? null, this.scrollPaddingBottom = w(t.scrollPaddingBottom) ?? null, this.scrollPaddingLeft = w(t.scrollPaddingLeft) ?? null, this.scrollPaddingRight = w(t.scrollPaddingRight) ?? null, this.selectionBackgroundColor = I(t.selectionBackgroundColor) || null, this.selectionTextColor = I(t.selectionTextColor) || null, this.textAlign = se(t.textAlign, J) || null, this.textColor = I(t.textColor) || null, this.textNormalization = P(t.textNormalization) ?? !1, this.visitedColor = I(t.visitedColor) || null, this.wordSpacing = w(t.wordSpacing) || null, this.optimalLineLength = w(t.optimalLineLength) || 65, this.maximalLineLength = ue(Rr(t.maximalLineLength, this.optimalLineLength), 80), this.minimalLineLength = ue(xr(t.minimalLineLength, this.optimalLineLength), 40), this.experiments = hn(t.experiments) || null;
7526
+ this.backgroundColor = U(t.backgroundColor) || null, this.blendFilter = P(t.blendFilter) ?? !1, this.constraint = w(t.constraint) || 0, this.columnCount = w(t.columnCount) || null, this.darkenFilter = ft(t.darkenFilter) ?? !1, this.deprecatedFontSize = P(t.deprecatedFontSize), (this.deprecatedFontSize === !1 || this.deprecatedFontSize === null) && (this.deprecatedFontSize = !CSS.supports("zoom", "1")), this.fontFamily = U(t.fontFamily) || null, this.fontSize = M(t.fontSize, Gt.range) || 1, this.fontSizeNormalize = P(t.fontSizeNormalize) ?? !1, this.fontOpticalSizing = P(t.fontOpticalSizing) ?? null, this.fontWeight = M(t.fontWeight, nt.range) || null, this.fontWidth = M(t.fontWidth, $t.range) || null, this.hyphens = P(t.hyphens) ?? null, this.invertFilter = ft(t.invertFilter) ?? !1, this.invertGaijiFilter = ft(t.invertGaijiFilter) ?? !1, this.iOSPatch = t.iOSPatch === !1 ? !1 : (T.OS.iOS || T.OS.iPadOS) && T.iOSRequest === "mobile", this.iPadOSPatch = t.iPadOSPatch === !1 ? !1 : T.OS.iPadOS && T.iOSRequest === "desktop", this.letterSpacing = w(t.letterSpacing) || null, this.ligatures = P(t.ligatures) ?? null, this.lineHeight = w(t.lineHeight) || null, this.linkColor = U(t.linkColor) || null, this.noRuby = P(t.noRuby) ?? !1, this.pageGutter = ue(w(t.pageGutter), 20), this.paragraphIndent = w(t.paragraphIndent) ?? null, this.paragraphSpacing = w(t.paragraphSpacing) ?? null, this.scroll = P(t.scroll) ?? !1, this.scrollPaddingTop = w(t.scrollPaddingTop) ?? null, this.scrollPaddingBottom = w(t.scrollPaddingBottom) ?? null, this.scrollPaddingLeft = w(t.scrollPaddingLeft) ?? null, this.scrollPaddingRight = w(t.scrollPaddingRight) ?? null, this.selectionBackgroundColor = U(t.selectionBackgroundColor) || null, this.selectionTextColor = U(t.selectionTextColor) || null, this.textAlign = se(t.textAlign, J) || null, this.textColor = U(t.textColor) || null, this.textNormalization = P(t.textNormalization) ?? !1, this.visitedColor = U(t.visitedColor) || null, this.wordSpacing = w(t.wordSpacing) || null, this.optimalLineLength = w(t.optimalLineLength) || 65, this.maximalLineLength = ue(xr(t.maximalLineLength, this.optimalLineLength), 80), this.minimalLineLength = ue(Rr(t.minimalLineLength, this.optimalLineLength), 40), this.experiments = hn(t.experiments) || null;
7526
7527
  }
7527
7528
  }
7528
7529
  const hs = "#FFFFFF", cs = "#121212", ds = "#0000EE", us = "#551A8B", ps = "#b4d8fe", ms = "inherit", dt = {
@@ -7549,7 +7550,7 @@ class zi {
7549
7550
  effectiveValue: this.settings.backgroundColor || dt.RS__backgroundColor,
7550
7551
  isEffective: this.preferences.backgroundColor !== null,
7551
7552
  onChange: (t) => {
7552
- this.updatePreference("backgroundColor", t || null);
7553
+ this.updatePreference("backgroundColor", t ?? null);
7553
7554
  }
7554
7555
  });
7555
7556
  }
@@ -7559,7 +7560,7 @@ class zi {
7559
7560
  effectiveValue: this.settings.blendFilter || !1,
7560
7561
  isEffective: this.preferences.blendFilter !== null,
7561
7562
  onChange: (t) => {
7562
- this.updatePreference("blendFilter", t || null);
7563
+ this.updatePreference("blendFilter", t ?? null);
7563
7564
  }
7564
7565
  });
7565
7566
  }
@@ -7569,7 +7570,7 @@ class zi {
7569
7570
  effectiveValue: this.settings.columnCount || null,
7570
7571
  isEffective: this.layout !== S.fixed && !this.settings.scroll,
7571
7572
  onChange: (t) => {
7572
- this.updatePreference("columnCount", t || null);
7573
+ this.updatePreference("columnCount", t ?? null);
7573
7574
  }
7574
7575
  });
7575
7576
  }
@@ -7579,17 +7580,17 @@ class zi {
7579
7580
  effectiveValue: this.preferences.constraint || 0,
7580
7581
  isEffective: !0,
7581
7582
  onChange: (t) => {
7582
- this.updatePreference("constraint", t || null);
7583
+ this.updatePreference("constraint", t ?? null);
7583
7584
  }
7584
7585
  });
7585
7586
  }
7586
7587
  get darkenFilter() {
7587
- return new R({
7588
+ return new x({
7588
7589
  initialValue: typeof this.preferences.darkenFilter == "boolean" ? 100 : this.preferences.darkenFilter,
7589
7590
  effectiveValue: typeof this.settings.darkenFilter == "boolean" ? 100 : this.settings.darkenFilter || 0,
7590
7591
  isEffective: this.settings.darkenFilter !== null,
7591
7592
  onChange: (t) => {
7592
- this.updatePreference("darkenFilter", t || null);
7593
+ this.updatePreference("darkenFilter", t ?? null);
7593
7594
  },
7594
7595
  supportedRange: ht.range,
7595
7596
  step: ht.step
@@ -7601,7 +7602,7 @@ class zi {
7601
7602
  effectiveValue: CSS.supports("zoom", "1") ? this.settings.deprecatedFontSize || !1 : !0,
7602
7603
  isEffective: this.layout !== S.fixed,
7603
7604
  onChange: (t) => {
7604
- this.updatePreference("deprecatedFontSize", t || null);
7605
+ this.updatePreference("deprecatedFontSize", t ?? null);
7605
7606
  }
7606
7607
  });
7607
7608
  }
@@ -7611,17 +7612,17 @@ class zi {
7611
7612
  effectiveValue: this.settings.fontFamily || null,
7612
7613
  isEffective: this.layout !== S.fixed,
7613
7614
  onChange: (t) => {
7614
- this.updatePreference("fontFamily", t || null);
7615
+ this.updatePreference("fontFamily", t ?? null);
7615
7616
  }
7616
7617
  });
7617
7618
  }
7618
7619
  get fontSize() {
7619
- return new R({
7620
+ return new x({
7620
7621
  initialValue: this.preferences.fontSize,
7621
7622
  effectiveValue: this.settings.fontSize || 1,
7622
7623
  isEffective: this.layout !== S.fixed,
7623
7624
  onChange: (t) => {
7624
- this.updatePreference("fontSize", t || null);
7625
+ this.updatePreference("fontSize", t ?? null);
7625
7626
  },
7626
7627
  supportedRange: Gt.range,
7627
7628
  step: Gt.step
@@ -7633,7 +7634,7 @@ class zi {
7633
7634
  effectiveValue: this.settings.fontSizeNormalize || !1,
7634
7635
  isEffective: this.layout !== S.fixed && this.preferences.fontSizeNormalize !== null,
7635
7636
  onChange: (t) => {
7636
- this.updatePreference("fontSizeNormalize", t || null);
7637
+ this.updatePreference("fontSizeNormalize", t ?? null);
7637
7638
  }
7638
7639
  });
7639
7640
  }
@@ -7643,29 +7644,29 @@ class zi {
7643
7644
  effectiveValue: this.settings.fontOpticalSizing || !0,
7644
7645
  isEffective: this.layout !== S.fixed && this.preferences.fontOpticalSizing !== null,
7645
7646
  onChange: (t) => {
7646
- this.updatePreference("fontOpticalSizing", t || null);
7647
+ this.updatePreference("fontOpticalSizing", t ?? null);
7647
7648
  }
7648
7649
  });
7649
7650
  }
7650
7651
  get fontWeight() {
7651
- return new R({
7652
+ return new x({
7652
7653
  initialValue: this.preferences.fontWeight,
7653
7654
  effectiveValue: this.settings.fontWeight || 400,
7654
7655
  isEffective: this.layout !== S.fixed && this.preferences.fontWeight !== null,
7655
7656
  onChange: (t) => {
7656
- this.updatePreference("fontWeight", t || null);
7657
+ this.updatePreference("fontWeight", t ?? null);
7657
7658
  },
7658
7659
  supportedRange: nt.range,
7659
7660
  step: nt.step
7660
7661
  });
7661
7662
  }
7662
7663
  get fontWidth() {
7663
- return new R({
7664
+ return new x({
7664
7665
  initialValue: this.preferences.fontWidth,
7665
7666
  effectiveValue: this.settings.fontWidth || 100,
7666
7667
  isEffective: this.layout !== S.fixed && this.preferences.fontWidth !== null,
7667
7668
  onChange: (t) => {
7668
- this.updatePreference("fontWidth", t || null);
7669
+ this.updatePreference("fontWidth", t ?? null);
7669
7670
  },
7670
7671
  supportedRange: $t.range,
7671
7672
  step: $t.step
@@ -7677,29 +7678,29 @@ class zi {
7677
7678
  effectiveValue: this.settings.hyphens || !1,
7678
7679
  isEffective: this.layout !== S.fixed && this.metadata?.effectiveReadingProgression === D.ltr && this.preferences.hyphens !== null,
7679
7680
  onChange: (t) => {
7680
- this.updatePreference("hyphens", t || null);
7681
+ this.updatePreference("hyphens", t ?? null);
7681
7682
  }
7682
7683
  });
7683
7684
  }
7684
7685
  get invertFilter() {
7685
- return new R({
7686
+ return new x({
7686
7687
  initialValue: typeof this.preferences.invertFilter == "boolean" ? 100 : this.preferences.invertFilter,
7687
7688
  effectiveValue: typeof this.settings.invertFilter == "boolean" ? 100 : this.settings.invertFilter || 0,
7688
7689
  isEffective: this.settings.invertFilter !== null,
7689
7690
  onChange: (t) => {
7690
- this.updatePreference("invertFilter", t || null);
7691
+ this.updatePreference("invertFilter", t ?? null);
7691
7692
  },
7692
7693
  supportedRange: ht.range,
7693
7694
  step: ht.step
7694
7695
  });
7695
7696
  }
7696
7697
  get invertGaijiFilter() {
7697
- return new R({
7698
+ return new x({
7698
7699
  initialValue: typeof this.preferences.invertGaijiFilter == "boolean" ? 100 : this.preferences.invertGaijiFilter,
7699
7700
  effectiveValue: typeof this.settings.invertGaijiFilter == "boolean" ? 100 : this.settings.invertGaijiFilter || 0,
7700
7701
  isEffective: this.preferences.invertGaijiFilter !== null,
7701
7702
  onChange: (t) => {
7702
- this.updatePreference("invertGaijiFilter", t || null);
7703
+ this.updatePreference("invertGaijiFilter", t ?? null);
7703
7704
  },
7704
7705
  supportedRange: ht.range,
7705
7706
  step: ht.step
@@ -7711,7 +7712,7 @@ class zi {
7711
7712
  effectiveValue: this.settings.iOSPatch || !1,
7712
7713
  isEffective: this.layout !== S.fixed,
7713
7714
  onChange: (t) => {
7714
- this.updatePreference("iOSPatch", t || null);
7715
+ this.updatePreference("iOSPatch", t ?? null);
7715
7716
  }
7716
7717
  });
7717
7718
  }
@@ -7721,17 +7722,17 @@ class zi {
7721
7722
  effectiveValue: this.settings.iPadOSPatch || !1,
7722
7723
  isEffective: this.layout !== S.fixed,
7723
7724
  onChange: (t) => {
7724
- this.updatePreference("iPadOSPatch", t || null);
7725
+ this.updatePreference("iPadOSPatch", t ?? null);
7725
7726
  }
7726
7727
  });
7727
7728
  }
7728
7729
  get letterSpacing() {
7729
- return new R({
7730
+ return new x({
7730
7731
  initialValue: this.preferences.letterSpacing,
7731
7732
  effectiveValue: this.settings.letterSpacing || 0,
7732
7733
  isEffective: this.layout !== S.fixed && this.preferences.letterSpacing !== null,
7733
7734
  onChange: (t) => {
7734
- this.updatePreference("letterSpacing", t || null);
7735
+ this.updatePreference("letterSpacing", t ?? null);
7735
7736
  },
7736
7737
  supportedRange: Xt.range,
7737
7738
  step: Xt.step
@@ -7748,17 +7749,17 @@ class zi {
7748
7749
  return !(t && ["zh", "ja", "ko", "mn-mong"].some((e) => t.startsWith(e)));
7749
7750
  })(),
7750
7751
  onChange: (t) => {
7751
- this.updatePreference("ligatures", t || null);
7752
+ this.updatePreference("ligatures", t ?? null);
7752
7753
  }
7753
7754
  });
7754
7755
  }
7755
7756
  get lineHeight() {
7756
- return new R({
7757
+ return new x({
7757
7758
  initialValue: this.preferences.lineHeight,
7758
7759
  effectiveValue: this.settings.lineHeight,
7759
7760
  isEffective: this.layout !== S.fixed && this.preferences.lineHeight !== null,
7760
7761
  onChange: (t) => {
7761
- this.updatePreference("lineHeight", t || null);
7762
+ this.updatePreference("lineHeight", t ?? null);
7762
7763
  },
7763
7764
  supportedRange: Yt.range,
7764
7765
  step: Yt.step
@@ -7770,12 +7771,12 @@ class zi {
7770
7771
  effectiveValue: this.settings.linkColor || dt.RS__linkColor,
7771
7772
  isEffective: this.layout !== S.fixed && this.preferences.linkColor !== null,
7772
7773
  onChange: (t) => {
7773
- this.updatePreference("linkColor", t || null);
7774
+ this.updatePreference("linkColor", t ?? null);
7774
7775
  }
7775
7776
  });
7776
7777
  }
7777
7778
  get maximalLineLength() {
7778
- return new R({
7779
+ return new x({
7779
7780
  initialValue: this.preferences.maximalLineLength,
7780
7781
  effectiveValue: this.settings.maximalLineLength,
7781
7782
  isEffective: this.layout !== S.fixed,
@@ -7787,7 +7788,7 @@ class zi {
7787
7788
  });
7788
7789
  }
7789
7790
  get minimalLineLength() {
7790
- return new R({
7791
+ return new x({
7791
7792
  initialValue: this.preferences.minimalLineLength,
7792
7793
  effectiveValue: this.settings.minimalLineLength,
7793
7794
  isEffective: this.layout !== S.fixed,
@@ -7804,12 +7805,12 @@ class zi {
7804
7805
  effectiveValue: this.settings.noRuby || !1,
7805
7806
  isEffective: this.layout !== S.fixed && this.metadata?.languages?.includes("ja") || !1,
7806
7807
  onChange: (t) => {
7807
- this.updatePreference("noRuby", t || null);
7808
+ this.updatePreference("noRuby", t ?? null);
7808
7809
  }
7809
7810
  });
7810
7811
  }
7811
7812
  get optimalLineLength() {
7812
- return new R({
7813
+ return new x({
7813
7814
  initialValue: this.preferences.optimalLineLength,
7814
7815
  effectiveValue: this.settings.optimalLineLength,
7815
7816
  isEffective: this.layout !== S.fixed,
@@ -7826,29 +7827,29 @@ class zi {
7826
7827
  effectiveValue: this.settings.pageGutter,
7827
7828
  isEffective: this.layout !== S.fixed && !this.settings.scroll,
7828
7829
  onChange: (t) => {
7829
- this.updatePreference("pageGutter", t || null);
7830
+ this.updatePreference("pageGutter", t ?? null);
7830
7831
  }
7831
7832
  });
7832
7833
  }
7833
7834
  get paragraphIndent() {
7834
- return new R({
7835
+ return new x({
7835
7836
  initialValue: this.preferences.paragraphIndent,
7836
7837
  effectiveValue: this.settings.paragraphIndent || 0,
7837
7838
  isEffective: this.layout !== S.fixed && this.preferences.paragraphIndent !== null,
7838
7839
  onChange: (t) => {
7839
- this.updatePreference("paragraphIndent", t || null);
7840
+ this.updatePreference("paragraphIndent", t ?? null);
7840
7841
  },
7841
7842
  supportedRange: qt.range,
7842
7843
  step: qt.step
7843
7844
  });
7844
7845
  }
7845
7846
  get paragraphSpacing() {
7846
- return new R({
7847
+ return new x({
7847
7848
  initialValue: this.preferences.paragraphSpacing,
7848
7849
  effectiveValue: this.settings.paragraphSpacing || 0,
7849
7850
  isEffective: this.layout !== S.fixed && this.preferences.paragraphSpacing !== null,
7850
7851
  onChange: (t) => {
7851
- this.updatePreference("paragraphSpacing", t || null);
7852
+ this.updatePreference("paragraphSpacing", t ?? null);
7852
7853
  },
7853
7854
  supportedRange: Kt.range,
7854
7855
  step: Kt.step
@@ -7860,7 +7861,7 @@ class zi {
7860
7861
  effectiveValue: this.settings.scroll || !1,
7861
7862
  isEffective: this.layout !== S.fixed,
7862
7863
  onChange: (t) => {
7863
- this.updatePreference("scroll", t || null);
7864
+ this.updatePreference("scroll", t ?? null);
7864
7865
  }
7865
7866
  });
7866
7867
  }
@@ -7870,7 +7871,7 @@ class zi {
7870
7871
  effectiveValue: this.settings.scrollPaddingTop || 0,
7871
7872
  isEffective: this.layout !== S.fixed && !!this.settings.scroll && this.preferences.scrollPaddingTop !== null,
7872
7873
  onChange: (t) => {
7873
- this.updatePreference("scrollPaddingTop", t || null);
7874
+ this.updatePreference("scrollPaddingTop", t ?? null);
7874
7875
  }
7875
7876
  });
7876
7877
  }
@@ -7880,7 +7881,7 @@ class zi {
7880
7881
  effectiveValue: this.settings.scrollPaddingBottom || 0,
7881
7882
  isEffective: this.layout !== S.fixed && !!this.settings.scroll && this.preferences.scrollPaddingBottom !== null,
7882
7883
  onChange: (t) => {
7883
- this.updatePreference("scrollPaddingBottom", t || null);
7884
+ this.updatePreference("scrollPaddingBottom", t ?? null);
7884
7885
  }
7885
7886
  });
7886
7887
  }
@@ -7890,7 +7891,7 @@ class zi {
7890
7891
  effectiveValue: this.settings.scrollPaddingLeft || 0,
7891
7892
  isEffective: this.layout !== S.fixed && !!this.settings.scroll && this.preferences.scrollPaddingLeft !== null,
7892
7893
  onChange: (t) => {
7893
- this.updatePreference("scrollPaddingLeft", t || null);
7894
+ this.updatePreference("scrollPaddingLeft", t ?? null);
7894
7895
  }
7895
7896
  });
7896
7897
  }
@@ -7900,7 +7901,7 @@ class zi {
7900
7901
  effectiveValue: this.settings.scrollPaddingRight || 0,
7901
7902
  isEffective: this.layout !== S.fixed && !!this.settings.scroll && this.preferences.scrollPaddingRight !== null,
7902
7903
  onChange: (t) => {
7903
- this.updatePreference("scrollPaddingRight", t || null);
7904
+ this.updatePreference("scrollPaddingRight", t ?? null);
7904
7905
  }
7905
7906
  });
7906
7907
  }
@@ -7910,7 +7911,7 @@ class zi {
7910
7911
  effectiveValue: this.settings.selectionBackgroundColor || dt.RS__selectionBackgroundColor,
7911
7912
  isEffective: this.layout !== S.fixed && this.preferences.selectionBackgroundColor !== null,
7912
7913
  onChange: (t) => {
7913
- this.updatePreference("selectionBackgroundColor", t || null);
7914
+ this.updatePreference("selectionBackgroundColor", t ?? null);
7914
7915
  }
7915
7916
  });
7916
7917
  }
@@ -7920,7 +7921,7 @@ class zi {
7920
7921
  effectiveValue: this.settings.selectionTextColor || dt.RS__selectionTextColor,
7921
7922
  isEffective: this.layout !== S.fixed && this.preferences.selectionTextColor !== null,
7922
7923
  onChange: (t) => {
7923
- this.updatePreference("selectionTextColor", t || null);
7924
+ this.updatePreference("selectionTextColor", t ?? null);
7924
7925
  }
7925
7926
  });
7926
7927
  }
@@ -7930,7 +7931,7 @@ class zi {
7930
7931
  effectiveValue: this.settings.textAlign || J.start,
7931
7932
  isEffective: this.layout !== S.fixed && this.preferences.textAlign !== null,
7932
7933
  onChange: (t) => {
7933
- this.updatePreference("textAlign", t || null);
7934
+ this.updatePreference("textAlign", t ?? null);
7934
7935
  },
7935
7936
  supportedValues: Object.values(J)
7936
7937
  });
@@ -7941,7 +7942,7 @@ class zi {
7941
7942
  effectiveValue: this.settings.textColor || dt.RS__textColor,
7942
7943
  isEffective: this.layout !== S.fixed && this.preferences.textColor !== null,
7943
7944
  onChange: (t) => {
7944
- this.updatePreference("textColor", t || null);
7945
+ this.updatePreference("textColor", t ?? null);
7945
7946
  }
7946
7947
  });
7947
7948
  }
@@ -7951,7 +7952,7 @@ class zi {
7951
7952
  effectiveValue: this.settings.textNormalization || !1,
7952
7953
  isEffective: this.layout !== S.fixed,
7953
7954
  onChange: (t) => {
7954
- this.updatePreference("textNormalization", t || null);
7955
+ this.updatePreference("textNormalization", t ?? null);
7955
7956
  }
7956
7957
  });
7957
7958
  }
@@ -7961,17 +7962,17 @@ class zi {
7961
7962
  effectiveValue: this.settings.visitedColor || dt.RS__visitedColor,
7962
7963
  isEffective: this.layout !== S.fixed && this.preferences.visitedColor !== null,
7963
7964
  onChange: (t) => {
7964
- this.updatePreference("visitedColor", t || null);
7965
+ this.updatePreference("visitedColor", t ?? null);
7965
7966
  }
7966
7967
  });
7967
7968
  }
7968
7969
  get wordSpacing() {
7969
- return new R({
7970
+ return new x({
7970
7971
  initialValue: this.preferences.wordSpacing,
7971
7972
  effectiveValue: this.settings.wordSpacing || 0,
7972
7973
  isEffective: this.layout !== S.fixed && this.preferences.wordSpacing !== null,
7973
7974
  onChange: (t) => {
7974
- this.updatePreference("wordSpacing", t || null);
7975
+ this.updatePreference("wordSpacing", t ?? null);
7975
7976
  },
7976
7977
  supportedRange: Zt.range,
7977
7978
  step: Zt.step
@@ -7983,7 +7984,7 @@ class Mi {
7983
7984
  this.backgroundColor = t.backgroundColor || e.backgroundColor || null, this.blendFilter = typeof t.blendFilter == "boolean" ? t.blendFilter : e.blendFilter ?? null, this.columnCount = t.columnCount !== void 0 ? t.columnCount : e.columnCount !== void 0 ? e.columnCount : null, this.constraint = t.constraint || e.constraint, this.darkenFilter = typeof t.darkenFilter == "boolean" ? t.darkenFilter : e.darkenFilter ?? null, this.deprecatedFontSize = typeof t.deprecatedFontSize == "boolean" ? t.deprecatedFontSize : e.deprecatedFontSize ?? null, this.fontFamily = t.fontFamily || e.fontFamily || null, this.fontSize = t.fontSize !== void 0 ? t.fontSize : e.fontSize !== void 0 ? e.fontSize : null, this.fontSizeNormalize = typeof t.fontSizeNormalize == "boolean" ? t.fontSizeNormalize : e.fontSizeNormalize ?? null, this.fontOpticalSizing = typeof t.fontOpticalSizing == "boolean" ? t.fontOpticalSizing : e.fontOpticalSizing ?? null, this.fontWeight = t.fontWeight !== void 0 ? t.fontWeight : e.fontWeight !== void 0 ? e.fontWeight : null, this.fontWidth = t.fontWidth !== void 0 ? t.fontWidth : e.fontWidth !== void 0 ? e.fontWidth : null, this.hyphens = typeof t.hyphens == "boolean" ? t.hyphens : e.hyphens ?? null, this.invertFilter = typeof t.invertFilter == "boolean" ? t.invertFilter : e.invertFilter ?? null, this.invertGaijiFilter = typeof t.invertGaijiFilter == "boolean" ? t.invertGaijiFilter : e.invertGaijiFilter ?? null, this.iOSPatch = this.deprecatedFontSize || t.iOSPatch === !1 ? !1 : t.iOSPatch === !0 ? (T.OS.iOS || T.OS.iPadOS) && T.iOSRequest === "mobile" : e.iOSPatch, this.iPadOSPatch = this.deprecatedFontSize || t.iPadOSPatch === !1 ? !1 : t.iPadOSPatch === !0 ? T.OS.iPadOS && T.iOSRequest === "desktop" : e.iPadOSPatch, this.letterSpacing = t.letterSpacing !== void 0 ? t.letterSpacing : e.letterSpacing !== void 0 ? e.letterSpacing : null, this.ligatures = typeof t.ligatures == "boolean" ? t.ligatures : e.ligatures ?? null, this.lineHeight = t.lineHeight !== void 0 ? t.lineHeight : e.lineHeight !== void 0 ? e.lineHeight : null, this.linkColor = t.linkColor || e.linkColor || null, this.maximalLineLength = t.maximalLineLength === null ? null : t.maximalLineLength || e.maximalLineLength || null, this.minimalLineLength = t.minimalLineLength === null ? null : t.minimalLineLength || e.minimalLineLength || null, this.noRuby = typeof t.noRuby == "boolean" ? t.noRuby : e.noRuby ?? null, this.optimalLineLength = t.optimalLineLength || e.optimalLineLength, this.pageGutter = t.pageGutter !== void 0 ? t.pageGutter : e.pageGutter !== void 0 ? e.pageGutter : null, this.paragraphIndent = t.paragraphIndent !== void 0 ? t.paragraphIndent : e.paragraphIndent !== void 0 ? e.paragraphIndent : null, this.paragraphSpacing = t.paragraphSpacing !== void 0 ? t.paragraphSpacing : e.paragraphSpacing !== void 0 ? e.paragraphSpacing : null, this.scroll = typeof t.scroll == "boolean" ? t.scroll : e.scroll ?? null, this.scrollPaddingTop = t.scrollPaddingTop !== void 0 ? t.scrollPaddingTop : e.scrollPaddingTop !== void 0 ? e.scrollPaddingTop : null, this.scrollPaddingBottom = t.scrollPaddingBottom !== void 0 ? t.scrollPaddingBottom : e.scrollPaddingBottom !== void 0 ? e.scrollPaddingBottom : null, this.scrollPaddingLeft = t.scrollPaddingLeft !== void 0 ? t.scrollPaddingLeft : e.scrollPaddingLeft !== void 0 ? e.scrollPaddingLeft : null, this.scrollPaddingRight = t.scrollPaddingRight !== void 0 ? t.scrollPaddingRight : e.scrollPaddingRight !== void 0 ? e.scrollPaddingRight : null, this.selectionBackgroundColor = t.selectionBackgroundColor || e.selectionBackgroundColor || null, this.selectionTextColor = t.selectionTextColor || e.selectionTextColor || null, this.textAlign = t.textAlign || e.textAlign || null, this.textColor = t.textColor || e.textColor || null, this.textNormalization = typeof t.textNormalization == "boolean" ? t.textNormalization : e.textNormalization ?? null, this.visitedColor = t.visitedColor || e.visitedColor || null, this.wordSpacing = t.wordSpacing !== void 0 ? t.wordSpacing : e.wordSpacing !== void 0 ? e.wordSpacing : null, this.experiments = e.experiments || null;
7984
7985
  }
7985
7986
  }
7986
- function Ft(s) {
7987
+ function Nt(s) {
7987
7988
  const t = getComputedStyle(s), e = parseFloat(t.paddingLeft || "0"), i = parseFloat(t.paddingRight || "0");
7988
7989
  return s.clientWidth - e - i;
7989
7990
  }
@@ -8003,13 +8004,13 @@ class gs extends re {
8003
8004
  toCSSProperties() {
8004
8005
  const t = {};
8005
8006
  return this.backgroundColor && (t["--RS__backgroundColor"] = this.backgroundColor), this.baseFontFamily && (t["--RS__baseFontFamily"] = this.baseFontFamily), this.baseFontSize != null && (t["--RS__baseFontSize"] = this.toRem(this.baseFontSize)), this.baseLineHeight != null && (t["--RS__baseLineHeight"] = this.toUnitless(this.baseLineHeight)), this.boxSizingMedia && (t["--RS__boxSizingMedia"] = this.boxSizingMedia), this.boxSizingTable && (t["--RS__boxSizingTable"] = this.boxSizingTable), this.colWidth != null && (t["--RS__colWidth"] = this.colWidth), this.colCount != null && (t["--RS__colCount"] = this.toUnitless(this.colCount)), this.colGap != null && (t["--RS__colGap"] = this.toPx(this.colGap)), this.codeFontFamily && (t["--RS__codeFontFamily"] = this.codeFontFamily), this.compFontFamily && (t["--RS__compFontFamily"] = this.compFontFamily), this.defaultLineLength != null && (t["--RS__defaultLineLength"] = this.toPx(this.defaultLineLength)), this.flowSpacing != null && (t["--RS__flowSpacing"] = this.toRem(this.flowSpacing)), this.humanistTf && (t["--RS__humanistTf"] = this.humanistTf), this.linkColor && (t["--RS__linkColor"] = this.linkColor), this.maxMediaWidth && (t["--RS__maxMediaWidth"] = this.toVw(this.maxMediaWidth)), this.maxMediaHeight && (t["--RS__maxMediaHeight"] = this.toVh(this.maxMediaHeight)), this.modernTf && (t["--RS__modernTf"] = this.modernTf), this.monospaceTf && (t["--RS__monospaceTf"] = this.monospaceTf), this.noOverflow && (t["--RS__disableOverflow"] = this.toFlag("noOverflow")), this.noVerticalPagination && (t["--RS__disablePagination"] = this.toFlag("noVerticalPagination")), this.oldStyleTf && (t["--RS__oldStyleTf"] = this.oldStyleTf), this.pageGutter != null && (t["--RS__pageGutter"] = this.toPx(this.pageGutter)), this.paraIndent != null && (t["--RS__paraIndent"] = this.toRem(this.paraIndent)), this.paraSpacing != null && (t["--RS__paraSpacing"] = this.toRem(this.paraSpacing)), this.primaryColor && (t["--RS__primaryColor"] = this.primaryColor), this.sansSerifJa && (t["--RS__sans-serif-ja"] = this.sansSerifJa), this.sansSerifJaV && (t["--RS__sans-serif-ja-v"] = this.sansSerifJaV), this.sansTf && (t["--RS__sansTf"] = this.sansTf), this.scrollPaddingBottom != null && (t["--RS__scrollPaddingBottom"] = this.toPx(this.scrollPaddingBottom)), this.scrollPaddingLeft != null && (t["--RS__scrollPaddingLeft"] = this.toPx(this.scrollPaddingLeft)), this.scrollPaddingRight != null && (t["--RS__scrollPaddingRight"] = this.toPx(this.scrollPaddingRight)), this.scrollPaddingTop != null && (t["--RS__scrollPaddingTop"] = this.toPx(this.scrollPaddingTop)), this.secondaryColor && (t["--RS__secondaryColor"] = this.secondaryColor), this.selectionBackgroundColor && (t["--RS__selectionBackgroundColor"] = this.selectionBackgroundColor), this.selectionTextColor && (t["--RS__selectionTextColor"] = this.selectionTextColor), this.serifJa && (t["--RS__serif-ja"] = this.serifJa), this.serifJaV && (t["--RS__serif-ja-v"] = this.serifJaV), this.textColor && (t["--RS__textColor"] = this.textColor), this.typeScale && (t["--RS__typeScale"] = this.toUnitless(this.typeScale)), this.visitedColor && (t["--RS__visitedColor"] = this.visitedColor), this.experiments && this.experiments.forEach((e) => {
8006
- t["--RS__" + e] = Ie[e].value;
8007
+ t["--RS__" + e] = Ue[e].value;
8007
8008
  }), t;
8008
8009
  }
8009
8010
  }
8010
8011
  class fs {
8011
8012
  constructor(t) {
8012
- this.rsProperties = t.rsProperties, this.userProperties = t.userProperties, this.lineLengths = t.lineLengths, this.container = t.container, this.containerParent = t.container.parentElement || document.documentElement, this.constraint = t.constraint, this.cachedColCount = t.userProperties.colCount, this.effectiveContainerWidth = Ft(this.containerParent);
8013
+ this.rsProperties = t.rsProperties, this.userProperties = t.userProperties, this.lineLengths = t.lineLengths, this.container = t.container, this.containerParent = t.container.parentElement || document.documentElement, this.constraint = t.constraint, this.cachedColCount = t.userProperties.colCount, this.effectiveContainerWidth = Nt(this.containerParent);
8013
8014
  }
8014
8015
  update(t) {
8015
8016
  this.cachedColCount = t.columnCount, t.constraint !== this.constraint && (this.constraint = t.constraint), t.pageGutter !== this.rsProperties.pageGutter && (this.rsProperties.pageGutter = t.pageGutter), t.scrollPaddingBottom !== this.rsProperties.scrollPaddingBottom && (this.rsProperties.scrollPaddingBottom = t.scrollPaddingBottom), t.scrollPaddingLeft !== this.rsProperties.scrollPaddingLeft && (this.rsProperties.scrollPaddingLeft = t.scrollPaddingLeft), t.scrollPaddingRight !== this.rsProperties.scrollPaddingRight && (this.rsProperties.scrollPaddingRight = t.scrollPaddingRight), t.scrollPaddingTop !== this.rsProperties.scrollPaddingTop && (this.rsProperties.scrollPaddingTop = t.scrollPaddingTop), t.experiments !== this.rsProperties.experiments && (this.rsProperties.experiments = t.experiments), this.lineLengths.update({
@@ -8076,7 +8077,7 @@ class fs {
8076
8077
  // TODO: As scroll shows, the effective line-length
8077
8078
  // should be the same as uncompensated when scale >= 1
8078
8079
  paginate(t, e, i) {
8079
- const n = Math.round(Ft(this.containerParent) - this.constraint), r = this.getCompensatedMetrics(t, e), { zoomCompensation: o, optimal: a, minimal: l, maximal: h } = r, c = () => n >= a && h !== null ? Math.min(Math.round(h * o), n) : n;
8080
+ const n = Math.round(Nt(this.containerParent) - this.constraint), r = this.getCompensatedMetrics(t, e), { zoomCompensation: o, optimal: a, minimal: l, maximal: h } = r, c = () => n >= a && h !== null ? Math.min(Math.round(h * o), n) : n;
8080
8081
  let u = 1, m = n;
8081
8082
  if (i === void 0)
8082
8083
  return {
@@ -8122,7 +8123,7 @@ class fs {
8122
8123
  }
8123
8124
  // This behaves as paginate where colCount = 1
8124
8125
  computeScrollLength(t, e) {
8125
- const i = Math.round(Ft(this.containerParent) - this.constraint), n = this.getCompensatedMetrics(t && (t < 1 || e) ? t : 1, e), r = n.zoomCompensation, o = n.optimal, a = n.maximal;
8126
+ const i = Math.round(Nt(this.containerParent) - this.constraint), n = this.getCompensatedMetrics(t && (t < 1 || e) ? t : 1, e), r = n.zoomCompensation, o = n.optimal, a = n.maximal;
8126
8127
  let l, h = i, c = Math.round(o * r);
8127
8128
  if (a === null)
8128
8129
  c = i;
@@ -8145,7 +8146,7 @@ class fs {
8145
8146
  }
8146
8147
  }
8147
8148
  const ys = `/*!
8148
- * Readium CSS v.2.0.0
8149
+ * Readium CSS v.2.0.1
8149
8150
  * Copyright (c) 2017–2026. Readium Foundation. All rights reserved.
8150
8151
  * Use of this source code is governed by a BSD-style license which is detailed in the
8151
8152
  * LICENSE file present in the project repository where this source code is maintained.
@@ -8508,8 +8509,7 @@ body{
8508
8509
  text-indent:var(--USER__paraIndent) !important;
8509
8510
  }
8510
8511
 
8511
- :root[style*="--USER__paraIndent"] p *,
8512
- :root[style*="--USER__paraIndent"] p:first-letter{
8512
+ :root[style*="--USER__paraIndent"] p *{
8513
8513
  text-indent:0 !important;
8514
8514
  }
8515
8515
 
@@ -8734,7 +8734,7 @@ body{
8734
8734
  :root[style*="readium-iPadOSPatch-on"] p:not(:has(b, cite, em, i, q, s, small, span, strong)):first-line{
8735
8735
  -webkit-text-zoom:normal;
8736
8736
  }`, Ss = `/*!
8737
- * Readium CSS v.2.0.0
8737
+ * Readium CSS v.2.0.1
8738
8738
  * Copyright (c) 2017–2026. Readium Foundation. All rights reserved.
8739
8739
  * Use of this source code is governed by a BSD-style license which is detailed in the
8740
8740
  * LICENSE file present in the project repository where this source code is maintained.
@@ -9155,7 +9155,7 @@ table{
9155
9155
  max-width:var(--RS__maxMediaWidth);
9156
9156
  box-sizing:var(--RS__boxSizingTable);
9157
9157
  }`, bs = `/*!
9158
- * Readium CSS v.2.0.0
9158
+ * Readium CSS v.2.0.1
9159
9159
  * Copyright (c) 2017–2026. Readium Foundation. All rights reserved.
9160
9160
  * Use of this source code is governed by a BSD-style license which is detailed in the
9161
9161
  * LICENSE file present in the project repository where this source code is maintained.
@@ -9409,7 +9409,7 @@ function ws(s, t) {
9409
9409
  id: "readium-css-before",
9410
9410
  as: "link",
9411
9411
  target: "head",
9412
- blob: new Blob([Nt(Ss)], { type: "text/css" }),
9412
+ blob: new Blob([Ft(Ss)], { type: "text/css" }),
9413
9413
  rel: "stylesheet"
9414
9414
  }), o.unshift(
9415
9415
  // Readium CSS Default - only for reflowable AND no existing styles
@@ -9417,7 +9417,7 @@ function ws(s, t) {
9417
9417
  id: "readium-css-default",
9418
9418
  as: "link",
9419
9419
  target: "head",
9420
- blob: new Blob([Nt(bs)], { type: "text/css" }),
9420
+ blob: new Blob([Ft(bs)], { type: "text/css" }),
9421
9421
  rel: "stylesheet",
9422
9422
  condition: (a) => !(a.querySelector("link[rel='stylesheet']") || a.querySelector("style") || a.querySelector("[style]:not([style=''])"))
9423
9423
  },
@@ -9426,7 +9426,7 @@ function ws(s, t) {
9426
9426
  id: "readium-css-after",
9427
9427
  as: "link",
9428
9428
  target: "head",
9429
- blob: new Blob([Nt(ys)], { type: "text/css" }),
9429
+ blob: new Blob([Ft(ys)], { type: "text/css" }),
9430
9430
  rel: "stylesheet"
9431
9431
  }
9432
9432
  )), [
@@ -9571,7 +9571,7 @@ class Sn extends rn {
9571
9571
  async resizeHandler() {
9572
9572
  const t = this.container.parentElement || document.documentElement;
9573
9573
  if (this._layout === S.fixed)
9574
- this.container.style.width = `${Ft(t) - this._settings.constraint}px`, this.framePool.resizeHandler();
9574
+ this.container.style.width = `${Nt(t) - this._settings.constraint}px`, this.framePool.resizeHandler();
9575
9575
  else {
9576
9576
  const e = this._css.userProperties.colCount, i = this._css.userProperties.lineLength;
9577
9577
  this._css.resizeHandler(), (this._css.userProperties.view !== "scroll" && e !== this._css.userProperties.colCount || i !== this._css.userProperties.lineLength) && await this.commitCSS(this._css);
@@ -9608,9 +9608,9 @@ class Sn extends rn {
9608
9608
  this.listeners.frameLoaded(this._cframes[0].iframe.contentWindow), this.listeners.positionChanged(this.currentLocation);
9609
9609
  break;
9610
9610
  case "first_visible_locator":
9611
- const i = N.deserialize(e);
9611
+ const i = F.deserialize(e);
9612
9612
  if (!i) break;
9613
- this.currentLocation = new N({
9613
+ this.currentLocation = new F({
9614
9614
  href: this.currentLocation.href,
9615
9615
  type: this.currentLocation.type,
9616
9616
  title: this.currentLocation.title,
@@ -9899,25 +9899,53 @@ class Sn extends rn {
9899
9899
  }
9900
9900
  }
9901
9901
  const Ps = `// PreservePitchProcessor.js
9902
- // AudioWorklet processor for pitch preservation via pitch shifting
9902
+ // AudioWorklet processor for pitch preservation via pitch shifting.
9903
+ //
9904
+ // Architecture:
9905
+ // - Overlap-add (OLA) phase vocoder with an iterative in-place Cooley-Tukey FFT/IFFT.
9906
+ // - All intermediate buffers are pre-allocated in the constructor; the hot path
9907
+ // (process → _processBuffer → _fft) is allocation-free and GC-safe.
9908
+ // - An output ring buffer decouples OLA processing (fires every hopSize input
9909
+ // samples) from the Web Audio render quantum (128 frames), so process() always
9910
+ // fills outputChannel completely.
9903
9911
 
9904
9912
  class PreservePitchProcessor extends AudioWorkletProcessor {
9905
9913
  constructor() {
9906
9914
  super();
9907
- this.bufferSize = 1024;
9908
- this.hopSize = 256;
9909
- this.overlap = this.bufferSize - this.hopSize;
9910
- this.inputBuffer = new Float32Array(this.bufferSize);
9911
- this.outputBuffer = new Float32Array(this.bufferSize);
9912
- this.window = new Float32Array(this.bufferSize);
9913
- this.bufferIndex = 0;
9915
+ this.bufferSize = 1024;
9916
+ this.hopSize = 256;
9917
+ this.overlap = this.bufferSize - this.hopSize;
9914
9918
  this.pitchFactor = 1.0;
9915
9919
 
9916
- // Hann window
9920
+ // Sliding input window (always holds the last bufferSize samples)
9921
+ this.inputBuffer = new Float32Array(this.bufferSize);
9922
+ this.inputFill = 0; // samples loaded during startup (saturates at bufferSize)
9923
+ this.hopAccum = 0; // new samples since last OLA step; triggers a step at hopSize
9924
+
9925
+ // OLA output accumulator: overlap-add results accumulate here; hopSize samples
9926
+ // are drained to the ring buffer and the remainder shifts down each OLA step.
9927
+ this.olaBuffer = new Float32Array(this.bufferSize);
9928
+
9929
+ // Output FIFO ring buffer — power-of-2 size for allocation-free modulo wrapping.
9930
+ this._ringSize = 4096;
9931
+ this._ring = new Float32Array(this._ringSize);
9932
+ this._ringMask = this._ringSize - 1;
9933
+ this._ringWrite = 0;
9934
+ this._ringRead = 0;
9935
+ this._ringAvail = 0;
9936
+
9937
+ // Hann window (pre-computed, never mutated)
9938
+ this.window = new Float32Array(this.bufferSize);
9917
9939
  for (let i = 0; i < this.bufferSize; i++) {
9918
9940
  this.window[i] = 0.5 * (1 - Math.cos(2 * Math.PI * i / this.bufferSize));
9919
9941
  }
9920
9942
 
9943
+ // Pre-allocated FFT work buffers — never re-created in the hot path
9944
+ this._re = new Float64Array(this.bufferSize);
9945
+ this._im = new Float64Array(this.bufferSize);
9946
+ this._shiftedRe = new Float64Array(this.bufferSize);
9947
+ this._shiftedIm = new Float64Array(this.bufferSize);
9948
+
9921
9949
  this.port.onmessage = (event) => {
9922
9950
  if (event.data.type === 'setPitchFactor') {
9923
9951
  this.pitchFactor = event.data.factor;
@@ -9926,123 +9954,160 @@ class PreservePitchProcessor extends AudioWorkletProcessor {
9926
9954
  }
9927
9955
 
9928
9956
  process(inputs, outputs) {
9929
- const input = inputs[0];
9957
+ const input = inputs[0];
9930
9958
  const output = outputs[0];
9931
-
9932
9959
  if (!input || !output) return true;
9960
+ const inCh = input[0];
9961
+ const outCh = output[0];
9962
+ if (!inCh || !outCh) return true;
9963
+
9964
+ const newCount = inCh.length; // always 128 under normal Web Audio conditions
9965
+
9966
+ // --- 1. Push new samples into the sliding input window ---
9967
+ if (this.inputFill < this.bufferSize) {
9968
+ // Startup: fill the window until we have a full bufferSize frame.
9969
+ // Since bufferSize (1024) is an exact multiple of the render quantum (128)
9970
+ // this branch always copies exactly newCount samples.
9971
+ this.inputBuffer.set(inCh, this.inputFill);
9972
+ this.inputFill += newCount;
9973
+ } else {
9974
+ // Steady state: slide left by newCount, append the new quantum at the end.
9975
+ this.inputBuffer.copyWithin(0, newCount);
9976
+ this.inputBuffer.set(inCh, this.bufferSize - newCount);
9977
+ }
9978
+ this.hopAccum += newCount;
9933
9979
 
9934
- const inputChannel = input[0];
9935
- const outputChannel = output[0];
9936
-
9937
- // Accumulate input
9938
- for (let i = 0; i < inputChannel.length; i++) {
9939
- this.inputBuffer[this.bufferIndex] = inputChannel[i];
9940
- this.bufferIndex++;
9980
+ // --- 2. Run OLA step(s) whenever hopAccum reaches hopSize ---
9981
+ // During startup we skip processing until a full window is available.
9982
+ while (this.inputFill >= this.bufferSize && this.hopAccum >= this.hopSize) {
9983
+ this.hopAccum -= this.hopSize;
9984
+ this._processBuffer(); // drains hopSize samples into _ring
9985
+ }
9941
9986
 
9942
- if (this.bufferIndex >= this.bufferSize) {
9943
- // Process buffer
9944
- this.processBuffer();
9945
- // Output hopSize samples
9946
- for (let j = 0; j < this.hopSize; j++) {
9947
- outputChannel[j] = this.outputBuffer[j];
9948
- }
9949
- // Shift buffer
9950
- for (let j = 0; j < this.overlap; j++) {
9951
- this.inputBuffer[j] = this.inputBuffer[j + this.hopSize];
9952
- }
9953
- this.bufferIndex = this.overlap;
9954
- // Clear output buffer for next
9955
- this.outputBuffer.fill(0);
9987
+ // --- 3. Drain output ring into outputChannel ---
9988
+ // Output silence during the initial buffering latency (bufferSize samples ≈ 23 ms
9989
+ // at 44100 Hz). Once the ring has data it stays ahead of demand.
9990
+ if (this._ringAvail >= newCount) {
9991
+ for (let i = 0; i < newCount; i++) {
9992
+ outCh[i] = this._ring[this._ringRead];
9993
+ this._ringRead = (this._ringRead + 1) & this._ringMask;
9956
9994
  }
9995
+ this._ringAvail -= newCount;
9996
+ } else {
9997
+ outCh.fill(0);
9957
9998
  }
9958
9999
 
9959
10000
  return true;
9960
10001
  }
9961
10002
 
9962
- processBuffer() {
9963
- // Apply window
9964
- let windowed = new Float32Array(this.bufferSize);
9965
- for (let i = 0; i < this.bufferSize; i++) {
9966
- windowed[i] = this.inputBuffer[i] * this.window[i];
10003
+ _processBuffer() {
10004
+ const N = this.bufferSize;
10005
+ const re = this._re;
10006
+ const im = this._im;
10007
+ const shiftedRe = this._shiftedRe;
10008
+ const shiftedIm = this._shiftedIm;
10009
+ const win = this.window;
10010
+
10011
+ // Load windowed input into real part; zero imaginary part
10012
+ for (let i = 0; i < N; i++) {
10013
+ re[i] = this.inputBuffer[i] * win[i];
10014
+ im[i] = 0;
9967
10015
  }
9968
10016
 
9969
- // FFT
9970
- let fftResult = this.fft(windowed);
10017
+ this._fft(re, im, false);
10018
+
10019
+ // Spectral pitch shift: map bin k → round(k * factor)
10020
+ shiftedRe.fill(0);
10021
+ shiftedIm.fill(0);
10022
+ const half = N >> 1;
10023
+ const factor = this.pitchFactor;
10024
+ for (let k = 0; k <= half; k++) {
10025
+ const newK = Math.round(k * factor);
10026
+ if (newK <= half) {
10027
+ shiftedRe[newK] += re[k];
10028
+ shiftedIm[newK] += im[k];
10029
+ // Restore conjugate symmetry so the IFFT yields a real-valued signal
10030
+ if (newK > 0 && newK < half) {
10031
+ shiftedRe[N - newK] = shiftedRe[newK];
10032
+ shiftedIm[N - newK] = -shiftedIm[newK];
10033
+ }
10034
+ }
10035
+ }
9971
10036
 
9972
- // Pitch shift
9973
- let shifted = this.pitchShift(fftResult, this.pitchFactor);
10037
+ this._fft(shiftedRe, shiftedIm, true); // in-place IFFT
9974
10038
 
9975
- // IFFT
9976
- let ifftResult = this.ifft(shifted);
10039
+ // Overlap-add into olaBuffer
10040
+ for (let i = 0; i < N; i++) {
10041
+ this.olaBuffer[i] += shiftedRe[i] * win[i];
10042
+ }
9977
10043
 
9978
- // Overlap-add
9979
- for (let i = 0; i < this.bufferSize; i++) {
9980
- this.outputBuffer[i] += ifftResult[i] * this.window[i];
10044
+ // Push hopSize output samples to the ring buffer
10045
+ for (let i = 0; i < this.hopSize; i++) {
10046
+ this._ring[this._ringWrite] = this.olaBuffer[i];
10047
+ this._ringWrite = (this._ringWrite + 1) & this._ringMask;
9981
10048
  }
10049
+ this._ringAvail += this.hopSize;
10050
+
10051
+ // Shift the OLA accumulator left by hopSize; clear the vacated tail
10052
+ this.olaBuffer.copyWithin(0, this.hopSize);
10053
+ this.olaBuffer.fill(0, this.bufferSize - this.hopSize);
9982
10054
  }
9983
10055
 
9984
- pitchShift(fft, factor) {
9985
- let N = fft.length;
9986
- let result = new Array(N).fill(null).map(() => ({ real: 0, imag: 0 }));
9987
- for (let k = 0; k < N / 2; k++) {
9988
- let newK = Math.round(k * factor);
9989
- if (newK < N / 2) {
9990
- result[newK] = fft[k];
9991
- result[N - newK] = fft[N - k]; // symmetric for real input
10056
+ /**
10057
+ * In-place iterative Cooley-Tukey FFT / IFFT.
10058
+ * Operates entirely on the caller-supplied Float64Arrays no allocation.
10059
+ *
10060
+ * @param {Float64Array} re Real parts (mutated in place)
10061
+ * @param {Float64Array} im Imaginary parts (mutated in place)
10062
+ * @param {boolean} inverse true → IFFT (divides by N), false → FFT
10063
+ */
10064
+ _fft(re, im, inverse) {
10065
+ const N = re.length;
10066
+
10067
+ // Bit-reversal permutation
10068
+ let j = 0;
10069
+ for (let i = 1; i < N; i++) {
10070
+ let bit = N >> 1;
10071
+ for (; j & bit; bit >>= 1) j ^= bit;
10072
+ j ^= bit;
10073
+ if (i < j) {
10074
+ let tmp;
10075
+ tmp = re[i]; re[i] = re[j]; re[j] = tmp;
10076
+ tmp = im[i]; im[i] = im[j]; im[j] = tmp;
9992
10077
  }
9993
10078
  }
9994
- return result;
9995
- }
9996
-
9997
- fft(input) {
9998
- let N = input.length;
9999
- if (N <= 1) return [{ real: input[0] || 0, imag: 0 }];
10000
- if ((N & (N - 1)) !== 0) throw new Error('N must be power of 2');
10001
10079
 
10002
- let even = this.fft(input.filter((_, i) => i % 2 === 0));
10003
- let odd = this.fft(input.filter((_, i) => i % 2 === 1));
10004
-
10005
- let result = new Array(N);
10006
- for (let k = 0; k < N / 2; k++) {
10007
- let t = odd[k];
10008
- let angle = -2 * Math.PI * k / N;
10009
- let twiddle = { real: Math.cos(angle), imag: Math.sin(angle) };
10010
- let twiddled = {
10011
- real: t.real * twiddle.real - t.imag * twiddle.imag,
10012
- imag: t.real * twiddle.imag + t.imag * twiddle.real
10013
- };
10014
- result[k] = {
10015
- real: even[k].real + twiddled.real,
10016
- imag: even[k].imag + twiddled.imag
10017
- };
10018
- result[k + N / 2] = {
10019
- real: even[k].real - twiddled.real,
10020
- imag: even[k].imag - twiddled.imag
10021
- };
10080
+ // Butterfly stages — O(N log N), no allocation
10081
+ const sign = inverse ? 1 : -1;
10082
+ for (let len = 2; len <= N; len <<= 1) {
10083
+ const halfLen = len >> 1;
10084
+ const ang = sign * Math.PI / halfLen;
10085
+ const wBaseRe = Math.cos(ang);
10086
+ const wBaseIm = Math.sin(ang);
10087
+ for (let i = 0; i < N; i += len) {
10088
+ let wRe = 1, wIm = 0;
10089
+ for (let k = 0; k < halfLen; k++) {
10090
+ const uRe = re[i + k];
10091
+ const uIm = im[i + k];
10092
+ const vRe = re[i + k + halfLen] * wRe - im[i + k + halfLen] * wIm;
10093
+ const vIm = re[i + k + halfLen] * wIm + im[i + k + halfLen] * wRe;
10094
+ re[i + k] = uRe + vRe;
10095
+ im[i + k] = uIm + vIm;
10096
+ re[i + k + halfLen] = uRe - vRe;
10097
+ im[i + k + halfLen] = uIm - vIm;
10098
+ const newWRe = wRe * wBaseRe - wIm * wBaseIm;
10099
+ wIm = wRe * wBaseIm + wIm * wBaseRe;
10100
+ wRe = newWRe;
10101
+ }
10102
+ }
10022
10103
  }
10023
- return result;
10024
- }
10025
-
10026
- ifft(input) {
10027
- let N = input.length;
10028
- // Conjugate
10029
- let conj = input.map(c => ({ real: c.real, imag: -c.imag }));
10030
- // FFT
10031
- let fftConj = this.fft(conj.map(c => c.real)); // wait, fft expects real array
10032
- // FFT on complex is needed, but simplify
10033
- // For simplicity, implement IFFT similarly
10034
- let result = new Float32Array(N);
10035
- for (let n = 0; n < N; n++) {
10036
- let sumReal = 0, sumImag = 0;
10037
- for (let k = 0; k < N; k++) {
10038
- let angle = 2 * Math.PI * k * n / N;
10039
- let c = input[k];
10040
- sumReal += c.real * Math.cos(angle) - c.imag * Math.sin(angle);
10041
- sumImag += c.real * Math.sin(angle) + c.imag * Math.cos(angle);
10104
+
10105
+ if (inverse) {
10106
+ for (let i = 0; i < N; i++) {
10107
+ re[i] /= N;
10108
+ im[i] /= N;
10042
10109
  }
10043
- result[n] = sumReal / N;
10044
10110
  }
10045
- return result;
10046
10111
  }
10047
10112
  }
10048
10113
 
@@ -10050,40 +10115,37 @@ registerProcessor('preserve-pitch-processor', PreservePitchProcessor);
10050
10115
  `;
10051
10116
  class Be {
10052
10117
  constructor(t) {
10053
- this.mediaElement = null, this.source = null, this.workletNode = null, this.url = null, this.ctx = t;
10118
+ this.workletNode = null, this.url = null, this.ctx = t;
10054
10119
  }
10055
10120
  static async createWorklet(t) {
10056
- const { ctx: e, mediaElement: i, pitchFactor: n, modulePath: r } = t, o = new Be(e);
10121
+ const { ctx: e, pitchFactor: i, modulePath: n } = t, r = new Be(e);
10057
10122
  try {
10058
- if (r)
10059
- await e.audioWorklet.addModule(r);
10123
+ if (n)
10124
+ await e.audioWorklet.addModule(n);
10060
10125
  else {
10061
- const a = new Blob([Ps], { type: "text/javascript" });
10062
- o.url = URL.createObjectURL(a), await e.audioWorklet.addModule(o.url);
10126
+ const o = new Blob([Ps], { type: "text/javascript" });
10127
+ r.url = URL.createObjectURL(o), await e.audioWorklet.addModule(r.url);
10063
10128
  }
10064
- } catch (a) {
10065
- throw o.destroy(), new Error(`Error adding module: ${a}`);
10129
+ } catch (o) {
10130
+ throw r.destroy(), new Error(`Error adding module: ${o}`);
10066
10131
  }
10067
10132
  try {
10068
- if (o.workletNode = new AudioWorkletNode(e, "preserve-pitch-processor"), n && o.updatePitchFactor(n), i) {
10069
- const a = e.createMediaElementSource(i);
10070
- a.connect(o.workletNode), o.mediaElement = i, o.source = a;
10071
- }
10072
- } catch (a) {
10073
- throw o.destroy(), new Error(`Error creating worklet node: ${a}`);
10133
+ r.workletNode = new AudioWorkletNode(e, "preserve-pitch-processor"), i && r.updatePitchFactor(i);
10134
+ } catch (o) {
10135
+ throw r.destroy(), new Error(`Error creating worklet node: ${o}`);
10074
10136
  }
10075
- return o;
10137
+ return r;
10076
10138
  }
10077
10139
  updatePitchFactor(t) {
10078
10140
  this.workletNode && this.workletNode.port.postMessage({ type: "setPitchFactor", factor: t });
10079
10141
  }
10080
10142
  destroy() {
10081
- this.workletNode && (this.workletNode.disconnect(), this.workletNode = null), this.source && (this.source.disconnect(), this.source = null), this.url && (URL.revokeObjectURL(this.url), this.url = null);
10143
+ this.workletNode && (this.workletNode.disconnect(), this.workletNode = null), this.url && (URL.revokeObjectURL(this.url), this.url = null);
10082
10144
  }
10083
10145
  }
10084
10146
  class Es {
10085
10147
  constructor(t) {
10086
- this.audioContext = null, this.sourceNode = null, this.gainNode = null, this.listeners = {}, this.currentVolume = 1, this.currentPlaybackRate = 1, this.isMutedValue = !1, this.isPlayingValue = !1, this.isPausedValue = !1, this.isLoadingValue = !1, this.isLoadedValue = !1, this.isEndedValue = !1, this.isStoppedValue = !1, this.worklet = null, this.webAudioActive = !1, this.boundOnCanPlayThrough = this.onCanPlayThrough.bind(this), this.boundOnTimeUpdate = this.onTimeUpdate.bind(this), this.boundOnError = this.onError.bind(this), this.boundOnEnded = this.onEnded.bind(this), this.boundOnStalled = this.onStalled.bind(this), this.boundOnEmptied = this.onEmptied.bind(this), this.boundOnSuspend = this.onSuspend.bind(this), this.boundOnWaiting = this.onWaiting.bind(this), this.boundOnLoadedMetadata = this.onLoadedMetadata.bind(this), this.boundOnSeeking = this.onSeeking.bind(this), this.boundOnSeeked = this.onSeeked.bind(this), this.boundOnPlay = this.onPlay.bind(this), this.boundOnPlaying = this.onPlaying.bind(this), this.boundOnPause = this.onPause.bind(this), this.boundOnProgress = this.onProgress.bind(this), this.playback = t.playback, this.mediaElement = document.createElement("audio"), this.mediaElement.addEventListener("canplaythrough", this.boundOnCanPlayThrough), this.mediaElement.addEventListener("timeupdate", this.boundOnTimeUpdate), this.mediaElement.addEventListener("error", this.boundOnError), this.mediaElement.addEventListener("ended", this.boundOnEnded), this.mediaElement.addEventListener("stalled", this.boundOnStalled), this.mediaElement.addEventListener("emptied", this.boundOnEmptied), this.mediaElement.addEventListener("suspend", this.boundOnSuspend), this.mediaElement.addEventListener("waiting", this.boundOnWaiting), this.mediaElement.addEventListener("loadedmetadata", this.boundOnLoadedMetadata), this.mediaElement.addEventListener("seeking", this.boundOnSeeking), this.mediaElement.addEventListener("seeked", this.boundOnSeeked), this.mediaElement.addEventListener("play", this.boundOnPlay), this.mediaElement.addEventListener("playing", this.boundOnPlaying), this.mediaElement.addEventListener("pause", this.boundOnPause), this.mediaElement.addEventListener("progress", this.boundOnProgress), this.mediaElement.currentTime = this.playback.state.currentTime;
10148
+ this.audioContext = null, this.sourceNode = null, this.gainNode = null, this.listeners = {}, this.isMutedValue = !1, this.isPlayingValue = !1, this.isPausedValue = !1, this.isLoadingValue = !1, this.isLoadedValue = !1, this.isEndedValue = !1, this.isStoppedValue = !1, this.worklet = null, this.webAudioActive = !1, this.boundOnCanPlayThrough = this.onCanPlayThrough.bind(this), this.boundOnTimeUpdate = this.onTimeUpdate.bind(this), this.boundOnError = this.onError.bind(this), this.boundOnEnded = this.onEnded.bind(this), this.boundOnStalled = this.onStalled.bind(this), this.boundOnEmptied = this.onEmptied.bind(this), this.boundOnSuspend = this.onSuspend.bind(this), this.boundOnWaiting = this.onWaiting.bind(this), this.boundOnLoadedMetadata = this.onLoadedMetadata.bind(this), this.boundOnSeeking = this.onSeeking.bind(this), this.boundOnSeeked = this.onSeeked.bind(this), this.boundOnPlay = this.onPlay.bind(this), this.boundOnPlaying = this.onPlaying.bind(this), this.boundOnPause = this.onPause.bind(this), this.boundOnProgress = this.onProgress.bind(this), this.playback = t.playback, this.mediaElement = document.createElement("audio"), this.mediaElement.addEventListener("canplaythrough", this.boundOnCanPlayThrough), this.mediaElement.addEventListener("timeupdate", this.boundOnTimeUpdate), this.mediaElement.addEventListener("error", this.boundOnError), this.mediaElement.addEventListener("ended", this.boundOnEnded), this.mediaElement.addEventListener("stalled", this.boundOnStalled), this.mediaElement.addEventListener("emptied", this.boundOnEmptied), this.mediaElement.addEventListener("suspend", this.boundOnSuspend), this.mediaElement.addEventListener("waiting", this.boundOnWaiting), this.mediaElement.addEventListener("loadedmetadata", this.boundOnLoadedMetadata), this.mediaElement.addEventListener("seeking", this.boundOnSeeking), this.mediaElement.addEventListener("seeked", this.boundOnSeeked), this.mediaElement.addEventListener("play", this.boundOnPlay), this.mediaElement.addEventListener("playing", this.boundOnPlaying), this.mediaElement.addEventListener("pause", this.boundOnPause), this.mediaElement.addEventListener("progress", this.boundOnProgress), this.mediaElement.currentTime = this.playback.state.currentTime;
10087
10149
  }
10088
10150
  /**
10089
10151
  * Adds an event listener to the audio engine.
@@ -10103,23 +10165,6 @@ class Es {
10103
10165
  (i) => i !== e
10104
10166
  ));
10105
10167
  }
10106
- deactivateWebAudio() {
10107
- this.worklet && (this.worklet.destroy(), this.worklet = null), this.sourceNode && (this.sourceNode.disconnect(), this.sourceNode = null), this.gainNode && (this.gainNode.disconnect(), this.gainNode = null), this.webAudioActive = !1;
10108
- }
10109
- /**
10110
- * Sets the media element for playback.
10111
- * @param element The HTML audio element to use.
10112
- */
10113
- setMediaElement(t) {
10114
- if (this.mediaElement.removeEventListener("canplaythrough", this.boundOnCanPlayThrough), this.mediaElement.removeEventListener("timeupdate", this.boundOnTimeUpdate), this.mediaElement.removeEventListener("error", this.boundOnError), this.mediaElement.removeEventListener("ended", this.boundOnEnded), this.mediaElement.removeEventListener("stalled", this.boundOnStalled), this.mediaElement.removeEventListener("emptied", this.boundOnEmptied), this.mediaElement.removeEventListener("suspend", this.boundOnSuspend), this.mediaElement.removeEventListener("waiting", this.boundOnWaiting), this.mediaElement.removeEventListener("loadedmetadata", this.boundOnLoadedMetadata), this.mediaElement.removeEventListener("seeking", this.boundOnSeeking), this.mediaElement.removeEventListener("seeked", this.boundOnSeeked), this.mediaElement.removeEventListener("play", this.boundOnPlay), this.mediaElement.removeEventListener("playing", this.boundOnPlaying), this.mediaElement.removeEventListener("pause", this.boundOnPause), this.mediaElement.removeEventListener("progress", this.boundOnProgress), this.mediaElement.pause(), this.isPlayingValue = !1, this.isPausedValue = !1, this.sourceNode && (this.sourceNode.disconnect(), this.sourceNode = null), this.mediaElement = t, this.mediaElement.addEventListener("canplaythrough", this.boundOnCanPlayThrough), this.mediaElement.addEventListener("timeupdate", this.boundOnTimeUpdate), this.mediaElement.addEventListener("error", this.boundOnError), this.mediaElement.addEventListener("ended", this.boundOnEnded), this.mediaElement.addEventListener("stalled", this.boundOnStalled), this.mediaElement.addEventListener("emptied", this.boundOnEmptied), this.mediaElement.addEventListener("suspend", this.boundOnSuspend), this.mediaElement.addEventListener("waiting", this.boundOnWaiting), this.mediaElement.addEventListener("loadedmetadata", this.boundOnLoadedMetadata), this.mediaElement.addEventListener("seeking", this.boundOnSeeking), this.mediaElement.addEventListener("seeked", this.boundOnSeeked), this.mediaElement.addEventListener("play", this.boundOnPlay), this.mediaElement.addEventListener("playing", this.boundOnPlaying), this.mediaElement.addEventListener("pause", this.boundOnPause), this.mediaElement.addEventListener("progress", this.boundOnProgress), this.mediaElement.volume = this.isMutedValue ? 0 : this.currentVolume, this.mediaElement.playbackRate = this.currentPlaybackRate, this.webAudioActive)
10115
- try {
10116
- const e = this.getOrCreateAudioContext();
10117
- this.sourceNode = new MediaElementAudioSourceNode(e, { mediaElement: this.mediaElement }), this.gainNode || (this.gainNode = e.createGain(), this.gainNode.connect(e.destination)), this.worklet?.workletNode ? this.sourceNode.connect(this.worklet.workletNode) : this.sourceNode.connect(this.gainNode);
10118
- } catch {
10119
- this.deactivateWebAudio();
10120
- }
10121
- this.mediaElement.readyState >= 1 && this.onLoadedMetadata(new Event("loadedmetadata")), this.mediaElement.seekable.length > 0 && this.onProgress(), this.mediaElement.readyState >= 4 ? this.onCanPlayThrough() : (this.isLoadingValue = !0, this.isLoadedValue = !1);
10122
- }
10123
10168
  // Ensure AudioContext is running
10124
10169
  async ensureAudioContextRunning() {
10125
10170
  this.audioContext || (this.audioContext = new AudioContext()), this.audioContext.state === "suspended" && await this.audioContext.resume();
@@ -10186,7 +10231,7 @@ class Es {
10186
10231
  async play() {
10187
10232
  if (!this.isPlayingValue)
10188
10233
  try {
10189
- await this.mediaElement.play(), this.isPlayingValue = !0, this.isPausedValue = !1, this.isStoppedValue = !1;
10234
+ this.audioContext && await this.ensureAudioContextRunning(), await this.mediaElement.play(), this.isPlayingValue = !0, this.isPausedValue = !1, this.isStoppedValue = !1;
10190
10235
  } catch (t) {
10191
10236
  if (t?.name === "AbortError") return;
10192
10237
  console.error("error trying to play media element", t), this.emit("error", t);
@@ -10209,15 +10254,8 @@ class Es {
10209
10254
  * @volume The volume to set, in the range [0, 1].
10210
10255
  */
10211
10256
  setVolume(t) {
10212
- if (t < 0) {
10213
- this.currentVolume = 0, this.mediaElement.volume = 0, this.gainNode && (this.gainNode.gain.value = 0), this.isMutedValue = !0;
10214
- return;
10215
- }
10216
- if (t > 1) {
10217
- this.setVolume(t / 100);
10218
- return;
10219
- }
10220
- this.currentVolume = t, this.mediaElement.volume = t, this.gainNode && (this.gainNode.gain.value = t);
10257
+ const e = Math.max(0, Math.min(1, t));
10258
+ this.gainNode ? (this.mediaElement.volume = 1, this.gainNode.gain.value = e) : this.mediaElement.volume = e, this.isMutedValue = e === 0;
10221
10259
  }
10222
10260
  /**
10223
10261
  * Skips [seconds] either forward or backward if [seconds] is negative.
@@ -10286,19 +10324,18 @@ class Es {
10286
10324
  * Sets the playback rate of the audio resource with pitch preservation.
10287
10325
  */
10288
10326
  setPlaybackRate(t, e) {
10289
- this.currentPlaybackRate = t, this.mediaElement.playbackRate = t, e ? "preservesPitch" in this.mediaElement ? this.mediaElement.preservesPitch = !0 : this.activateWebAudio().then(() => {
10290
- this.worklet ? this.worklet.updatePitchFactor(1 / t) : (this.sourceNode && (this.sourceNode.disconnect(), this.sourceNode = null), Be.createWorklet({
10327
+ this.mediaElement.playbackRate = t, e ? "preservesPitch" in this.mediaElement ? this.mediaElement.preservesPitch = !0 : this.activateWebAudio().then(() => {
10328
+ this.worklet ? this.worklet.updatePitchFactor(1 / t) : Be.createWorklet({
10291
10329
  ctx: this.getOrCreateAudioContext(),
10292
- mediaElement: this.mediaElement,
10293
10330
  pitchFactor: 1
10294
10331
  }).then((i) => {
10295
- this.worklet = i, this.worklet.workletNode.connect(this.gainNode), this.worklet.updatePitchFactor(1 / t);
10332
+ this.sourceNode && this.sourceNode.disconnect(), this.worklet = i, this.sourceNode?.connect(this.worklet.workletNode), this.worklet.workletNode.connect(this.gainNode), this.worklet.updatePitchFactor(1 / t);
10296
10333
  }).catch((i) => {
10297
10334
  console.warn("Failed to create preserve pitch worklet", i);
10298
- }));
10335
+ });
10299
10336
  }).catch((i) => {
10300
10337
  console.warn("Web Audio unavailable, playing without pitch correction:", i);
10301
- }) : this.worklet && (this.worklet.destroy(), this.worklet = null, this.webAudioActive && (this.sourceNode = new MediaElementAudioSourceNode(this.getOrCreateAudioContext(), { mediaElement: this.mediaElement }), this.sourceNode.connect(this.gainNode)));
10338
+ }) : ("preservesPitch" in this.mediaElement && (this.mediaElement.preservesPitch = !1), this.worklet && (this.worklet.destroy(), this.worklet = null, this.webAudioActive && this.sourceNode && (this.sourceNode.disconnect(), this.sourceNode.connect(this.gainNode))));
10302
10339
  }
10303
10340
  /**
10304
10341
  * Activates the Web Audio graph for the current media element.
@@ -10310,20 +10347,61 @@ class Es {
10310
10347
  const t = this.mediaElement.src;
10311
10348
  if (!t) return;
10312
10349
  const e = this.mediaElement.currentTime, i = this.isPlayingValue;
10313
- i && (this.mediaElement.pause(), this.isPlayingValue = !1), this.mediaElement.crossOrigin = "anonymous", this.mediaElement.src = t, this.mediaElement.load(), await new Promise((r, o) => {
10314
- const a = () => {
10315
- this.mediaElement.removeEventListener("canplaythrough", a), this.mediaElement.removeEventListener("error", l), r();
10316
- }, l = () => {
10317
- this.mediaElement.removeEventListener("canplaythrough", a), this.mediaElement.removeEventListener("error", l), o(new Error("Audio reload with CORS failed — server may not send Access-Control-Allow-Origin"));
10318
- };
10319
- this.mediaElement.addEventListener("canplaythrough", a), this.mediaElement.addEventListener("error", l);
10320
- }), this.mediaElement.currentTime = e, this.sourceNode = new MediaElementAudioSourceNode(this.getOrCreateAudioContext(), { mediaElement: this.mediaElement });
10350
+ i && (this.mediaElement.pause(), this.isPlayingValue = !1), this.mediaElement.crossOrigin = "anonymous", this.mediaElement.src = t, this.mediaElement.load();
10351
+ try {
10352
+ await new Promise((r, o) => {
10353
+ const a = () => {
10354
+ this.mediaElement.removeEventListener("canplaythrough", a), this.mediaElement.removeEventListener("error", l), r();
10355
+ }, l = () => {
10356
+ this.mediaElement.removeEventListener("canplaythrough", a), this.mediaElement.removeEventListener("error", l), o(new Error("Audio reload with CORS failed — server may not send Access-Control-Allow-Origin"));
10357
+ };
10358
+ this.mediaElement.addEventListener("canplaythrough", a), this.mediaElement.addEventListener("error", l);
10359
+ });
10360
+ } catch (r) {
10361
+ throw this.mediaElement.removeAttribute("crossorigin"), this.mediaElement.src = t, this.mediaElement.load(), i ? (await new Promise((o) => {
10362
+ const a = () => {
10363
+ this.mediaElement.removeEventListener("canplaythrough", a), o();
10364
+ };
10365
+ this.mediaElement.addEventListener("canplaythrough", a);
10366
+ }), this.mediaElement.currentTime = e, await this.mediaElement.play(), this.isPlayingValue = !0, this.isPausedValue = !1) : this.mediaElement.currentTime = e, r;
10367
+ }
10368
+ this.mediaElement.currentTime = e, this.sourceNode = new MediaElementAudioSourceNode(this.getOrCreateAudioContext(), { mediaElement: this.mediaElement });
10321
10369
  const n = this.getOrCreateAudioContext();
10322
- this.gainNode = n.createGain(), this.sourceNode.connect(this.gainNode), this.gainNode.connect(n.destination), this.webAudioActive = !0, i && (await this.ensureAudioContextRunning(), await this.mediaElement.play(), this.isPlayingValue = !0, this.isPausedValue = !1);
10370
+ this.gainNode = n.createGain(), this.gainNode.gain.value = this.mediaElement.volume, this.mediaElement.volume = 1, this.sourceNode.connect(this.gainNode), this.gainNode.connect(n.destination), this.webAudioActive = !0, i && (await this.ensureAudioContextRunning(), await this.mediaElement.play(), this.isPlayingValue = !0, this.isPausedValue = !1);
10323
10371
  }
10324
10372
  get isWebAudioActive() {
10325
10373
  return this.webAudioActive;
10326
10374
  }
10375
+ /**
10376
+ * Tears down the Web Audio graph and restores the media element to standalone
10377
+ * playback. Safe to call even if Web Audio was never activated.
10378
+ */
10379
+ tearDownWebAudio() {
10380
+ this.worklet && (this.worklet.destroy(), this.worklet = null), this.sourceNode && (this.sourceNode.disconnect(), this.sourceNode = null), this.gainNode && (this.mediaElement.volume = this.gainNode.gain.value, this.gainNode.disconnect(), this.gainNode = null), this.webAudioActive = !1;
10381
+ }
10382
+ /**
10383
+ * Changes the src of the primary media element without swapping the element.
10384
+ * Preserves the RemotePlayback session and all attached event listeners.
10385
+ * When the Web Audio graph is active, the new src is loaded with
10386
+ * crossOrigin="anonymous". If the CORS request fails (server does not send
10387
+ * the required headers), the graph is torn down and the src is reloaded
10388
+ * without CORS so playback continues — just without pitch correction.
10389
+ */
10390
+ changeSrc(t) {
10391
+ if (this.mediaElement.src !== t)
10392
+ if (this.mediaElement.pause(), this.isPlayingValue = !1, this.isPausedValue = !1, this.isLoadedValue = !1, this.isLoadingValue = !0, this.isEndedValue = !1, this.webAudioActive) {
10393
+ this.mediaElement.crossOrigin = "anonymous", this.mediaElement.src = t, this.mediaElement.load();
10394
+ const e = () => {
10395
+ n();
10396
+ }, i = () => {
10397
+ n(), console.warn("CORS reload failed for new track — disabling Web Audio graph:", t), this.tearDownWebAudio(), this.mediaElement.removeAttribute("crossorigin"), this.mediaElement.src = t, this.mediaElement.load();
10398
+ }, n = () => {
10399
+ this.mediaElement.removeEventListener("canplaythrough", e), this.mediaElement.removeEventListener("error", i);
10400
+ };
10401
+ this.mediaElement.addEventListener("canplaythrough", e), this.mediaElement.addEventListener("error", i);
10402
+ } else
10403
+ this.mediaElement.src = t, this.mediaElement.load();
10404
+ }
10327
10405
  /**
10328
10406
  * Returns the HTML media element used for playback.
10329
10407
  */
@@ -10347,12 +10425,12 @@ class Cs {
10347
10425
  this.volume = M(t.volume, Qt.range) ?? 1, this.playbackRate = M(t.playbackRate, te.range) ?? 1, this.preservePitch = P(t.preservePitch) ?? !0, this.skipBackwardInterval = M(t.skipBackwardInterval, et.range) ?? 10, this.skipForwardInterval = M(t.skipForwardInterval, et.range) ?? 10, this.pollInterval = w(t.pollInterval) ?? 1e3, this.autoPlay = P(t.autoPlay) ?? !0, this.enableMediaSession = P(t.enableMediaSession) ?? !0;
10348
10426
  }
10349
10427
  }
10350
- class Ni {
10428
+ class Fi {
10351
10429
  constructor(t, e) {
10352
10430
  this.volume = t.volume ?? e.volume, this.playbackRate = t.playbackRate ?? e.playbackRate, this.preservePitch = t.preservePitch ?? e.preservePitch, this.skipBackwardInterval = t.skipBackwardInterval ?? e.skipBackwardInterval, this.skipForwardInterval = t.skipForwardInterval ?? e.skipForwardInterval, this.pollInterval = t.pollInterval ?? e.pollInterval, this.autoPlay = t.autoPlay ?? e.autoPlay, this.enableMediaSession = t.enableMediaSession ?? e.enableMediaSession;
10353
10431
  }
10354
10432
  }
10355
- class Fi {
10433
+ class Ni {
10356
10434
  constructor(t, e) {
10357
10435
  this.preferences = t, this.settings = e;
10358
10436
  }
@@ -10363,24 +10441,24 @@ class Fi {
10363
10441
  this.preferences[t] = e;
10364
10442
  }
10365
10443
  get volume() {
10366
- return new R({
10444
+ return new x({
10367
10445
  initialValue: this.preferences.volume,
10368
10446
  effectiveValue: this.settings.volume,
10369
10447
  isEffective: this.preferences.volume !== null,
10370
10448
  onChange: (t) => {
10371
- this.updatePreference("volume", t ?? 1);
10449
+ this.updatePreference("volume", t ?? null);
10372
10450
  },
10373
10451
  supportedRange: Qt.range,
10374
10452
  step: Qt.step
10375
10453
  });
10376
10454
  }
10377
10455
  get playbackRate() {
10378
- return new R({
10456
+ return new x({
10379
10457
  initialValue: this.preferences.playbackRate,
10380
10458
  effectiveValue: this.settings.playbackRate,
10381
10459
  isEffective: this.preferences.playbackRate !== null,
10382
10460
  onChange: (t) => {
10383
- this.updatePreference("playbackRate", t ?? 1);
10461
+ this.updatePreference("playbackRate", t ?? null);
10384
10462
  },
10385
10463
  supportedRange: te.range,
10386
10464
  step: te.step
@@ -10392,29 +10470,29 @@ class Fi {
10392
10470
  effectiveValue: this.settings.preservePitch,
10393
10471
  isEffective: this.preferences.preservePitch !== null,
10394
10472
  onChange: (t) => {
10395
- this.updatePreference("preservePitch", t ?? !0);
10473
+ this.updatePreference("preservePitch", t ?? null);
10396
10474
  }
10397
10475
  });
10398
10476
  }
10399
10477
  get skipBackwardInterval() {
10400
- return new R({
10478
+ return new x({
10401
10479
  initialValue: this.preferences.skipBackwardInterval,
10402
10480
  effectiveValue: this.settings.skipBackwardInterval,
10403
10481
  isEffective: this.preferences.skipBackwardInterval !== null,
10404
10482
  onChange: (t) => {
10405
- this.updatePreference("skipBackwardInterval", t ?? 10);
10483
+ this.updatePreference("skipBackwardInterval", t ?? null);
10406
10484
  },
10407
10485
  supportedRange: et.range,
10408
10486
  step: et.step
10409
10487
  });
10410
10488
  }
10411
10489
  get skipForwardInterval() {
10412
- return new R({
10490
+ return new x({
10413
10491
  initialValue: this.preferences.skipForwardInterval,
10414
10492
  effectiveValue: this.settings.skipForwardInterval,
10415
10493
  isEffective: this.preferences.skipForwardInterval !== null,
10416
10494
  onChange: (t) => {
10417
- this.updatePreference("skipForwardInterval", t ?? 10);
10495
+ this.updatePreference("skipForwardInterval", t ?? null);
10418
10496
  },
10419
10497
  supportedRange: et.range,
10420
10498
  step: et.step
@@ -10426,7 +10504,7 @@ class Fi {
10426
10504
  effectiveValue: this.settings.pollInterval,
10427
10505
  isEffective: this.preferences.pollInterval !== null,
10428
10506
  onChange: (t) => {
10429
- this.updatePreference("pollInterval", t ?? 1e3);
10507
+ this.updatePreference("pollInterval", t ?? null);
10430
10508
  }
10431
10509
  });
10432
10510
  }
@@ -10436,7 +10514,7 @@ class Fi {
10436
10514
  effectiveValue: this.settings.autoPlay,
10437
10515
  isEffective: this.preferences.autoPlay !== null,
10438
10516
  onChange: (t) => {
10439
- this.updatePreference("autoPlay", t ?? !0);
10517
+ this.updatePreference("autoPlay", t ?? null);
10440
10518
  }
10441
10519
  });
10442
10520
  }
@@ -10446,15 +10524,15 @@ class Fi {
10446
10524
  effectiveValue: this.settings.enableMediaSession,
10447
10525
  isEffective: this.preferences.enableMediaSession !== null,
10448
10526
  onChange: (t) => {
10449
- this.updatePreference("enableMediaSession", t ?? !0);
10527
+ this.updatePreference("enableMediaSession", t ?? null);
10450
10528
  }
10451
10529
  });
10452
10530
  }
10453
10531
  }
10454
- const Ui = 1, Ii = 1;
10455
- class xs {
10456
- constructor(t, e) {
10457
- this.pool = /* @__PURE__ */ new Map(), this._audioEngine = t, this._publication = e, this._supportedAudioTypes = this.detectSupportedAudioTypes();
10532
+ const Ii = 1, Ui = 1;
10533
+ class Rs {
10534
+ constructor(t, e, i = {}) {
10535
+ this.pool = /* @__PURE__ */ new Map(), this._audioEngine = t, this._publication = e, this._supportedAudioTypes = this.detectSupportedAudioTypes(), i.disableRemotePlayback && (this._audioEngine.getMediaElement().disableRemotePlayback = !0);
10458
10536
  }
10459
10537
  detectSupportedAudioTypes() {
10460
10538
  const t = document.createElement("audio"), e = /* @__PURE__ */ new Set();
@@ -10471,17 +10549,17 @@ class xs {
10471
10549
  return i;
10472
10550
  }
10473
10551
  pickPlayableHref(t) {
10474
- const e = [t, ...t.alternates?.items ?? []];
10475
- let i;
10476
- for (const n of e) {
10477
- if (!n.type) continue;
10478
- const r = this._supportedAudioTypes.get(n.type);
10479
- if (r) {
10480
- if (r === "probably") return n.href;
10481
- i || (i = { href: n.href, confidence: r });
10482
- }
10552
+ const e = this._publication.baseURL, i = [t, ...t.alternates?.items ?? []];
10553
+ let n;
10554
+ for (const r of i) {
10555
+ if (!r.type) continue;
10556
+ const o = this._supportedAudioTypes.get(r.type);
10557
+ if (!o) continue;
10558
+ const a = r.toURL(e) ?? r.href;
10559
+ if (o === "probably") return a;
10560
+ n || (n = { href: a, confidence: o });
10483
10561
  }
10484
- return i?.href ?? t.href;
10562
+ return n?.href ?? t.toURL(e) ?? t.href;
10485
10563
  }
10486
10564
  get audioEngine() {
10487
10565
  return this._audioEngine;
@@ -10497,23 +10575,30 @@ class xs {
10497
10575
  /**
10498
10576
  * Updates the pool around the given index: ensures elements exist within
10499
10577
  * the LOWER_BOUNDARY and disposes those beyond the UPPER_BOUNDARY.
10578
+ * The current track is excluded — the primary engine element represents it.
10500
10579
  */
10501
10580
  update(t) {
10502
10581
  const e = this._publication.readingOrder.items, i = /* @__PURE__ */ new Set();
10503
10582
  for (let n = 0; n < e.length; n++) {
10583
+ if (n === t) continue;
10504
10584
  const r = this.pickPlayableHref(e[n]);
10505
- n >= t - Ii && n <= t + Ii ? (this.ensure(r), i.add(r)) : n >= t - Ui && n <= t + Ui && this.pool.has(r) && i.add(r);
10585
+ n >= t - Ui && n <= t + Ui ? (this.ensure(r), i.add(r)) : n >= t - Ii && n <= t + Ii && this.pool.has(r) && i.add(r);
10506
10586
  }
10507
10587
  for (const [n, r] of this.pool)
10508
10588
  i.has(n) || (r.removeAttribute("src"), r.load(), this.pool.delete(n));
10509
10589
  }
10510
10590
  /**
10511
- * Sets the current audio for playback at the given track index.
10512
- * The element is always sourced from the pool never loaded ad-hoc on the engine.
10591
+ * Sets the current audio for playback at the given track index by changing
10592
+ * the src on the persistent primary element. This preserves the RemotePlayback
10593
+ * session and any Web Audio graph connections across track changes.
10513
10594
  */
10514
10595
  setCurrentAudio(t, e) {
10515
- const i = this.pickPlayableHref(this._publication.readingOrder.items[t]), n = this.ensure(i);
10516
- this.audioEngine.setMediaElement(n), this.pool.delete(i), this.update(t);
10596
+ const i = this.pickPlayableHref(this._publication.readingOrder.items[t]);
10597
+ if (this.audioEngine.changeSrc(i), this.pool.has(i)) {
10598
+ const n = this.pool.get(i);
10599
+ n.removeAttribute("src"), n.load(), this.pool.delete(i);
10600
+ }
10601
+ this.update(t);
10517
10602
  }
10518
10603
  destroy() {
10519
10604
  this.audioEngine.stop();
@@ -10522,33 +10607,35 @@ class xs {
10522
10607
  this.pool.clear();
10523
10608
  }
10524
10609
  }
10525
- class Rs {
10610
+ class xs {
10526
10611
  constructor(t = {}) {
10527
10612
  this.dragstartHandler = (e) => {
10528
10613
  e.preventDefault(), e.stopPropagation(), t.onDragDetected?.(Array.from(e.dataTransfer?.types ?? []));
10614
+ }, this.dragoverHandler = (e) => {
10615
+ e.preventDefault(), e.stopPropagation();
10529
10616
  }, this.dropHandler = (e) => {
10530
10617
  e.preventDefault(), e.stopPropagation();
10531
10618
  const i = Array.from(e.dataTransfer?.types ?? []), n = e.dataTransfer?.files.length ?? 0;
10532
10619
  t.onDropDetected?.(i, n);
10533
- }, document.addEventListener("dragstart", this.dragstartHandler, !0), document.addEventListener("drop", this.dropHandler, !0), window.addEventListener("unload", () => this.destroy());
10620
+ }, this.unloadHandler = () => this.destroy(), document.addEventListener("dragstart", this.dragstartHandler, !0), document.addEventListener("dragover", this.dragoverHandler, !0), document.addEventListener("drop", this.dropHandler, !0), window.addEventListener("unload", this.unloadHandler);
10534
10621
  }
10535
10622
  destroy() {
10536
- document.removeEventListener("dragstart", this.dragstartHandler, !0), document.removeEventListener("drop", this.dropHandler, !0);
10623
+ document.removeEventListener("dragstart", this.dragstartHandler, !0), document.removeEventListener("dragover", this.dragoverHandler, !0), document.removeEventListener("drop", this.dropHandler, !0), window.removeEventListener("unload", this.unloadHandler);
10537
10624
  }
10538
10625
  }
10539
10626
  class Ls {
10540
10627
  constructor(t = {}) {
10541
10628
  this.copyHandler = (e) => {
10542
10629
  e.preventDefault(), e.stopPropagation(), t.onCopyBlocked?.();
10543
- }, document.addEventListener("copy", this.copyHandler, !0), window.addEventListener("unload", () => this.destroy());
10630
+ }, this.unloadHandler = () => this.destroy(), document.addEventListener("copy", this.copyHandler, !0), window.addEventListener("unload", this.unloadHandler);
10544
10631
  }
10545
10632
  destroy() {
10546
- document.removeEventListener("copy", this.copyHandler, !0);
10633
+ document.removeEventListener("copy", this.copyHandler, !0), window.removeEventListener("unload", this.unloadHandler);
10547
10634
  }
10548
10635
  }
10549
10636
  class ks extends We {
10550
10637
  constructor(t = {}) {
10551
- super(t), t.disableDragAndDrop && (this.dragAndDropProtector = new Rs({
10638
+ super(t), t.disableDragAndDrop && (this.dragAndDropProtector = new xs({
10552
10639
  onDragDetected: (e) => {
10553
10640
  this.dispatchSuspiciousActivity("drag_detected", { dataTransferTypes: e, targetFrameSrc: "" });
10554
10641
  },
@@ -10593,6 +10680,8 @@ const Os = (s) => ({
10593
10680
  peripheral: s.peripheral ?? (() => {
10594
10681
  }),
10595
10682
  contextMenu: s.contextMenu ?? (() => {
10683
+ }),
10684
+ remotePlaybackStateChanged: s.remotePlaybackStateChanged ?? (() => {
10596
10685
  })
10597
10686
  });
10598
10687
  class As extends dr {
@@ -10600,23 +10689,28 @@ class As extends dr {
10600
10689
  preferences: {},
10601
10690
  defaults: {}
10602
10691
  }) {
10603
- if (super(), this.positionPollInterval = null, this.navigationId = 0, this._playIntent = !1, this._preferencesEditor = null, this._mediaSessionEnabled = !1, this._navigatorProtector = null, this._keyboardPeripheralsManager = null, this._suspiciousActivityListener = null, this._keyboardPeripheralListener = null, this.pub = t, this.listeners = Os(e), this._preferences = new oe(n.preferences), this._defaults = new Cs(n.defaults), this._settings = new Ni(this._preferences, this._defaults), i)
10692
+ if (super(), this.positionPollInterval = null, this.navigationId = 0, this._playIntent = !1, this._preferencesEditor = null, this._mediaSessionEnabled = !1, this._navigatorProtector = null, this._keyboardPeripheralsManager = null, this._suspiciousActivityListener = null, this._keyboardPeripheralListener = null, this._isNavigating = !1, this._isStalled = !1, this._stalledWatchdog = null, this._stalledCheckTime = 0, this.pub = t, this.listeners = Os(e), this._preferences = new oe(n.preferences), this._defaults = new Cs(n.defaults), this._settings = new Fi(this._preferences, this._defaults), t.readingOrder.items.length === 0)
10693
+ throw new Error("AudioNavigator: publication has an empty reading order");
10694
+ if (i)
10604
10695
  this.currentLocation = this.ensureLocatorLocations(i);
10605
10696
  else {
10606
10697
  const u = this.pub.readingOrder.items[0];
10607
- this.currentLocation = new N({
10698
+ this.currentLocation = new F({
10608
10699
  href: u.href,
10609
10700
  type: u.type || "audio/mpeg",
10610
10701
  title: u.title,
10611
10702
  locations: new E({
10612
- position: 0,
10703
+ position: 1,
10613
10704
  progression: 0,
10614
10705
  totalProgression: 0,
10615
10706
  fragments: ["t=0"]
10616
10707
  })
10617
10708
  });
10618
10709
  }
10619
- const r = this.currentLocation.href.split("#")[0], o = this.hrefToTrackIndex(r), a = this.currentLocation.locations?.time() || 0, l = new Es({
10710
+ const r = this.currentLocation.href.split("#")[0], o = this.hrefToTrackIndex(r);
10711
+ if (o === -1)
10712
+ throw new Error(`AudioNavigator: initial href "${r}" not found in reading order`);
10713
+ const a = this.currentLocation.locations?.time() || 0, l = new Es({
10620
10714
  playback: {
10621
10715
  state: {
10622
10716
  currentTime: a,
@@ -10626,8 +10720,10 @@ class As extends dr {
10626
10720
  index: o
10627
10721
  }
10628
10722
  });
10629
- this.pool = new xs(l, t);
10630
- const h = n.contentProtection || {}, c = this.mergeKeyboardPeripherals(
10723
+ this.pool = new Rs(l, t, n.contentProtection);
10724
+ const h = n.contentProtection || {};
10725
+ this._contentProtection = h;
10726
+ const c = this.mergeKeyboardPeripherals(
10631
10727
  h,
10632
10728
  n.keyboardPeripherals || []
10633
10729
  );
@@ -10636,22 +10732,23 @@ class As extends dr {
10636
10732
  m === "context_menu" ? this.listeners.contextMenu(y) : this.listeners.contentProtection(m, y);
10637
10733
  }, window.addEventListener(st, this._suspiciousActivityListener)), c.length > 0 && (this._keyboardPeripheralsManager = new He({ keyboardPeripherals: c }), this._keyboardPeripheralListener = (u) => {
10638
10734
  this.listeners.peripheral(u.detail);
10639
- }, window.addEventListener(ot, this._keyboardPeripheralListener)), this.setupEventListeners(), this.applyPreferences(), this.pool.setCurrentAudio(o, "forward"), this.waitForLoadedAndSeeked(a).then(() => {
10640
- this.listeners.trackLoaded(this.pool.audioEngine.getMediaElement()), this._notifyTimelineChange(this.currentLocator), this.listeners.positionChanged(this.currentLocator);
10735
+ }, window.addEventListener(ot, this._keyboardPeripheralListener)), this.setupEventListeners(), this._isNavigating = !0, this.pool.setCurrentAudio(o, "forward"), this.applyPreferences(), this.waitForLoadedAndSeeked(a).then(() => {
10736
+ this._isNavigating = !1, this.listeners.trackLoaded(this.pool.audioEngine.getMediaElement()), this._notifyTimelineChange(this.currentLocator), this.listeners.positionChanged(this.currentLocator), this._setupRemotePlayback();
10641
10737
  }).catch(() => {
10738
+ this._isNavigating = !1;
10642
10739
  });
10643
10740
  }
10644
10741
  get settings() {
10645
10742
  return this._settings;
10646
10743
  }
10647
10744
  get preferencesEditor() {
10648
- return this._preferencesEditor === null && (this._preferencesEditor = new Fi(this._preferences, this.settings)), this._preferencesEditor;
10745
+ return this._preferencesEditor === null && (this._preferencesEditor = new Ni(this._preferences, this.settings)), this._preferencesEditor;
10649
10746
  }
10650
10747
  async submitPreferences(t) {
10651
10748
  this._preferences = this._preferences.merging(t), this.applyPreferences();
10652
10749
  }
10653
10750
  applyPreferences() {
10654
- this._settings = new Ni(this._preferences, this._defaults), this._preferencesEditor !== null && (this._preferencesEditor = new Fi(this._preferences, this.settings)), this.pool.audioEngine.setVolume(this._settings.volume), this.pool.audioEngine.setPlaybackRate(this._settings.playbackRate, this._settings.preservePitch), this._settings.enableMediaSession && !this._mediaSessionEnabled ? (this._mediaSessionEnabled = !0, this.setupMediaSession()) : !this._settings.enableMediaSession && this._mediaSessionEnabled && (this._mediaSessionEnabled = !1, this.destroyMediaSession());
10751
+ this._settings = new Fi(this._preferences, this._defaults), this._preferencesEditor !== null && (this._preferencesEditor = new Ni(this._preferences, this.settings)), this.pool.audioEngine.setVolume(this._settings.volume), this.pool.audioEngine.setPlaybackRate(this._settings.playbackRate, this._settings.preservePitch), this.positionPollInterval !== null && this.startPositionPolling(), this._settings.enableMediaSession && !this._mediaSessionEnabled ? (this._mediaSessionEnabled = !0, this.setupMediaSession()) : !this._settings.enableMediaSession && this._mediaSessionEnabled && (this._mediaSessionEnabled = !1, this.destroyMediaSession());
10655
10752
  }
10656
10753
  get publication() {
10657
10754
  return this.pub;
@@ -10661,10 +10758,10 @@ class As extends dr {
10661
10758
  }
10662
10759
  _notifyTimelineChange(t) {
10663
10760
  const e = this.pub.timeline.locate(t);
10664
- e !== this._currentTimelineItem && (this._currentTimelineItem = e, this.listeners.timelineItemChanged(e));
10761
+ e !== this._currentTimelineItem && (this._currentTimelineItem = e, this.listeners.timelineItemChanged(e), this._settings.enableMediaSession && this.updateMediaSessionMetadata());
10665
10762
  }
10666
10763
  ensureLocatorLocations(t) {
10667
- return new N({
10764
+ return new F({
10668
10765
  ...t,
10669
10766
  locations: t.locations instanceof E ? t.locations : t.locations ? new E(t.locations) : void 0
10670
10767
  });
@@ -10697,13 +10794,13 @@ class As extends dr {
10697
10794
  const i = this.pub.readingOrder.items[t];
10698
10795
  if (!i) throw new Error(`Invalid track index: ${t}`);
10699
10796
  const n = this.pool.audioEngine.duration();
10700
- return new N({
10797
+ return new F({
10701
10798
  href: i.href,
10702
10799
  type: i.type || "audio/mpeg",
10703
10800
  title: i.title,
10704
10801
  locations: new E({
10705
10802
  progression: n > 0 ? e / n : 0,
10706
- position: t,
10803
+ position: t + 1,
10707
10804
  fragments: [`t=${e}`]
10708
10805
  })
10709
10806
  });
@@ -10746,29 +10843,61 @@ class As extends dr {
10746
10843
  this.listeners.error(t, this.currentLocator);
10747
10844
  }), this.pool.audioEngine.on("ended", async () => {
10748
10845
  this.stopPositionPolling(), this.currentLocation = this.currentLocation.copyWithLocations(new E({
10749
- position: this.currentTrackIndex(),
10846
+ position: this.currentTrackIndex() + 1,
10750
10847
  progression: 1,
10751
10848
  fragments: [`t=${this.duration}`]
10752
10849
  })), this.listeners.trackEnded(this.currentLocator), this.canGoForward && (await this.nextTrack(), this._settings.autoPlay && this.play());
10753
10850
  }), this.pool.audioEngine.on("play", () => {
10754
- this.startPositionPolling(), this.listeners.play(this.currentLocator);
10851
+ this._isNavigating || (this.startPositionPolling(), this.listeners.play(this.currentLocator));
10755
10852
  }), this.pool.audioEngine.on("playing", () => {
10756
- this.listeners.stalled(!1);
10853
+ this._isNavigating || this._setStalled(!1);
10757
10854
  }), this.pool.audioEngine.on("pause", () => {
10758
- this.stopPositionPolling(), this.listeners.pause(this.currentLocator);
10855
+ this._isNavigating || (this.stopPositionPolling(), this.listeners.pause(this.currentLocator));
10759
10856
  }), this.pool.audioEngine.on("seeked", () => {
10760
- if (this.listeners.seeking(!1), !this.isPlaying) {
10761
- const t = this.currentTime, e = this.duration, i = e > 0 ? t / e : 0;
10762
- this.currentLocation = this.currentLocation.copyWithLocations(new E({
10763
- position: this.currentTrackIndex(),
10764
- progression: i,
10765
- fragments: [`t=${t}`]
10766
- })), this._notifyTimelineChange(this.currentLocation), this.listeners.positionChanged(this.currentLocation);
10767
- }
10768
- }), this.pool.audioEngine.on("seeking", () => this.listeners.seeking(!0)), this.pool.audioEngine.on("waiting", () => this.listeners.seeking(!0)), this.pool.audioEngine.on("stalled", () => this.listeners.stalled(!0)), this.pool.audioEngine.on("canplaythrough", () => this.listeners.stalled(!1)), this.pool.audioEngine.on("progress", (t) => this.listeners.seekable(t)), this.pool.audioEngine.on("loadedmetadata", () => {
10769
- this.listeners.metadataLoaded(this.pool.audioEngine.duration());
10857
+ if (this._isNavigating) return;
10858
+ this.listeners.seeking(!1);
10859
+ const t = this.currentTime, e = this.duration, i = e > 0 ? t / e : 0;
10860
+ this.currentLocation = this.currentLocation.copyWithLocations(new E({
10861
+ position: this.currentTrackIndex() + 1,
10862
+ progression: i,
10863
+ fragments: [`t=${t}`]
10864
+ })), this._notifyTimelineChange(this.currentLocation), this.listeners.positionChanged(this.currentLocation);
10865
+ }), this.pool.audioEngine.on("seeking", () => {
10866
+ this._isNavigating || this.listeners.seeking(!0);
10867
+ }), this.pool.audioEngine.on("waiting", () => {
10868
+ this._isNavigating || this.listeners.seeking(!0);
10869
+ }), this.pool.audioEngine.on("stalled", () => {
10870
+ this._isNavigating || this._setStalled(!0);
10871
+ }), this.pool.audioEngine.on("canplaythrough", () => {
10872
+ this._isNavigating || this._setStalled(!1);
10873
+ }), this.pool.audioEngine.on("progress", (t) => {
10874
+ this._isNavigating || this.listeners.seekable(t);
10875
+ }), this.pool.audioEngine.on("loadedmetadata", () => {
10876
+ const t = this.pool.audioEngine.getMediaElement(), e = {
10877
+ duration: this.pool.audioEngine.duration(),
10878
+ textTracks: t.textTracks,
10879
+ readyState: t.readyState,
10880
+ networkState: t.networkState
10881
+ };
10882
+ this.listeners.metadataLoaded(e);
10770
10883
  });
10771
10884
  }
10885
+ _setStalled(t) {
10886
+ this._isStalled !== t && (this._isStalled = t, this.listeners.stalled(t), t ? (this._stalledCheckTime = this.currentTime, this._startStalledWatchdog()) : this._stopStalledWatchdog());
10887
+ }
10888
+ _startStalledWatchdog() {
10889
+ this._stalledWatchdog = setInterval(() => {
10890
+ if (!this.isPlaying) {
10891
+ this._setStalled(!1);
10892
+ return;
10893
+ }
10894
+ const t = this.currentTime;
10895
+ t !== this._stalledCheckTime && this._setStalled(!1), this._stalledCheckTime = t;
10896
+ }, 500);
10897
+ }
10898
+ _stopStalledWatchdog() {
10899
+ this._stalledWatchdog !== null && (clearInterval(this._stalledWatchdog), this._stalledWatchdog = null);
10900
+ }
10772
10901
  setupMediaSession() {
10773
10902
  "mediaSession" in navigator && (navigator.mediaSession.setActionHandler("play", () => this.play()), navigator.mediaSession.setActionHandler("pause", () => this.pause()), navigator.mediaSession.setActionHandler("previoustrack", () => this.goBackward(!1, () => {
10774
10903
  })), navigator.mediaSession.setActionHandler("nexttrack", () => this.goForward(!1, () => {
@@ -10781,14 +10910,14 @@ class As extends dr {
10781
10910
  title: e?.title || `Track ${t + 1}`,
10782
10911
  artist: this.pub.metadata.authors ? this.pub.metadata.authors.items.map((n) => n.name.getTranslation()).join(", ") : void 0,
10783
10912
  album: this.pub.metadata.title.getTranslation(),
10784
- artwork: i ? [{ src: i.href, type: i.type }] : void 0
10913
+ artwork: i ? [{ src: i.toURL(this.pub.baseURL) ?? i.href, type: i.type }] : void 0
10785
10914
  });
10786
10915
  }
10787
10916
  startPositionPolling() {
10788
10917
  this.stopPositionPolling(), this.positionPollInterval = setInterval(() => {
10789
10918
  const t = this.currentTime, e = this.duration, i = e > 0 ? t / e : 0;
10790
10919
  this.currentLocation = this.currentLocation.copyWithLocations(new E({
10791
- position: this.currentTrackIndex(),
10920
+ position: this.currentTrackIndex() + 1,
10792
10921
  progression: i,
10793
10922
  fragments: [`t=${t}`]
10794
10923
  })), this._notifyTimelineChange(this.currentLocation), this.listeners.positionChanged(this.currentLocation);
@@ -10805,14 +10934,14 @@ class As extends dr {
10805
10934
  i(!1);
10806
10935
  return;
10807
10936
  }
10808
- const a = ++this.navigationId, l = r >= this.currentTrackIndex() ? "forward" : "backward", h = this.isPlaying || this._playIntent;
10809
- if (this._playIntent = h, this.stopPositionPolling(), this.pool.setCurrentAudio(r, l), this.currentLocation = t.copyWithLocations(t.locations), await this.waitForLoadedAndSeeked(o, a), a !== this.navigationId) {
10937
+ const a = ++this.navigationId, l = this.currentTrackIndex(), h = r >= l ? "forward" : "backward", c = this.isPlaying || this._playIntent;
10938
+ if (this._playIntent = c, this._isNavigating = !0, this.stopPositionPolling(), this.pool.setCurrentAudio(r, h), this.currentLocation = t.copyWithLocations(t.locations), await this.waitForLoadedAndSeeked(o, a), this._isNavigating = !1, a !== this.navigationId) {
10810
10939
  i(!1);
10811
10940
  return;
10812
10941
  }
10813
- this.listeners.trackLoaded(this.pool.audioEngine.getMediaElement()), this._notifyTimelineChange(this.currentLocator), this.listeners.positionChanged(this.currentLocator), this._settings.enableMediaSession && this.updateMediaSessionMetadata(), h && this.play(), i(!0);
10942
+ r !== l && this.listeners.trackLoaded(this.pool.audioEngine.getMediaElement()), this._notifyTimelineChange(this.currentLocator), this.listeners.positionChanged(this.currentLocator), this._settings.enableMediaSession && this.updateMediaSessionMetadata(), c && this.play(), i(!0);
10814
10943
  } catch (n) {
10815
- console.error("Failed to go to locator:", n), i(!1);
10944
+ this._isNavigating = !1, console.error("Failed to go to locator:", n), i(!1);
10816
10945
  } finally {
10817
10946
  this._playIntent = !1;
10818
10947
  }
@@ -10890,19 +11019,36 @@ class As extends dr {
10890
11019
  get canGoForward() {
10891
11020
  return this.currentTrackIndex() < this.pub.readingOrder.items.length - 1;
10892
11021
  }
11022
+ /**
11023
+ * The RemotePlayback object for the primary media element.
11024
+ * Because the element is never swapped, this reference is stable for the
11025
+ * lifetime of the navigator — host apps can store it and call `.prompt()`,
11026
+ * `.watchAvailability()`, etc. directly.
11027
+ */
11028
+ get remotePlayback() {
11029
+ const t = this.pool.audioEngine.getMediaElement();
11030
+ return "remote" in t ? t.remote : void 0;
11031
+ }
11032
+ /** Wires up the optional remotePlaybackStateChanged listener. Called once after initial load. */
11033
+ _setupRemotePlayback() {
11034
+ if (this._contentProtection.disableRemotePlayback)
11035
+ return;
11036
+ const t = this.remotePlayback;
11037
+ t && (t.onconnecting = () => this.listeners.remotePlaybackStateChanged("connecting"), t.onconnect = () => this.listeners.remotePlaybackStateChanged("connected"), t.ondisconnect = () => this.listeners.remotePlaybackStateChanged("disconnected"));
11038
+ }
10893
11039
  destroyMediaSession() {
10894
11040
  "mediaSession" in navigator && (navigator.mediaSession.metadata = null, navigator.mediaSession.setActionHandler("play", null), navigator.mediaSession.setActionHandler("pause", null), navigator.mediaSession.setActionHandler("previoustrack", null), navigator.mediaSession.setActionHandler("nexttrack", null), navigator.mediaSession.setActionHandler("seekbackward", null), navigator.mediaSession.setActionHandler("seekforward", null));
10895
11041
  }
10896
11042
  destroy() {
10897
- this.stopPositionPolling(), this.destroyMediaSession(), this._suspiciousActivityListener && window.removeEventListener(st, this._suspiciousActivityListener), this._keyboardPeripheralListener && window.removeEventListener(ot, this._keyboardPeripheralListener), this._navigatorProtector?.destroy(), this._keyboardPeripheralsManager?.destroy(), this.pool.destroy();
11043
+ this.stopPositionPolling(), this._stopStalledWatchdog(), this.destroyMediaSession(), this._suspiciousActivityListener && window.removeEventListener(st, this._suspiciousActivityListener), this._keyboardPeripheralListener && window.removeEventListener(ot, this._keyboardPeripheralListener), this._navigatorProtector?.destroy(), this._keyboardPeripheralsManager?.destroy(), this.pool.destroy();
10898
11044
  }
10899
11045
  }
10900
11046
  export {
10901
11047
  Cs as AudioDefaults,
10902
11048
  As as AudioNavigator,
10903
11049
  oe as AudioPreferences,
10904
- Fi as AudioPreferencesEditor,
10905
- Ni as AudioSettings,
11050
+ Ni as AudioPreferencesEditor,
11051
+ Fi as AudioSettings,
10906
11052
  O as BooleanPreference,
10907
11053
  cn as EnumPreference,
10908
11054
  ls as EpubDefaults,
@@ -10924,11 +11070,11 @@ export {
10924
11070
  _t as LineLengths,
10925
11071
  dr as MediaNavigator,
10926
11072
  nn as Navigator,
10927
- Re as Orientation,
11073
+ xe as Orientation,
10928
11074
  A as Preference,
10929
11075
  re as Properties,
10930
11076
  gs as RSProperties,
10931
- R as RangePreference,
11077
+ x as RangePreference,
10932
11078
  fs as ReadiumCSS,
10933
11079
  Le as Spread,
10934
11080
  J as TextAlignment,
@@ -10951,12 +11097,12 @@ export {
10951
11097
  se as ensureEnumValue,
10952
11098
  hn as ensureExperiment,
10953
11099
  ft as ensureFilter,
10954
- xr as ensureLessThanOrEqual,
10955
- Rr as ensureMoreThanOrEqual,
11100
+ Rr as ensureLessThanOrEqual,
11101
+ xr as ensureMoreThanOrEqual,
10956
11102
  w as ensureNonNegative,
10957
- I as ensureString,
11103
+ U as ensureString,
10958
11104
  M as ensureValueInRange,
10959
- Ie as experiments,
11105
+ Ue as experiments,
10960
11106
  ht as filterRangeConfig,
10961
11107
  Gt as fontSizeRangeConfig,
10962
11108
  nt as fontWeightRangeConfig,