@openrails/contentkit-ui 0.103.2 → 0.104.0-rc.2

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 (253) hide show
  1. package/README.md +111 -49
  2. package/dist/client/beacons.d.ts +3 -13
  3. package/dist/client/beacons.js +8 -46
  4. package/dist/client/beacons.js.map +1 -1
  5. package/dist/client/client.d.ts +3 -0
  6. package/dist/client/client.js +45 -43
  7. package/dist/client/client.js.map +1 -1
  8. package/dist/client/content/favorites.d.ts +2 -0
  9. package/dist/client/content/favorites.js.map +1 -1
  10. package/dist/client/content/types.d.ts +3 -0
  11. package/dist/client/content/types.js.map +1 -1
  12. package/dist/client/contents.d.ts +7 -1
  13. package/dist/client/contents.js +8 -0
  14. package/dist/client/contents.js.map +1 -1
  15. package/dist/client/discovery.d.ts +34 -5
  16. package/dist/client/discovery.js +23 -2
  17. package/dist/client/discovery.js.map +1 -1
  18. package/dist/client/engagement.d.ts +70 -0
  19. package/dist/client/engagement.js +191 -0
  20. package/dist/client/engagement.js.map +1 -0
  21. package/dist/client/generated/routes.d.ts +74 -35
  22. package/dist/client/generated/routes.js +119 -60
  23. package/dist/client/generated/routes.js.map +1 -1
  24. package/dist/client/generated/wire.d.ts +88 -85
  25. package/dist/client/generated/wire.js.map +1 -1
  26. package/dist/client/guest-reading-history.d.ts +40 -0
  27. package/dist/client/guest-reading-history.js +144 -0
  28. package/dist/client/guest-reading-history.js.map +1 -0
  29. package/dist/client/index.d.ts +5 -3
  30. package/dist/client/media/windows.d.ts +2 -0
  31. package/dist/client/media/windows.js +4 -1
  32. package/dist/client/media/windows.js.map +1 -1
  33. package/dist/client/stats.d.ts +4 -20
  34. package/dist/client/stats.js +0 -11
  35. package/dist/client/stats.js.map +1 -1
  36. package/dist/client/versions.d.ts +8 -6
  37. package/dist/client/versions.js +15 -10
  38. package/dist/client/versions.js.map +1 -1
  39. package/dist/client.js +24 -22
  40. package/dist/components/admin/bulk-drafts.d.ts +17 -0
  41. package/dist/components/admin/bulk-drafts.js +41 -0
  42. package/dist/components/admin/bulk-drafts.js.map +1 -0
  43. package/dist/components/admin/content-admin.d.ts +1 -1
  44. package/dist/components/admin/content-admin.js.map +1 -1
  45. package/dist/components/admin/content-manager.d.ts +11 -3
  46. package/dist/components/admin/content-manager.js +751 -394
  47. package/dist/components/admin/content-manager.js.map +1 -1
  48. package/dist/components/admin/group-manager.d.ts +8 -3
  49. package/dist/components/admin/group-manager.js +218 -146
  50. package/dist/components/admin/group-manager.js.map +1 -1
  51. package/dist/components/admin/page-notices.d.ts +16 -0
  52. package/dist/components/admin/page-notices.js +113 -0
  53. package/dist/components/admin/page-notices.js.map +1 -0
  54. package/dist/components/admin/page-picker.d.ts +38 -0
  55. package/dist/components/admin/page-picker.js +159 -0
  56. package/dist/components/admin/page-picker.js.map +1 -0
  57. package/dist/components/admin/quick-search.d.ts +14 -0
  58. package/dist/components/admin/quick-search.js +60 -0
  59. package/dist/components/admin/quick-search.js.map +1 -0
  60. package/dist/components/admin/reader-content-editor.js +382 -321
  61. package/dist/components/admin/reader-content-editor.js.map +1 -1
  62. package/dist/components/admin/reader-manifest.js +181 -179
  63. package/dist/components/admin/reader-manifest.js.map +1 -1
  64. package/dist/components/admin/shell.d.ts +10 -2
  65. package/dist/components/admin/shell.js +114 -42
  66. package/dist/components/admin/shell.js.map +1 -1
  67. package/dist/components/admin/stats-dashboard.d.ts +4 -9
  68. package/dist/components/admin/stats-dashboard.js +303 -207
  69. package/dist/components/admin/stats-dashboard.js.map +1 -1
  70. package/dist/components/admin/upload-queue.d.ts +14 -0
  71. package/dist/components/admin/upload-queue.js +115 -98
  72. package/dist/components/admin/upload-queue.js.map +1 -1
  73. package/dist/components/content/card.d.ts +31 -3
  74. package/dist/components/content/card.js +324 -158
  75. package/dist/components/content/card.js.map +1 -1
  76. package/dist/components/content/daily-releases.js +144 -190
  77. package/dist/components/content/daily-releases.js.map +1 -1
  78. package/dist/components/content/editor-save.js +27 -25
  79. package/dist/components/content/editor-save.js.map +1 -1
  80. package/dist/components/content/editors.js +274 -253
  81. package/dist/components/content/editors.js.map +1 -1
  82. package/dist/components/content/favorites.d.ts +6 -0
  83. package/dist/components/content/favorites.js +47 -0
  84. package/dist/components/content/favorites.js.map +1 -0
  85. package/dist/components/content/filter-dialog.js +19 -15
  86. package/dist/components/content/filter-dialog.js.map +1 -1
  87. package/dist/components/content/filters.d.ts +2 -0
  88. package/dist/components/content/filters.js +5 -1
  89. package/dist/components/content/filters.js.map +1 -1
  90. package/dist/components/content/grid.d.ts +44 -16
  91. package/dist/components/content/grid.js +308 -270
  92. package/dist/components/content/grid.js.map +1 -1
  93. package/dist/components/content/history.d.ts +6 -0
  94. package/dist/components/content/history.js +111 -0
  95. package/dist/components/content/history.js.map +1 -0
  96. package/dist/components/content/index.d.ts +6 -3
  97. package/dist/components/content/listing.d.ts +14 -3
  98. package/dist/components/content/listing.js +65 -56
  99. package/dist/components/content/listing.js.map +1 -1
  100. package/dist/components/content/offer-fields.js +6 -6
  101. package/dist/components/content/paged-grid.d.ts +10 -0
  102. package/dist/components/content/paged-grid.js +116 -0
  103. package/dist/components/content/paged-grid.js.map +1 -0
  104. package/dist/components/content/pagination.d.ts +19 -0
  105. package/dist/components/content/pagination.js +97 -0
  106. package/dist/components/content/pagination.js.map +1 -0
  107. package/dist/components/content/paywall.d.ts +9 -0
  108. package/dist/components/content/paywall.js +27 -3
  109. package/dist/components/content/paywall.js.map +1 -1
  110. package/dist/components/content/post-list.d.ts +37 -0
  111. package/dist/components/content/post-list.js +203 -0
  112. package/dist/components/content/post-list.js.map +1 -0
  113. package/dist/components/content/reader-settings.d.ts +2 -0
  114. package/dist/components/content/reader-settings.js +1 -1
  115. package/dist/components/content/reader-settings.js.map +1 -1
  116. package/dist/components/content/search.d.ts +11 -4
  117. package/dist/components/content/search.js +22 -11
  118. package/dist/components/content/search.js.map +1 -1
  119. package/dist/components/content/summary-tile.d.ts +14 -0
  120. package/dist/components/content/summary-tile.js +63 -0
  121. package/dist/components/content/summary-tile.js.map +1 -0
  122. package/dist/components/groups/banner.d.ts +6 -2
  123. package/dist/components/groups/banner.js +79 -61
  124. package/dist/components/groups/banner.js.map +1 -1
  125. package/dist/components/groups/directory.d.ts +12 -2
  126. package/dist/components/groups/directory.js +168 -105
  127. package/dist/components/groups/directory.js.map +1 -1
  128. package/dist/components/groups/editor.js +10 -10
  129. package/dist/components/groups/editor.js.map +1 -1
  130. package/dist/components/groups/entity-chips.d.ts +61 -0
  131. package/dist/components/groups/entity-chips.js +382 -0
  132. package/dist/components/groups/entity-chips.js.map +1 -0
  133. package/dist/components/groups/group-members.d.ts +29 -0
  134. package/dist/components/groups/group-members.js +474 -0
  135. package/dist/components/groups/group-members.js.map +1 -0
  136. package/dist/components/groups/header.js +53 -45
  137. package/dist/components/groups/header.js.map +1 -1
  138. package/dist/components/groups/index.d.ts +3 -1
  139. package/dist/components/groups/memberships.d.ts +3 -36
  140. package/dist/components/groups/memberships.js +105 -480
  141. package/dist/components/groups/memberships.js.map +1 -1
  142. package/dist/components/groups/scoped.d.ts +23 -0
  143. package/dist/components/groups/scoped.js +92 -0
  144. package/dist/components/groups/scoped.js.map +1 -0
  145. package/dist/components/media-folder-editor.d.ts +5 -0
  146. package/dist/components/media-folder-editor.js +419 -231
  147. package/dist/components/media-folder-editor.js.map +1 -1
  148. package/dist/components/sortable-list.d.ts +5 -1
  149. package/dist/components/sortable-list.js +97 -81
  150. package/dist/components/sortable-list.js.map +1 -1
  151. package/dist/components/video-mini-player.d.ts +4 -1
  152. package/dist/components/video-mini-player.js +77 -71
  153. package/dist/components/video-mini-player.js.map +1 -1
  154. package/dist/components/video-player.d.ts +4 -1
  155. package/dist/components/video-player.js +280 -276
  156. package/dist/components/video-player.js.map +1 -1
  157. package/dist/index.d.ts +2 -1
  158. package/dist/index.js +41 -34
  159. package/dist/locales/admin/de.js +80 -47
  160. package/dist/locales/admin/de.js.map +1 -1
  161. package/dist/locales/admin/en.d.ts +74 -41
  162. package/dist/locales/admin/en.js +80 -47
  163. package/dist/locales/admin/en.js.map +1 -1
  164. package/dist/locales/admin/es.js +80 -47
  165. package/dist/locales/admin/es.js.map +1 -1
  166. package/dist/locales/admin/ja.js +80 -47
  167. package/dist/locales/admin/ja.js.map +1 -1
  168. package/dist/locales/admin/ko.js +80 -47
  169. package/dist/locales/admin/ko.js.map +1 -1
  170. package/dist/locales/admin/zh.js +80 -47
  171. package/dist/locales/admin/zh.js.map +1 -1
  172. package/dist/locales/de.js +1 -0
  173. package/dist/locales/de.js.map +1 -1
  174. package/dist/locales/discovery/de.js +25 -2
  175. package/dist/locales/discovery/de.js.map +1 -1
  176. package/dist/locales/discovery/en.d.ts +24 -1
  177. package/dist/locales/discovery/en.js +25 -2
  178. package/dist/locales/discovery/en.js.map +1 -1
  179. package/dist/locales/discovery/es.js +25 -2
  180. package/dist/locales/discovery/es.js.map +1 -1
  181. package/dist/locales/discovery/ja.js +25 -2
  182. package/dist/locales/discovery/ja.js.map +1 -1
  183. package/dist/locales/discovery/ko.js +25 -2
  184. package/dist/locales/discovery/ko.js.map +1 -1
  185. package/dist/locales/discovery/zh.js +25 -2
  186. package/dist/locales/discovery/zh.js.map +1 -1
  187. package/dist/locales/en.d.ts +119 -44
  188. package/dist/locales/en.js +1 -0
  189. package/dist/locales/en.js.map +1 -1
  190. package/dist/locales/es.js +1 -0
  191. package/dist/locales/es.js.map +1 -1
  192. package/dist/locales/groups/de.js +22 -4
  193. package/dist/locales/groups/de.js.map +1 -1
  194. package/dist/locales/groups/en.d.ts +20 -2
  195. package/dist/locales/groups/en.js +22 -4
  196. package/dist/locales/groups/en.js.map +1 -1
  197. package/dist/locales/groups/es.js +22 -4
  198. package/dist/locales/groups/es.js.map +1 -1
  199. package/dist/locales/groups/ja.js +22 -4
  200. package/dist/locales/groups/ja.js.map +1 -1
  201. package/dist/locales/groups/ko.js +22 -4
  202. package/dist/locales/groups/ko.js.map +1 -1
  203. package/dist/locales/groups/zh.js +22 -4
  204. package/dist/locales/groups/zh.js.map +1 -1
  205. package/dist/locales/ja.js +1 -0
  206. package/dist/locales/ja.js.map +1 -1
  207. package/dist/locales/ko.js +1 -0
  208. package/dist/locales/ko.js.map +1 -1
  209. package/dist/locales/zh.js +1 -0
  210. package/dist/locales/zh.js.map +1 -1
  211. package/dist/react/discovery.d.ts +36 -17
  212. package/dist/react/discovery.js +305 -221
  213. package/dist/react/discovery.js.map +1 -1
  214. package/dist/react/groups.d.ts +19 -3
  215. package/dist/react/groups.js +49 -22
  216. package/dist/react/groups.js.map +1 -1
  217. package/dist/react/index.d.ts +7 -4
  218. package/dist/react/page-notices.d.ts +13 -0
  219. package/dist/react/page-notices.js +38 -0
  220. package/dist/react/page-notices.js.map +1 -0
  221. package/dist/react/post-reads.d.ts +23 -0
  222. package/dist/react/post-reads.js +90 -0
  223. package/dist/react/post-reads.js.map +1 -0
  224. package/dist/react/remembered-sort.d.ts +5 -0
  225. package/dist/react/remembered-sort.js +29 -0
  226. package/dist/react/remembered-sort.js.map +1 -0
  227. package/dist/react/resources.d.ts +3 -1
  228. package/dist/react/resources.js +6 -2
  229. package/dist/react/resources.js.map +1 -1
  230. package/dist/react/stats.d.ts +3 -7
  231. package/dist/react/stats.js +2 -6
  232. package/dist/react/stats.js.map +1 -1
  233. package/dist/react/use-engagement.d.ts +28 -0
  234. package/dist/react/use-engagement.js +226 -0
  235. package/dist/react/use-engagement.js.map +1 -0
  236. package/dist/react/use-resource.d.ts +4 -3
  237. package/dist/react/use-resource.js +2 -1
  238. package/dist/react/use-resource.js.map +1 -1
  239. package/dist/react.js +29 -26
  240. package/dist/styles.css +1 -1
  241. package/dist/ui/dialog.d.ts +2 -1
  242. package/dist/ui/dialog.js +23 -20
  243. package/dist/ui/dialog.js.map +1 -1
  244. package/dist/urls/index.d.ts +1 -1
  245. package/dist/urls.js +2 -2
  246. package/dist/urls.js.map +1 -1
  247. package/package.json +1 -1
  248. package/dist/components/admin/page-review.d.ts +0 -13
  249. package/dist/components/admin/page-review.js +0 -225
  250. package/dist/components/admin/page-review.js.map +0 -1
  251. package/dist/react/page-review.d.ts +0 -14
  252. package/dist/react/page-review.js +0 -37
  253. package/dist/react/page-review.js.map +0 -1
@@ -0,0 +1,191 @@
1
+ //#region src/client/engagement.ts
2
+ var e = 12e4, t = () => typeof performance > "u" ? Date.now() : performance.now(), n = () => crypto.randomUUID(), r = (e, t, n = Infinity) => e !== void 0 && Number.isFinite(e) ? Math.max(1e3, Math.min(n, Math.floor(e))) : t;
3
+ function i(e, t = Infinity) {
4
+ let n = e.filter((e) => Number.isFinite(e.from) && Number.isFinite(e.to)).map(({ from: e, to: n }) => ({
5
+ from: Math.max(0, Math.round(e)),
6
+ to: Math.min(t, Math.round(n))
7
+ })).filter(({ from: e, to: t }) => t > e).sort((e, t) => e.from - t.from), r = [];
8
+ for (let e of n) {
9
+ let t = r.at(-1);
10
+ t && e.from <= t.to ? t.to = Math.max(t.to, e.to) : r.push({ ...e });
11
+ }
12
+ return r;
13
+ }
14
+ var a = class {
15
+ options;
16
+ visitId;
17
+ now;
18
+ id;
19
+ idleAfter;
20
+ interval;
21
+ last;
22
+ lastActivity;
23
+ attentive = !1;
24
+ observation = {};
25
+ segment;
26
+ pending = [];
27
+ tail = Promise.resolve();
28
+ stopped = !1;
29
+ keepaliveRequested = !1;
30
+ constructor(i) {
31
+ this.options = i, this.now = i.now ?? t, this.id = i.id ?? n, this.visitId = this.id(), this.idleAfter = r(i.idleAfter, 6e4), this.interval = r(i.checkpointInterval, e, e), this.last = this.lastActivity = this.now();
32
+ }
33
+ activity() {
34
+ this.advance(this.now()), this.lastActivity = this.now(), this.startObservedSegment();
35
+ }
36
+ attention(e) {
37
+ this.advance(this.now()), this.attentive = e, this.startObservedSegment();
38
+ }
39
+ observe(e) {
40
+ let t = this.now();
41
+ this.advance(t, e.video);
42
+ let n = 512, r = /* @__PURE__ */ new Map();
43
+ for (let t of e.pages ?? []) {
44
+ if (!Number.isSafeInteger(t.index) || t.index < 0 || r.size >= 128 || !n) continue;
45
+ let e = i(t.ranges, 1e4).slice(0, Math.min(16, n));
46
+ e.length && (r.set(t.index, {
47
+ index: t.index,
48
+ ranges: e
49
+ }), n -= e.length);
50
+ }
51
+ this.observation = {
52
+ ...e,
53
+ pages: [...r.values()]
54
+ }, this.startObservedSegment(), e.resume !== void 0 && this.segment && (this.segment.resume = e.resume, this.segment.changed = !0);
55
+ }
56
+ tick() {
57
+ this.advance(this.now()), this.startObservedSegment();
58
+ }
59
+ flush(e = !1) {
60
+ return this.stopped ? Promise.resolve() : (this.advance(this.now()), this.capture(), this.send(e));
61
+ }
62
+ discard() {
63
+ this.stopped = !0, this.segment = void 0, this.pending = [], this.observation = {};
64
+ }
65
+ startObservedSegment() {
66
+ let e = this.now();
67
+ !this.stopped && this.attentive && (this.observation.video?.playing || this.observation.pages?.length && e < this.lastActivity + this.idleAfter) && (this.segment ??= this.createSegment(e));
68
+ }
69
+ receipt() {
70
+ try {
71
+ return this.options.begin().catch(() => null);
72
+ } catch {
73
+ return Promise.resolve(null);
74
+ }
75
+ }
76
+ createSegment(e) {
77
+ return {
78
+ id: this.id(),
79
+ start: e,
80
+ active: 0,
81
+ pages: /* @__PURE__ */ new Map(),
82
+ watched: [],
83
+ revision: 0,
84
+ changed: !1,
85
+ resume: this.observation.resume,
86
+ receipt: this.receipt()
87
+ };
88
+ }
89
+ advance(e, t) {
90
+ if (this.stopped) return;
91
+ let n = this.last;
92
+ if (this.last = Math.max(n, e), e - n > 5e3) {
93
+ this.capture(), this.segment = void 0, this.send(!1);
94
+ return;
95
+ }
96
+ this.record(n, e, t, e), this.segment && e >= this.segment.start + this.interval && (this.capture(), this.segment = void 0, this.send(!1));
97
+ }
98
+ record(e, t, n, r) {
99
+ let a = this.observation.pages ?? [], o = this.observation.video, s = r - e, c = n && o ? n.positionMs - o.positionMs : 0, l = o?.playing && !o.seeking && n && !n.seeking && c > 0 && s > 0 && c <= s * 4 + 250;
100
+ if (!this.attentive || !a.length && !l) return;
101
+ let u = l ? t : Math.min(t, this.lastActivity + this.idleAfter), d = e;
102
+ for (; u > d;) {
103
+ this.segment ??= this.createSegment(d);
104
+ let t = Math.min(u, this.segment.start + this.interval), n = t - d;
105
+ if (n <= 0) {
106
+ this.capture(), this.segment = void 0, this.send(!1);
107
+ continue;
108
+ }
109
+ let r = l && o ? {
110
+ from: o.positionMs + c * (d - e) / s,
111
+ to: o.positionMs + c * (t - e) / s
112
+ } : void 0, f = new Map(this.segment.pages);
113
+ for (let e of a) f.set(e.index, {
114
+ index: e.index,
115
+ active_ms: 0,
116
+ ranges: i([...f.get(e.index)?.ranges ?? [], ...e.ranges], 1e4)
117
+ });
118
+ let p = r ? i([...this.segment.watched, r]) : this.segment.watched;
119
+ if (this.segment.active > 0 && (f.size > 128 || [...f.values()].some((e) => e.ranges.length > 16) || [...f.values()].reduce((e, t) => e + t.ranges.length, 0) > 512 || p.length > 256)) {
120
+ this.capture(), this.segment = void 0, this.send(!1);
121
+ continue;
122
+ }
123
+ if (this.segment.active += n, this.segment.changed = !0, this.segment.resume = this.observation.resume, a.length) {
124
+ let e = n / a.length;
125
+ for (let t of a) {
126
+ let n = this.segment.pages.get(t.index);
127
+ n || this.segment.pages.set(t.index, n = {
128
+ index: t.index,
129
+ ranges: [],
130
+ active_ms: 0
131
+ }), n.active_ms += e, n.ranges = i([...n.ranges, ...t.ranges], 1e4);
132
+ }
133
+ }
134
+ this.segment.watched = p, d = t, d >= this.segment.start + this.interval && (this.capture(), this.segment = void 0, this.send(!1));
135
+ }
136
+ }
137
+ capture() {
138
+ let e = this.segment;
139
+ if (!e?.changed || e.active < 1) return;
140
+ let t = [...e.pages.values()].filter((e) => e.active_ms >= 1).sort((e, t) => e.index - t.index).map((e) => ({
141
+ ...e,
142
+ active_ms: Math.floor(e.active_ms),
143
+ ranges: e.ranges.map((e) => ({ ...e }))
144
+ })), n = e.watched.map(({ from: e, to: t }) => ({
145
+ from_ms: e,
146
+ to_ms: t
147
+ }));
148
+ if (!t.length && !n.length) return;
149
+ e.changed = !1;
150
+ let r = {
151
+ content_id: this.options.contentId,
152
+ version_id: this.options.versionId,
153
+ visit_id: this.visitId,
154
+ segment_id: e.id,
155
+ revision: ++e.revision,
156
+ activity_token: "",
157
+ active_ms: Math.floor(e.active),
158
+ ...e.resume === void 0 ? {} : { resume: e.resume },
159
+ ...t.length ? { pages: t } : {},
160
+ ...n.length ? { watched: n } : {}
161
+ };
162
+ this.options.onSnapshot?.(r), this.pending = this.pending.filter((t) => t.snapshot.segment_id !== e.id), this.pending.push({
163
+ snapshot: r,
164
+ receipt: e.receipt
165
+ }), this.pending.length > 100 && this.pending.shift();
166
+ }
167
+ send(e) {
168
+ return this.keepaliveRequested ||= e, this.tail = this.tail.then(async () => {
169
+ for (let t of [...this.pending]) {
170
+ if (this.stopped) return;
171
+ let n = await t.receipt;
172
+ if (this.stopped) return;
173
+ if (!n) {
174
+ this.pending = this.pending.filter((e) => e !== t);
175
+ continue;
176
+ }
177
+ try {
178
+ await this.options.submit({
179
+ ...t.snapshot,
180
+ activity_token: n.token
181
+ }, { keepalive: e || this.keepaliveRequested }), this.pending = this.pending.filter((e) => e !== t);
182
+ } catch {}
183
+ }
184
+ this.pending.length || (this.keepaliveRequested = !1);
185
+ }), this.tail;
186
+ }
187
+ };
188
+ //#endregion
189
+ export { a as EngagementTracker };
190
+
191
+ //# sourceMappingURL=engagement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engagement.js","names":[],"sources":["../../src/client/engagement.ts"],"sourcesContent":["import type { ActivityContext, CoverageRange, EngagementSnapshot, PageEngagement, WatchedRange } from \"./generated/wire.js\";\n\nexport interface VisiblePage {\n /** Zero-based index in the version's reading order. */\n index: number;\n /** The part actually on screen, in 0..10000 basis points of page height. */\n ranges: readonly CoverageRange[];\n}\n\nexport interface ReadingObservation {\n pages?: readonly VisiblePage[];\n video?: { positionMs: number; playing: boolean; seeking?: boolean };\n resume?: string;\n}\n\nexport interface EngagementTrackerOptions {\n contentId: string;\n versionId?: string;\n /** Acquired when attention begins, never by preloading or opening a route. */\n begin: () => Promise<ActivityContext | null>;\n submit: (snapshot: EngagementSnapshot, options: { keepalive: boolean }) => Promise<void>;\n onSnapshot?: (snapshot: EngagementSnapshot) => void;\n idleAfter?: number;\n checkpointInterval?: number;\n now?: () => number;\n id?: () => string;\n}\n\nconst MAX_SEGMENT = 120_000;\nconst MAX_PENDING = 100;\nconst clock = () => typeof performance === \"undefined\" ? Date.now() : performance.now();\nconst randomId = () => crypto.randomUUID();\nconst durationOption = (value: number | undefined, fallback: number, max = Infinity) =>\n value !== undefined && Number.isFinite(value) ? Math.max(1000, Math.min(max, Math.floor(value))) : fallback;\n\n/** Coalesce coverage, so looking at the same page or video interval never inflates completion. */\nfunction union(ranges: readonly CoverageRange[], max = Infinity): CoverageRange[] {\n const ordered = ranges.filter((range) => Number.isFinite(range.from) && Number.isFinite(range.to))\n .map(({ from, to }) => ({ from: Math.max(0, Math.round(from)), to: Math.min(max, Math.round(to)) }))\n .filter(({ from, to }) => to > from).sort((a, b) => a.from - b.from);\n const merged: CoverageRange[] = [];\n for (const range of ordered) {\n const last = merged.at(-1);\n if (last && range.from <= last.to) last.to = Math.max(last.to, range.to);\n else merged.push({ ...range });\n }\n return merged;\n}\n\ninterface Segment {\n id: string;\n start: number;\n active: number;\n pages: Map<number, PageEngagement>;\n watched: CoverageRange[];\n revision: number;\n changed: boolean;\n resume?: string;\n receipt: Promise<ActivityContext | null>;\n}\n\n/**\n * One content visit, represented by cumulative, bounded attention snapshots.\n * The clock and transport are injected so ownership and browser lifecycle stay\n * outside the accounting. Repeated snapshots replace a revision, not add views.\n */\nexport class EngagementTracker {\n readonly visitId: string;\n private readonly now: () => number;\n private readonly id: () => string;\n private readonly idleAfter: number;\n private readonly interval: number;\n private last: number;\n private lastActivity: number;\n private attentive = false;\n private observation: ReadingObservation = {};\n private segment?: Segment;\n private pending: { snapshot: EngagementSnapshot; receipt: Promise<ActivityContext | null> }[] = [];\n private tail: Promise<void> = Promise.resolve();\n private stopped = false;\n private keepaliveRequested = false;\n\n constructor(private readonly options: EngagementTrackerOptions) {\n this.now = options.now ?? clock;\n this.id = options.id ?? randomId;\n this.visitId = this.id();\n this.idleAfter = durationOption(options.idleAfter, 60_000);\n this.interval = durationOption(options.checkpointInterval, MAX_SEGMENT, MAX_SEGMENT);\n this.last = this.lastActivity = this.now();\n }\n\n /** Genuine input extends the reading window; a timer or preload does not. */\n activity(): void {\n this.advance(this.now());\n this.lastActivity = this.now();\n this.startObservedSegment();\n }\n\n attention(attentive: boolean): void {\n this.advance(this.now());\n this.attentive = attentive;\n this.startObservedSegment();\n }\n\n observe(observation: ReadingObservation): void {\n const at = this.now();\n this.advance(at, observation.video);\n let remaining = 512;\n const pages = new Map<number, VisiblePage>();\n for (const page of observation.pages ?? []) {\n if (!Number.isSafeInteger(page.index) || page.index < 0 || pages.size >= 128 || !remaining) continue;\n const ranges = union(page.ranges, 10_000).slice(0, Math.min(16, remaining));\n if (!ranges.length) continue;\n pages.set(page.index, { index: page.index, ranges });\n remaining -= ranges.length;\n }\n this.observation = { ...observation, pages: [...pages.values()] };\n this.startObservedSegment();\n if (observation.resume !== undefined && this.segment) {\n this.segment.resume = observation.resume;\n this.segment.changed = true;\n }\n }\n\n /** Tick even while the geometry is unchanged, so idle and checkpoint bounds hold. */\n tick(): void { this.advance(this.now()); this.startObservedSegment(); }\n\n /** Send accumulated attention; failed packets retain their exact revision for retry. */\n flush(keepalive = false): Promise<void> {\n if (this.stopped) return Promise.resolve();\n this.advance(this.now());\n this.capture();\n return this.send(keepalive);\n }\n\n /** Account changes discard old ownership instead of sending under new credentials. */\n discard(): void {\n this.stopped = true;\n this.segment = undefined;\n this.pending = [];\n this.observation = {};\n }\n\n private startObservedSegment(): void {\n const at = this.now();\n if (!this.stopped && this.attentive && (this.observation.video?.playing\n || (this.observation.pages?.length && at < this.lastActivity + this.idleAfter))) this.segment ??= this.createSegment(at);\n }\n\n private receipt(): Promise<ActivityContext | null> {\n try { return this.options.begin().catch(() => null); }\n catch { return Promise.resolve(null); }\n }\n\n private createSegment(start: number): Segment {\n return {\n id: this.id(), start, active: 0, pages: new Map(), watched: [], revision: 0, changed: false,\n resume: this.observation.resume,\n // Capture immediately; a later checkpoint must not rebind old attention\n // to a new access level. An unavailable receipt drops remote telemetry.\n receipt: this.receipt(),\n };\n }\n\n private advance(at: number, video?: ReadingObservation[\"video\"]): void {\n if (this.stopped) return;\n const previous = this.last;\n this.last = Math.max(previous, at);\n if (at - previous > 5000) {\n // A suspended tab or stalled timer cannot tell us what stayed visible or\n // which access cohort applied. Never backfill it under a new receipt.\n this.capture(); this.segment = undefined; void this.send(false);\n return;\n }\n this.record(previous, at, video, at);\n if (this.segment && at >= this.segment.start + this.interval) {\n this.capture(); this.segment = undefined; void this.send(false);\n }\n }\n\n private record(from: number, to: number, video: ReadingObservation[\"video\"], sampledAt: number): void {\n const pages = this.observation.pages ?? [];\n const previousVideo = this.observation.video;\n const duration = sampledAt - from;\n const delta = video && previousVideo ? video.positionMs - previousVideo.positionMs : 0;\n const playing = previousVideo?.playing && !previousVideo.seeking && video && !video.seeking\n && delta > 0 && duration > 0 && delta <= duration * 4 + 250;\n if (!this.attentive || (!pages.length && !playing)) return;\n const end = playing ? to : Math.min(to, this.lastActivity + this.idleAfter);\n let start = from;\n while (end > start) {\n this.segment ??= this.createSegment(start);\n const boundary = Math.min(end, this.segment.start + this.interval);\n const elapsed = boundary - start;\n if (elapsed <= 0) {\n this.capture(); this.segment = undefined; void this.send(false);\n continue;\n }\n // Real playback can be faster than 1x; discontinuous seeks are not watched.\n const watched = playing && previousVideo ? {\n from: previousVideo.positionMs + delta * (start - from) / duration,\n to: previousVideo.positionMs + delta * (boundary - from) / duration,\n } : undefined;\n const nextPages = new Map(this.segment.pages);\n for (const page of pages) nextPages.set(page.index, { index: page.index, active_ms: 0,\n ranges: union([...(nextPages.get(page.index)?.ranges ?? []), ...page.ranges], 10_000) });\n const nextWatched = watched ? union([...this.segment.watched, watched]) : this.segment.watched;\n if (this.segment.active > 0 && (nextPages.size > 128 || [...nextPages.values()].some((page) => page.ranges.length > 16)\n || [...nextPages.values()].reduce((total, page) => total + page.ranges.length, 0) > 512 || nextWatched.length > 256)) {\n this.capture(); this.segment = undefined; void this.send(false);\n continue;\n }\n this.segment.active += elapsed;\n this.segment.changed = true;\n this.segment.resume = this.observation.resume;\n if (pages.length) {\n const share = elapsed / pages.length;\n for (const page of pages) {\n let row = this.segment.pages.get(page.index);\n if (!row) this.segment.pages.set(page.index, (row = { index: page.index, ranges: [], active_ms: 0 }));\n row.active_ms += share;\n row.ranges = union([...row.ranges, ...page.ranges], 10_000);\n }\n }\n this.segment.watched = nextWatched;\n start = boundary;\n if (start >= this.segment.start + this.interval) {\n this.capture(); this.segment = undefined; void this.send(false);\n }\n }\n }\n\n private capture(): void {\n const segment = this.segment;\n if (!segment?.changed || segment.active < 1) return;\n const pages = [...segment.pages.values()].filter((page) => page.active_ms >= 1)\n .sort((a, b) => a.index - b.index).map((page) => ({ ...page, active_ms: Math.floor(page.active_ms), ranges: page.ranges.map((range) => ({ ...range })) }));\n const watched: WatchedRange[] = segment.watched.map(({ from, to }) => ({ from_ms: from, to_ms: to }));\n if (!pages.length && !watched.length) return;\n segment.changed = false;\n const snapshot: EngagementSnapshot = {\n content_id: this.options.contentId, version_id: this.options.versionId,\n visit_id: this.visitId, segment_id: segment.id, revision: ++segment.revision,\n activity_token: \"\", active_ms: Math.floor(segment.active),\n ...(segment.resume !== undefined ? { resume: segment.resume } : {}),\n ...(pages.length ? { pages } : {}), ...(watched.length ? { watched } : {}),\n };\n this.options.onSnapshot?.(snapshot);\n // A newer cumulative revision makes an unsent earlier revision unnecessary.\n this.pending = this.pending.filter((entry) => entry.snapshot.segment_id !== segment.id);\n this.pending.push({ snapshot, receipt: segment.receipt });\n if (this.pending.length > MAX_PENDING) this.pending.shift();\n }\n\n private send(keepalive: boolean): Promise<void> {\n this.keepaliveRequested ||= keepalive;\n this.tail = this.tail.then(async () => {\n for (const entry of [...this.pending]) {\n if (this.stopped) return;\n const context = await entry.receipt;\n if (this.stopped) return;\n if (!context) { this.pending = this.pending.filter((item) => item !== entry); continue; }\n try {\n await this.options.submit({ ...entry.snapshot, activity_token: context.token }, { keepalive: keepalive || this.keepaliveRequested });\n this.pending = this.pending.filter((item) => item !== entry);\n } catch {\n // A later checkpoint, online event or exit can retry this same revision.\n }\n }\n if (!this.pending.length) this.keepaliveRequested = false;\n });\n return this.tail;\n }\n}\n"],"mappings":";AA4BA,IAAM,IAAc,MAEd,UAAc,OAAO,cAAgB,MAAc,KAAK,IAAI,IAAI,YAAY,IAAI,GAChF,UAAiB,OAAO,WAAW,GACnC,KAAkB,GAA2B,GAAkB,IAAM,aACzE,MAAU,KAAA,KAAa,OAAO,SAAS,CAAK,IAAI,KAAK,IAAI,KAAM,KAAK,IAAI,GAAK,KAAK,MAAM,CAAK,CAAC,CAAC,IAAI;AAGrG,SAAS,EAAM,GAAkC,IAAM,UAA2B;CAChF,IAAM,IAAU,EAAO,QAAQ,MAAU,OAAO,SAAS,EAAM,IAAI,KAAK,OAAO,SAAS,EAAM,EAAE,CAAC,CAAC,CAC/F,KAAK,EAAE,SAAM,aAAU;EAAE,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM,CAAI,CAAC;EAAG,IAAI,KAAK,IAAI,GAAK,KAAK,MAAM,CAAE,CAAC;CAAE,EAAE,CAAC,CACnG,QAAQ,EAAE,SAAM,YAAS,IAAK,CAAI,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,IAAI,GAC/D,IAA0B,CAAC;CACjC,KAAK,IAAM,KAAS,GAAS;EAC3B,IAAM,IAAO,EAAO,GAAG,EAAE;EACzB,AAAI,KAAQ,EAAM,QAAQ,EAAK,KAAI,EAAK,KAAK,KAAK,IAAI,EAAK,IAAI,EAAM,EAAE,IAClE,EAAO,KAAK,EAAE,GAAG,EAAM,CAAC;CAC/B;CACA,OAAO;AACT;AAmBA,IAAa,IAAb,MAA+B;CAgBA;CAf7B;CACA;CACA;CACA;CACA;CACA;CACA;CACA,YAAoB;CACpB,cAA0C,CAAC;CAC3C;CACA,UAAgG,CAAC;CACjG,OAA8B,QAAQ,QAAQ;CAC9C,UAAkB;CAClB,qBAA6B;CAE7B,YAAY,GAAoD;EAM9D,AAN2B,KAAA,UAAA,GAC3B,KAAK,MAAM,EAAQ,OAAO,GAC1B,KAAK,KAAK,EAAQ,MAAM,GACxB,KAAK,UAAU,KAAK,GAAG,GACvB,KAAK,YAAY,EAAe,EAAQ,WAAW,GAAM,GACzD,KAAK,WAAW,EAAe,EAAQ,oBAAoB,GAAa,CAAW,GACnF,KAAK,OAAO,KAAK,eAAe,KAAK,IAAI;CAC3C;CAGA,WAAiB;EAGf,AAFA,KAAK,QAAQ,KAAK,IAAI,CAAC,GACvB,KAAK,eAAe,KAAK,IAAI,GAC7B,KAAK,qBAAqB;CAC5B;CAEA,UAAU,GAA0B;EAGlC,AAFA,KAAK,QAAQ,KAAK,IAAI,CAAC,GACvB,KAAK,YAAY,GACjB,KAAK,qBAAqB;CAC5B;CAEA,QAAQ,GAAuC;EAC7C,IAAM,IAAK,KAAK,IAAI;EACpB,KAAK,QAAQ,GAAI,EAAY,KAAK;EAClC,IAAI,IAAY,KACV,oBAAQ,IAAI,IAAyB;EAC3C,KAAK,IAAM,KAAQ,EAAY,SAAS,CAAC,GAAG;GAC1C,IAAI,CAAC,OAAO,cAAc,EAAK,KAAK,KAAK,EAAK,QAAQ,KAAK,EAAM,QAAQ,OAAO,CAAC,GAAW;GAC5F,IAAM,IAAS,EAAM,EAAK,QAAQ,GAAM,CAAC,CAAC,MAAM,GAAG,KAAK,IAAI,IAAI,CAAS,CAAC;GACrE,EAAO,WACZ,EAAM,IAAI,EAAK,OAAO;IAAE,OAAO,EAAK;IAAO;GAAO,CAAC,GACnD,KAAa,EAAO;EACtB;EAGA,AAFA,KAAK,cAAc;GAAE,GAAG;GAAa,OAAO,CAAC,GAAG,EAAM,OAAO,CAAC;EAAE,GAChE,KAAK,qBAAqB,GACtB,EAAY,WAAW,KAAA,KAAa,KAAK,YAC3C,KAAK,QAAQ,SAAS,EAAY,QAClC,KAAK,QAAQ,UAAU;CAE3B;CAGA,OAAa;EAA4B,AAA1B,KAAK,QAAQ,KAAK,IAAI,CAAC,GAAG,KAAK,qBAAqB;CAAG;CAGtE,MAAM,IAAY,IAAsB;EAItC,OAHI,KAAK,UAAgB,QAAQ,QAAQ,KACzC,KAAK,QAAQ,KAAK,IAAI,CAAC,GACvB,KAAK,QAAQ,GACN,KAAK,KAAK,CAAS;CAC5B;CAGA,UAAgB;EAId,AAHA,KAAK,UAAU,IACf,KAAK,UAAU,KAAA,GACf,KAAK,UAAU,CAAC,GAChB,KAAK,cAAc,CAAC;CACtB;CAEA,uBAAqC;EACnC,IAAM,IAAK,KAAK,IAAI;EACpB,AAAI,CAAC,KAAK,WAAW,KAAK,cAAc,KAAK,YAAY,OAAO,WAC1D,KAAK,YAAY,OAAO,UAAU,IAAK,KAAK,eAAe,KAAK,eAAa,KAAK,YAAY,KAAK,cAAc,CAAE;CAC3H;CAEA,UAAmD;EACjD,IAAI;GAAE,OAAO,KAAK,QAAQ,MAAM,CAAC,CAAC,YAAY,IAAI;EAAG,QAC/C;GAAE,OAAO,QAAQ,QAAQ,IAAI;EAAG;CACxC;CAEA,cAAsB,GAAwB;EAC5C,OAAO;GACL,IAAI,KAAK,GAAG;GAAG;GAAO,QAAQ;GAAG,uBAAO,IAAI,IAAI;GAAG,SAAS,CAAC;GAAG,UAAU;GAAG,SAAS;GACtF,QAAQ,KAAK,YAAY;GAGzB,SAAS,KAAK,QAAQ;EACxB;CACF;CAEA,QAAgB,GAAY,GAA2C;EACrE,IAAI,KAAK,SAAS;EAClB,IAAM,IAAW,KAAK;EAEtB,IADA,KAAK,OAAO,KAAK,IAAI,GAAU,CAAE,GAC7B,IAAK,IAAW,KAAM;GAGkB,AAA1C,KAAK,QAAQ,GAAG,KAAK,UAAU,KAAA,GAAW,KAAU,KAAK,EAAK;GAC9D;EACF;EAEA,AADA,KAAK,OAAO,GAAU,GAAI,GAAO,CAAE,GAC/B,KAAK,WAAW,KAAM,KAAK,QAAQ,QAAQ,KAAK,aAClD,KAAK,QAAQ,GAAG,KAAK,UAAU,KAAA,GAAW,KAAU,KAAK,EAAK;CAElE;CAEA,OAAe,GAAc,GAAY,GAAoC,GAAyB;EACpG,IAAM,IAAQ,KAAK,YAAY,SAAS,CAAC,GACnC,IAAgB,KAAK,YAAY,OACjC,IAAW,IAAY,GACvB,IAAQ,KAAS,IAAgB,EAAM,aAAa,EAAc,aAAa,GAC/E,IAAU,GAAe,WAAW,CAAC,EAAc,WAAW,KAAS,CAAC,EAAM,WAC/E,IAAQ,KAAK,IAAW,KAAK,KAAS,IAAW,IAAI;EAC1D,IAAI,CAAC,KAAK,aAAc,CAAC,EAAM,UAAU,CAAC,GAAU;EACpD,IAAM,IAAM,IAAU,IAAK,KAAK,IAAI,GAAI,KAAK,eAAe,KAAK,SAAS,GACtE,IAAQ;EACZ,OAAO,IAAM,IAAO;GAClB,KAAK,YAAY,KAAK,cAAc,CAAK;GACzC,IAAM,IAAW,KAAK,IAAI,GAAK,KAAK,QAAQ,QAAQ,KAAK,QAAQ,GAC3D,IAAU,IAAW;GAC3B,IAAI,KAAW,GAAG;IAC0B,AAA1C,KAAK,QAAQ,GAAG,KAAK,UAAU,KAAA,GAAW,KAAU,KAAK,EAAK;IAC9D;GACF;GAEA,IAAM,IAAU,KAAW,IAAgB;IACzC,MAAM,EAAc,aAAa,KAAS,IAAQ,KAAQ;IAC1D,IAAI,EAAc,aAAa,KAAS,IAAW,KAAQ;GAC7D,IAAI,KAAA,GACE,IAAY,IAAI,IAAI,KAAK,QAAQ,KAAK;GAC5C,KAAK,IAAM,KAAQ,GAAO,EAAU,IAAI,EAAK,OAAO;IAAE,OAAO,EAAK;IAAO,WAAW;IAClF,QAAQ,EAAM,CAAC,GAAI,EAAU,IAAI,EAAK,KAAK,CAAC,EAAE,UAAU,CAAC,GAAI,GAAG,EAAK,MAAM,GAAG,GAAM;GAAE,CAAC;GACzF,IAAM,IAAc,IAAU,EAAM,CAAC,GAAG,KAAK,QAAQ,SAAS,CAAO,CAAC,IAAI,KAAK,QAAQ;GACvF,IAAI,KAAK,QAAQ,SAAS,MAAM,EAAU,OAAO,OAAO,CAAC,GAAG,EAAU,OAAO,CAAC,CAAC,CAAC,MAAM,MAAS,EAAK,OAAO,SAAS,EAAE,KACjH,CAAC,GAAG,EAAU,OAAO,CAAC,CAAC,CAAC,QAAQ,GAAO,MAAS,IAAQ,EAAK,OAAO,QAAQ,CAAC,IAAI,OAAO,EAAY,SAAS,MAAM;IAC5E,AAA1C,KAAK,QAAQ,GAAG,KAAK,UAAU,KAAA,GAAW,KAAU,KAAK,EAAK;IAC9D;GACF;GAIA,IAHA,KAAK,QAAQ,UAAU,GACvB,KAAK,QAAQ,UAAU,IACvB,KAAK,QAAQ,SAAS,KAAK,YAAY,QACnC,EAAM,QAAQ;IAChB,IAAM,IAAQ,IAAU,EAAM;IAC9B,KAAK,IAAM,KAAQ,GAAO;KACxB,IAAI,IAAM,KAAK,QAAQ,MAAM,IAAI,EAAK,KAAK;KAG3C,AAFK,KAAK,KAAK,QAAQ,MAAM,IAAI,EAAK,OAAQ,IAAM;MAAE,OAAO,EAAK;MAAO,QAAQ,CAAC;MAAG,WAAW;KAAE,CAAE,GACpG,EAAI,aAAa,GACjB,EAAI,SAAS,EAAM,CAAC,GAAG,EAAI,QAAQ,GAAG,EAAK,MAAM,GAAG,GAAM;IAC5D;GACF;GAGA,AAFA,KAAK,QAAQ,UAAU,GACvB,IAAQ,GACJ,KAAS,KAAK,QAAQ,QAAQ,KAAK,aACrC,KAAK,QAAQ,GAAG,KAAK,UAAU,KAAA,GAAW,KAAU,KAAK,EAAK;EAElE;CACF;CAEA,UAAwB;EACtB,IAAM,IAAU,KAAK;EACrB,IAAI,CAAC,GAAS,WAAW,EAAQ,SAAS,GAAG;EAC7C,IAAM,IAAQ,CAAC,GAAG,EAAQ,MAAM,OAAO,CAAC,CAAC,CAAC,QAAQ,MAAS,EAAK,aAAa,CAAC,CAAC,CAC5E,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,KAAK,OAAU;GAAE,GAAG;GAAM,WAAW,KAAK,MAAM,EAAK,SAAS;GAAG,QAAQ,EAAK,OAAO,KAAK,OAAW,EAAE,GAAG,EAAM,EAAE;EAAE,EAAE,GACrJ,IAA0B,EAAQ,QAAQ,KAAK,EAAE,SAAM,aAAU;GAAE,SAAS;GAAM,OAAO;EAAG,EAAE;EACpG,IAAI,CAAC,EAAM,UAAU,CAAC,EAAQ,QAAQ;EACtC,EAAQ,UAAU;EAClB,IAAM,IAA+B;GACnC,YAAY,KAAK,QAAQ;GAAW,YAAY,KAAK,QAAQ;GAC7D,UAAU,KAAK;GAAS,YAAY,EAAQ;GAAI,UAAU,EAAE,EAAQ;GACpE,gBAAgB;GAAI,WAAW,KAAK,MAAM,EAAQ,MAAM;GACxD,GAAI,EAAQ,WAAW,KAAA,IAAyC,CAAC,IAA9B,EAAE,QAAQ,EAAQ,OAAO;GAC5D,GAAI,EAAM,SAAS,EAAE,SAAM,IAAI,CAAC;GAAI,GAAI,EAAQ,SAAS,EAAE,WAAQ,IAAI,CAAC;EAC1E;EAKA,AAJA,KAAK,QAAQ,aAAa,CAAQ,GAElC,KAAK,UAAU,KAAK,QAAQ,QAAQ,MAAU,EAAM,SAAS,eAAe,EAAQ,EAAE,GACtF,KAAK,QAAQ,KAAK;GAAE;GAAU,SAAS,EAAQ;EAAQ,CAAC,GACpD,KAAK,QAAQ,SAAS,OAAa,KAAK,QAAQ,MAAM;CAC5D;CAEA,KAAa,GAAmC;EAiB9C,OAhBA,KAAK,uBAAuB,GAC5B,KAAK,OAAO,KAAK,KAAK,KAAK,YAAY;GACrC,KAAK,IAAM,KAAS,CAAC,GAAG,KAAK,OAAO,GAAG;IACrC,IAAI,KAAK,SAAS;IAClB,IAAM,IAAU,MAAM,EAAM;IAC5B,IAAI,KAAK,SAAS;IAClB,IAAI,CAAC,GAAS;KAAE,KAAK,UAAU,KAAK,QAAQ,QAAQ,MAAS,MAAS,CAAK;KAAG;IAAU;IACxF,IAAI;KAEF,AADA,MAAM,KAAK,QAAQ,OAAO;MAAE,GAAG,EAAM;MAAU,gBAAgB,EAAQ;KAAM,GAAG,EAAE,WAAW,KAAa,KAAK,mBAAmB,CAAC,GACnI,KAAK,UAAU,KAAK,QAAQ,QAAQ,MAAS,MAAS,CAAK;IAC7D,QAAQ,CAER;GACF;GACA,AAAK,KAAK,QAAQ,WAAQ,KAAK,qBAAqB;EACtD,CAAC,GACM,KAAK;CACd;AACF"}
@@ -905,7 +905,7 @@ export declare const CONTENTKIT_ROUTES: readonly [{
905
905
  readonly path: "/manage";
906
906
  readonly auth: "public";
907
907
  readonly permission: null;
908
- readonly query: readonly ["state", "owner_group", "q", "language", "limit", "offset"];
908
+ readonly query: readonly ["state", "owner_group", "access", "tier", "q", "code", "ids", "language", "limit", "offset"];
909
909
  readonly request: null;
910
910
  readonly responses: {
911
911
  readonly 200: "Content[]";
@@ -918,13 +918,26 @@ export declare const CONTENTKIT_ROUTES: readonly [{
918
918
  readonly path: "/manage/{kind}";
919
919
  readonly auth: "public";
920
920
  readonly permission: null;
921
- readonly query: readonly ["state", "owner_group", "q", "language", "limit", "offset"];
921
+ readonly query: readonly ["state", "owner_group", "access", "tier", "q", "code", "ids", "language", "limit", "offset"];
922
922
  readonly request: null;
923
923
  readonly responses: {
924
924
  readonly 200: "Content[]";
925
925
  };
926
926
  readonly errors: readonly ["not_found"];
927
927
  readonly errorSets: readonly ["module:contents", "auth", "request"];
928
+ }, {
929
+ readonly method: "GET";
930
+ readonly module: "contents";
931
+ readonly path: "/manage/{kind}/count";
932
+ readonly auth: "public";
933
+ readonly permission: null;
934
+ readonly query: readonly ["state", "owner_group", "access", "tier", "q"];
935
+ readonly request: null;
936
+ readonly responses: {
937
+ readonly 200: "ManageCount";
938
+ };
939
+ readonly errors: readonly ["not_found"];
940
+ readonly errorSets: readonly ["module:contents", "auth", "request"];
928
941
  }, {
929
942
  readonly method: "POST";
930
943
  readonly module: "contents";
@@ -1295,7 +1308,7 @@ export declare const CONTENTKIT_ROUTES: readonly [{
1295
1308
  readonly method: "GET";
1296
1309
  readonly module: "codes";
1297
1310
  readonly path: "/{code}";
1298
- readonly auth: "open";
1311
+ readonly auth: "public";
1299
1312
  readonly permission: null;
1300
1313
  readonly query: readonly ["lang", "v"];
1301
1314
  readonly request: null;
@@ -1303,7 +1316,7 @@ export declare const CONTENTKIT_ROUTES: readonly [{
1303
1316
  readonly 200: "Resolved";
1304
1317
  };
1305
1318
  readonly errors: readonly ["gone", "not_found"];
1306
- readonly errorSets: readonly ["module:codes", "request"];
1319
+ readonly errorSets: readonly ["module:codes", "auth", "request"];
1307
1320
  }, {
1308
1321
  readonly method: "POST";
1309
1322
  readonly module: "codes";
@@ -1323,7 +1336,7 @@ export declare const CONTENTKIT_ROUTES: readonly [{
1323
1336
  readonly path: "/entities";
1324
1337
  readonly auth: "public";
1325
1338
  readonly permission: null;
1326
- readonly query: readonly ["kind", "parent", "scope", "slug", "letter", "language", "content_kind", "sort", "cursor", "limit"];
1339
+ readonly query: readonly ["kind", "parent", "scope", "slug", "letter", "language", "content_kind", "sort", "cursor", "page", "limit"];
1327
1340
  readonly request: null;
1328
1341
  readonly responses: {
1329
1342
  readonly 200: "GroupPage";
@@ -1349,7 +1362,7 @@ export declare const CONTENTKIT_ROUTES: readonly [{
1349
1362
  readonly path: "/manage/entities";
1350
1363
  readonly auth: "staff";
1351
1364
  readonly permission: "root:entities:write";
1352
- readonly query: readonly ["kind", "parent", "scope", "slug", "q", "letter", "language", "content_kind", "sort", "cursor", "limit"];
1365
+ readonly query: readonly ["state", "kind", "parent", "scope", "slug", "q", "letter", "language", "content_kind", "sort", "cursor", "limit"];
1353
1366
  readonly request: null;
1354
1367
  readonly responses: {
1355
1368
  readonly 200: "GroupPage";
@@ -1658,28 +1671,41 @@ export declare const CONTENTKIT_ROUTES: readonly [{
1658
1671
  }, {
1659
1672
  readonly method: "GET";
1660
1673
  readonly module: "versions";
1661
- readonly path: "/contents/{id}/versions/{version}/pages";
1674
+ readonly path: "/contents/{id}/versions/{version}/page-notices";
1662
1675
  readonly auth: "editor";
1663
1676
  readonly permission: "root:content:write";
1664
1677
  readonly query: readonly [];
1665
1678
  readonly request: null;
1666
1679
  readonly responses: {
1667
- readonly 200: "PageReview";
1680
+ readonly 200: "PageNotices";
1668
1681
  };
1669
1682
  readonly errors: readonly ["not_found", "forbidden"];
1670
1683
  readonly errorSets: readonly ["module:versions", "auth", "request"];
1671
1684
  }, {
1672
- readonly method: "PATCH";
1685
+ readonly method: "POST";
1673
1686
  readonly module: "versions";
1674
- readonly path: "/contents/{id}/versions/{version}/pages";
1687
+ readonly path: "/contents/{id}/versions/{version}/page-notices/{notice}/dismiss";
1675
1688
  readonly auth: "editor";
1676
1689
  readonly permission: "root:content:write";
1677
1690
  readonly query: readonly [];
1678
- readonly request: "PageReviewPatch";
1691
+ readonly request: null;
1679
1692
  readonly responses: {
1680
- readonly 200: "PageReview";
1693
+ readonly 204: null;
1681
1694
  };
1682
- readonly errors: readonly ["conflict", "invalid_request", "not_found", "forbidden"];
1695
+ readonly errors: readonly ["not_found", "forbidden"];
1696
+ readonly errorSets: readonly ["module:versions", "auth", "request"];
1697
+ }, {
1698
+ readonly method: "POST";
1699
+ readonly module: "versions";
1700
+ readonly path: "/contents/{id}/versions/{version}/page-notices/{notice}/restore";
1701
+ readonly auth: "editor";
1702
+ readonly permission: "root:content:write";
1703
+ readonly query: readonly [];
1704
+ readonly request: null;
1705
+ readonly responses: {
1706
+ readonly 200: "PageNotices";
1707
+ };
1708
+ readonly errors: readonly ["invalid_request", "not_found", "forbidden"];
1683
1709
  readonly errorSets: readonly ["module:versions", "auth", "request"];
1684
1710
  }, {
1685
1711
  readonly method: "GET";
@@ -1878,6 +1904,19 @@ export declare const CONTENTKIT_ROUTES: readonly [{
1878
1904
  };
1879
1905
  readonly errors: readonly [];
1880
1906
  readonly errorSets: readonly ["module:offers", "auth", "request"];
1907
+ }, {
1908
+ readonly method: "POST";
1909
+ readonly module: "discovery";
1910
+ readonly path: "/engagement";
1911
+ readonly auth: "public";
1912
+ readonly permission: null;
1913
+ readonly query: readonly [];
1914
+ readonly request: "EngagementBatch";
1915
+ readonly responses: {
1916
+ readonly 204: null;
1917
+ };
1918
+ readonly errors: readonly ["not_found", "not_configured"];
1919
+ readonly errorSets: readonly ["module:discovery", "auth", "request"];
1881
1920
  }, {
1882
1921
  readonly method: "POST";
1883
1922
  readonly module: "discovery";
@@ -1897,7 +1936,7 @@ export declare const CONTENTKIT_ROUTES: readonly [{
1897
1936
  readonly path: "/releases";
1898
1937
  readonly auth: "public";
1899
1938
  readonly permission: null;
1900
- readonly query: readonly ["kind", "groups", "exclude_groups", "owner_group", "creators", "access", "tiers", "traits", "attribute", "published_within", "view_status", "language", "display_language", "mode", "card_entities", "days", "end_date", "time_zone"];
1939
+ readonly query: readonly ["kind", "ids", "groups", "exclude_groups", "owner_group", "creators", "access", "tiers", "traits", "attribute", "published_within", "view_status", "language", "display_language", "mode", "card_entities", "days", "end_date", "time_zone"];
1901
1940
  readonly request: null;
1902
1941
  readonly responses: {
1903
1942
  readonly 200: "DailyReleases";
@@ -1910,7 +1949,7 @@ export declare const CONTENTKIT_ROUTES: readonly [{
1910
1949
  readonly path: "/contents";
1911
1950
  readonly auth: "public";
1912
1951
  readonly permission: null;
1913
- readonly query: readonly ["kind", "groups", "exclude_groups", "owner_group", "creators", "access", "tiers", "traits", "attribute", "released_on", "published_within", "tz", "view_status", "language", "display_language", "mode", "sort", "card_entities", "activity_from", "activity_until", "cursor", "limit"];
1952
+ readonly query: readonly ["kind", "ids", "groups", "exclude_groups", "owner_group", "creators", "access", "tiers", "traits", "attribute", "released_on", "published_within", "tz", "view_status", "language", "display_language", "mode", "sort", "card_entities", "summary", "activity_from", "activity_until", "cursor", "limit", "page"];
1914
1953
  readonly request: null;
1915
1954
  readonly responses: {
1916
1955
  readonly 200: "ContentPage";
@@ -1923,7 +1962,7 @@ export declare const CONTENTKIT_ROUTES: readonly [{
1923
1962
  readonly path: "/search";
1924
1963
  readonly auth: "public";
1925
1964
  readonly permission: null;
1926
- readonly query: readonly ["q", "kind", "groups", "exclude_groups", "owner_group", "creators", "access", "tiers", "traits", "attribute", "released_on", "published_within", "tz", "view_status", "language", "display_language", "mode", "sort", "card_entities", "personalize", "session", "cursor", "limit"];
1965
+ readonly query: readonly ["q", "kind", "ids", "groups", "exclude_groups", "owner_group", "creators", "access", "tiers", "traits", "attribute", "released_on", "published_within", "tz", "view_status", "language", "display_language", "mode", "sort", "card_entities", "summary", "personalize", "session", "cursor", "limit", "page"];
1927
1966
  readonly request: null;
1928
1967
  readonly responses: {
1929
1968
  readonly 200: "ContentPage";
@@ -1949,7 +1988,7 @@ export declare const CONTENTKIT_ROUTES: readonly [{
1949
1988
  readonly path: "/contents/{id}/similar";
1950
1989
  readonly auth: "public";
1951
1990
  readonly permission: null;
1952
- readonly query: readonly ["kind", "groups", "exclude_groups", "owner_group", "creators", "access", "tiers", "traits", "attribute", "released_on", "published_within", "tz", "view_status", "language", "display_language", "mode", "card_entities", "limit"];
1991
+ readonly query: readonly ["kind", "ids", "groups", "exclude_groups", "owner_group", "creators", "access", "tiers", "traits", "attribute", "released_on", "published_within", "tz", "view_status", "language", "display_language", "mode", "card_entities", "limit", "summary"];
1953
1992
  readonly request: null;
1954
1993
  readonly responses: {
1955
1994
  readonly 200: "ContentPage";
@@ -1962,7 +2001,7 @@ export declare const CONTENTKIT_ROUTES: readonly [{
1962
2001
  readonly path: "/recommendations";
1963
2002
  readonly auth: "user";
1964
2003
  readonly permission: null;
1965
- readonly query: readonly ["kind", "groups", "exclude_groups", "owner_group", "creators", "access", "tiers", "traits", "attribute", "released_on", "published_within", "tz", "view_status", "language", "display_language", "mode", "card_entities", "limit"];
2004
+ readonly query: readonly ["kind", "ids", "groups", "exclude_groups", "owner_group", "creators", "access", "tiers", "traits", "attribute", "released_on", "published_within", "tz", "view_status", "language", "display_language", "mode", "card_entities", "limit", "summary"];
1966
2005
  readonly request: null;
1967
2006
  readonly responses: {
1968
2007
  readonly 200: "ContentPage";
@@ -1975,7 +2014,7 @@ export declare const CONTENTKIT_ROUTES: readonly [{
1975
2014
  readonly path: "/release-dates";
1976
2015
  readonly auth: "public";
1977
2016
  readonly permission: null;
1978
- readonly query: readonly ["by", "kind", "groups", "exclude_groups", "owner_group", "creators", "access", "tiers", "traits", "attribute", "released_on", "published_within", "tz", "view_status", "language", "display_language", "mode", "cursor", "limit"];
2017
+ readonly query: readonly ["by", "kind", "ids", "groups", "exclude_groups", "owner_group", "creators", "access", "tiers", "traits", "attribute", "released_on", "published_within", "tz", "view_status", "language", "display_language", "mode", "cursor", "limit"];
1979
2018
  readonly request: null;
1980
2019
  readonly responses: {
1981
2020
  readonly 200: "ReleaseDates";
@@ -2027,7 +2066,7 @@ export declare const CONTENTKIT_ROUTES: readonly [{
2027
2066
  readonly path: "/me/history";
2028
2067
  readonly auth: "user";
2029
2068
  readonly permission: null;
2030
- readonly query: readonly ["kind", "status", "card_entities", "language", "display_language", "mode", "cursor", "limit"];
2069
+ readonly query: readonly ["kind", "status", "summary", "card_entities", "language", "display_language", "mode", "cursor", "limit"];
2031
2070
  readonly request: null;
2032
2071
  readonly responses: {
2033
2072
  readonly 200: "ContentPage";
@@ -2079,7 +2118,7 @@ export declare const CONTENTKIT_ROUTES: readonly [{
2079
2118
  readonly path: "/me/favorites";
2080
2119
  readonly auth: "user";
2081
2120
  readonly permission: null;
2082
- readonly query: readonly ["target", "kind", "card_entities", "cursor", "limit", "language", "display_language", "mode"];
2121
+ readonly query: readonly ["target", "kind", "card_entities", "cursor", "limit", "summary", "language", "display_language", "mode"];
2083
2122
  readonly request: null;
2084
2123
  readonly responses: {
2085
2124
  readonly 200: "InteractionPage";
@@ -2092,7 +2131,7 @@ export declare const CONTENTKIT_ROUTES: readonly [{
2092
2131
  readonly path: "/me/reactions";
2093
2132
  readonly auth: "user";
2094
2133
  readonly permission: null;
2095
- readonly query: readonly ["value", "target", "kind", "card_entities", "cursor", "limit", "language", "display_language", "mode"];
2134
+ readonly query: readonly ["value", "target", "kind", "card_entities", "cursor", "limit", "summary", "language", "display_language", "mode"];
2096
2135
  readonly request: null;
2097
2136
  readonly responses: {
2098
2137
  readonly 200: "InteractionPage";
@@ -2164,19 +2203,6 @@ export declare const CONTENTKIT_ROUTES: readonly [{
2164
2203
  };
2165
2204
  readonly errors: readonly ["not_configured"];
2166
2205
  readonly errorSets: readonly ["module:discovery", "auth", "request"];
2167
- }, {
2168
- readonly method: "GET";
2169
- readonly module: "discovery";
2170
- readonly path: "/stats/top";
2171
- readonly auth: "staff";
2172
- readonly permission: "root:content:view-restricted";
2173
- readonly query: readonly ["kind", "metric", "period", "access", "tiers", "language", "limit"];
2174
- readonly request: null;
2175
- readonly responses: {
2176
- readonly 200: "TopContents";
2177
- };
2178
- readonly errors: readonly ["not_configured"];
2179
- readonly errorSets: readonly ["module:discovery", "auth", "request"];
2180
2206
  }, {
2181
2207
  readonly method: "GET";
2182
2208
  readonly module: "discovery";
@@ -2190,6 +2216,19 @@ export declare const CONTENTKIT_ROUTES: readonly [{
2190
2216
  };
2191
2217
  readonly errors: readonly [];
2192
2218
  readonly errorSets: readonly ["module:discovery", "auth"];
2219
+ }, {
2220
+ readonly method: "GET";
2221
+ readonly module: "discovery";
2222
+ readonly path: "/manage/search-suggestions";
2223
+ readonly auth: "public";
2224
+ readonly permission: null;
2225
+ readonly query: readonly ["q", "content_kinds", "entity_kinds", "include_contents", "include_entities", "display_language", "limit"];
2226
+ readonly request: null;
2227
+ readonly responses: {
2228
+ readonly 200: "Typeahead";
2229
+ };
2230
+ readonly errors: readonly ["unauthorized", "forbidden", "unavailable"];
2231
+ readonly errorSets: readonly ["module:discovery", "auth", "request"];
2193
2232
  }, {
2194
2233
  readonly method: "POST";
2195
2234
  readonly module: "import";