@openrails/contentkit-ui 0.103.1 → 0.104.0-rc.1

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 (145) hide show
  1. package/README.md +105 -43
  2. package/dist/client/beacons.d.ts +3 -13
  3. package/dist/client/beacons.js +4 -45
  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/discovery.d.ts +28 -3
  13. package/dist/client/discovery.js +22 -1
  14. package/dist/client/discovery.js.map +1 -1
  15. package/dist/client/engagement.d.ts +70 -0
  16. package/dist/client/engagement.js +191 -0
  17. package/dist/client/engagement.js.map +1 -0
  18. package/dist/client/generated/routes.d.ts +35 -9
  19. package/dist/client/generated/routes.js +59 -2
  20. package/dist/client/generated/routes.js.map +1 -1
  21. package/dist/client/generated/wire.d.ts +53 -12
  22. package/dist/client/generated/wire.js.map +1 -1
  23. package/dist/client/guest-reading-history.d.ts +40 -0
  24. package/dist/client/guest-reading-history.js +144 -0
  25. package/dist/client/guest-reading-history.js.map +1 -0
  26. package/dist/client/index.d.ts +4 -2
  27. package/dist/client/stats.d.ts +5 -5
  28. package/dist/client/stats.js.map +1 -1
  29. package/dist/client.js +24 -22
  30. package/dist/components/admin/content-manager.d.ts +1 -1
  31. package/dist/components/admin/content-manager.js +342 -302
  32. package/dist/components/admin/content-manager.js.map +1 -1
  33. package/dist/components/admin/page-review.js +106 -97
  34. package/dist/components/admin/page-review.js.map +1 -1
  35. package/dist/components/admin/quick-search.d.ts +14 -0
  36. package/dist/components/admin/quick-search.js +60 -0
  37. package/dist/components/admin/quick-search.js.map +1 -0
  38. package/dist/components/admin/reader-content-editor.d.ts +6 -0
  39. package/dist/components/admin/reader-content-editor.js +733 -0
  40. package/dist/components/admin/reader-content-editor.js.map +1 -0
  41. package/dist/components/admin/reader-manifest.js +120 -105
  42. package/dist/components/admin/reader-manifest.js.map +1 -1
  43. package/dist/components/admin/stats-dashboard.d.ts +4 -4
  44. package/dist/components/admin/stats-dashboard.js +132 -134
  45. package/dist/components/admin/stats-dashboard.js.map +1 -1
  46. package/dist/components/content/daily-releases.js +143 -191
  47. package/dist/components/content/daily-releases.js.map +1 -1
  48. package/dist/components/content/editor-save.d.ts +32 -0
  49. package/dist/components/content/editor-save.js +51 -0
  50. package/dist/components/content/editor-save.js.map +1 -0
  51. package/dist/components/content/editors.d.ts +17 -2
  52. package/dist/components/content/editors.js +359 -328
  53. package/dist/components/content/editors.js.map +1 -1
  54. package/dist/components/content/favorites.d.ts +6 -0
  55. package/dist/components/content/favorites.js +33 -0
  56. package/dist/components/content/favorites.js.map +1 -0
  57. package/dist/components/content/filter-dialog.js +19 -15
  58. package/dist/components/content/filter-dialog.js.map +1 -1
  59. package/dist/components/content/filters.d.ts +2 -0
  60. package/dist/components/content/filters.js +5 -1
  61. package/dist/components/content/filters.js.map +1 -1
  62. package/dist/components/content/grid.d.ts +34 -13
  63. package/dist/components/content/grid.js +300 -271
  64. package/dist/components/content/grid.js.map +1 -1
  65. package/dist/components/content/history.d.ts +6 -0
  66. package/dist/components/content/history.js +91 -0
  67. package/dist/components/content/history.js.map +1 -0
  68. package/dist/components/content/index.d.ts +1 -0
  69. package/dist/components/content/offer-fields.d.ts +1 -1
  70. package/dist/components/content/offer-fields.js +86 -64
  71. package/dist/components/content/offer-fields.js.map +1 -1
  72. package/dist/components/content/search.d.ts +11 -4
  73. package/dist/components/content/search.js +22 -11
  74. package/dist/components/content/search.js.map +1 -1
  75. package/dist/components/content/summary-tile.d.ts +14 -0
  76. package/dist/components/content/summary-tile.js +63 -0
  77. package/dist/components/content/summary-tile.js.map +1 -0
  78. package/dist/components/groups/memberships.d.ts +11 -1
  79. package/dist/components/groups/memberships.js +1 -1
  80. package/dist/components/groups/memberships.js.map +1 -1
  81. package/dist/components/media-folder-editor.d.ts +4 -0
  82. package/dist/components/media-folder-editor.js +178 -168
  83. package/dist/components/media-folder-editor.js.map +1 -1
  84. package/dist/components/video-mini-player.d.ts +4 -1
  85. package/dist/components/video-mini-player.js +77 -71
  86. package/dist/components/video-mini-player.js.map +1 -1
  87. package/dist/components/video-player.d.ts +4 -1
  88. package/dist/components/video-player.js +280 -276
  89. package/dist/components/video-player.js.map +1 -1
  90. package/dist/index.d.ts +1 -0
  91. package/dist/index.js +17 -14
  92. package/dist/locales/admin/de.js +33 -8
  93. package/dist/locales/admin/de.js.map +1 -1
  94. package/dist/locales/admin/en.d.ts +29 -4
  95. package/dist/locales/admin/en.js +33 -8
  96. package/dist/locales/admin/en.js.map +1 -1
  97. package/dist/locales/admin/es.js +33 -8
  98. package/dist/locales/admin/es.js.map +1 -1
  99. package/dist/locales/admin/ja.js +33 -8
  100. package/dist/locales/admin/ja.js.map +1 -1
  101. package/dist/locales/admin/ko.js +33 -8
  102. package/dist/locales/admin/ko.js.map +1 -1
  103. package/dist/locales/admin/zh.js +33 -8
  104. package/dist/locales/admin/zh.js.map +1 -1
  105. package/dist/locales/discovery/de.js +0 -1
  106. package/dist/locales/discovery/de.js.map +1 -1
  107. package/dist/locales/discovery/en.d.ts +0 -1
  108. package/dist/locales/discovery/en.js +0 -1
  109. package/dist/locales/discovery/en.js.map +1 -1
  110. package/dist/locales/discovery/es.js +0 -1
  111. package/dist/locales/discovery/es.js.map +1 -1
  112. package/dist/locales/discovery/ja.js +0 -1
  113. package/dist/locales/discovery/ja.js.map +1 -1
  114. package/dist/locales/discovery/ko.js +0 -1
  115. package/dist/locales/discovery/ko.js.map +1 -1
  116. package/dist/locales/discovery/zh.js +0 -1
  117. package/dist/locales/discovery/zh.js.map +1 -1
  118. package/dist/locales/en.d.ts +29 -5
  119. package/dist/react/discovery.d.ts +20 -17
  120. package/dist/react/discovery.js +273 -221
  121. package/dist/react/discovery.js.map +1 -1
  122. package/dist/react/index.d.ts +2 -1
  123. package/dist/react/page-review.d.ts +1 -1
  124. package/dist/react/page-review.js +6 -5
  125. package/dist/react/page-review.js.map +1 -1
  126. package/dist/react/resources.d.ts +3 -1
  127. package/dist/react/resources.js +4 -0
  128. package/dist/react/resources.js.map +1 -1
  129. package/dist/react/stats.d.ts +2 -2
  130. package/dist/react/stats.js.map +1 -1
  131. package/dist/react/use-draft.d.ts +8 -0
  132. package/dist/react/use-draft.js +35 -0
  133. package/dist/react/use-draft.js.map +1 -0
  134. package/dist/react/use-engagement.d.ts +26 -0
  135. package/dist/react/use-engagement.js +221 -0
  136. package/dist/react/use-engagement.js.map +1 -0
  137. package/dist/react/use-resource.d.ts +4 -3
  138. package/dist/react/use-resource.js +2 -1
  139. package/dist/react/use-resource.js.map +1 -1
  140. package/dist/react.js +12 -11
  141. package/dist/styles.css +1 -1
  142. package/dist/ui/dialog.d.ts +2 -1
  143. package/dist/ui/dialog.js +23 -20
  144. package/dist/ui/dialog.js.map +1 -1
  145. package/package.json +1 -1
@@ -33,8 +33,8 @@ export interface ActivityContextsInput {
33
33
  }
34
34
  export interface ActivityDay {
35
35
  date: string;
36
- views: number;
37
- viewers: number;
36
+ readers: number;
37
+ active_ms: number;
38
38
  users: number;
39
39
  }
40
40
  export interface ActivityTarget {
@@ -170,6 +170,7 @@ export interface Batch {
170
170
  polls?: PollRecord[];
171
171
  votes?: VoteRecord[];
172
172
  answers?: AnswerRecord[];
173
+ legacy_reading?: LegacyReadingRecord[];
173
174
  signals?: SignalRecord[];
174
175
  deletes?: DeleteRecord[];
175
176
  }
@@ -344,7 +345,6 @@ export interface Content {
344
345
  creators: Creator[];
345
346
  entities: GroupSummary[];
346
347
  versions: Version[];
347
- views?: number;
348
348
  viewer?: ViewerState;
349
349
  editor: boolean;
350
350
  text?: Record<string, CatalogText>;
@@ -408,6 +408,7 @@ export interface ContentModel {
408
408
  }
409
409
  export interface ContentPage {
410
410
  contents: Card[];
411
+ summary?: ListingSummary;
411
412
  next_cursor?: string;
412
413
  ranking?: RankingInfo;
413
414
  }
@@ -435,7 +436,6 @@ export interface ContentRecord {
435
436
  deleted_at?: string;
436
437
  listing?: string;
437
438
  comments?: string;
438
- view_baseline?: number;
439
439
  access?: Rule;
440
440
  restrictions?: string[];
441
441
  attributes?: Record<string, unknown>;
@@ -480,7 +480,10 @@ export interface Counts {
480
480
  likes?: number;
481
481
  dislikes?: number;
482
482
  favorites?: number;
483
- views?: number;
483
+ }
484
+ export interface CoverageRange {
485
+ from: number;
486
+ to: number;
484
487
  }
485
488
  export interface Creator {
486
489
  user_id: string;
@@ -554,6 +557,22 @@ export interface EncodeProgress {
554
557
  stage?: number;
555
558
  stages?: number;
556
559
  }
560
+ export interface EngagementBatch {
561
+ session?: string;
562
+ snapshots: EngagementSnapshot[];
563
+ }
564
+ export interface EngagementSnapshot {
565
+ content_id: string;
566
+ version_id?: string;
567
+ visit_id: string;
568
+ segment_id: string;
569
+ revision: number;
570
+ activity_token: string;
571
+ active_ms: number;
572
+ resume?: string;
573
+ pages?: PageEngagement[];
574
+ watched?: WatchedRange[];
575
+ }
557
576
  export interface EntityReference {
558
577
  id?: string;
559
578
  kind?: string;
@@ -950,6 +969,7 @@ export interface Interaction {
950
969
  export interface InteractionPage {
951
970
  items: Interaction[];
952
971
  next_cursor?: string;
972
+ summary?: ListingSummary;
953
973
  }
954
974
  export interface Item {
955
975
  id: string;
@@ -985,6 +1005,18 @@ export interface LanguageTotal {
985
1005
  public: number;
986
1006
  tiers: Record<string, number>;
987
1007
  }
1008
+ export interface LegacyReadingRecord {
1009
+ target: TargetRef;
1010
+ user_id?: string;
1011
+ anon_key?: string;
1012
+ first_read_at?: string;
1013
+ last_read_at: string;
1014
+ progress: number;
1015
+ progress_max: number;
1016
+ completed: boolean;
1017
+ resume?: string;
1018
+ revision?: number;
1019
+ }
988
1020
  export interface LibraryItem {
989
1021
  content_id: string;
990
1022
  kind: string;
@@ -999,6 +1031,12 @@ export interface LibraryPage {
999
1031
  next_cursor?: string;
1000
1032
  complete: boolean;
1001
1033
  }
1034
+ export interface ListingSummary {
1035
+ filtered_count: number;
1036
+ filtered_entities: ReleaseFilteredEntity[];
1037
+ locked_count: number;
1038
+ truncated?: boolean;
1039
+ }
1002
1040
  export interface Locked {
1003
1041
  show: string[];
1004
1042
  preview?: Preview;
@@ -1201,6 +1239,11 @@ export interface PageDecision {
1201
1239
  confidence: string;
1202
1240
  related?: string[];
1203
1241
  }
1242
+ export interface PageEngagement {
1243
+ index: number;
1244
+ ranges: CoverageRange[];
1245
+ active_ms: number;
1246
+ }
1204
1247
  export interface PageReview {
1205
1248
  revision: string;
1206
1249
  pages: PageReviewEntry[];
@@ -1635,9 +1678,6 @@ export interface SignalInput {
1635
1678
  event_id: string;
1636
1679
  revision?: number;
1637
1680
  occurred_at: string;
1638
- duration_s?: number;
1639
- progress?: number;
1640
- resume?: string;
1641
1681
  render_id?: string;
1642
1682
  surface?: string;
1643
1683
  position?: number;
@@ -1651,9 +1691,6 @@ export interface SignalRecord {
1651
1691
  event_id: string;
1652
1692
  revision?: number;
1653
1693
  occurred_at: string;
1654
- duration_s?: number;
1655
- progress?: number;
1656
- resume?: string;
1657
1694
  }
1658
1695
  export interface Signals {
1659
1696
  session?: string;
@@ -1830,7 +1867,7 @@ export interface ViewerState {
1830
1867
  progress: number;
1831
1868
  progress_max: number;
1832
1869
  resume?: string;
1833
- last_view_at?: string;
1870
+ last_read_at?: string;
1834
1871
  }
1835
1872
  export interface VoteRecord {
1836
1873
  poll: Ref;
@@ -1839,6 +1876,10 @@ export interface VoteRecord {
1839
1876
  ip?: string;
1840
1877
  created_at?: string;
1841
1878
  }
1879
+ export interface WatchedRange {
1880
+ from_ms: number;
1881
+ to_ms: number;
1882
+ }
1842
1883
  export interface Written {
1843
1884
  count: number;
1844
1885
  }
@@ -1 +1 @@
1
- {"version":3,"file":"wire.js","names":[],"sources":["../../../src/client/generated/wire.ts"],"sourcesContent":["// Generated by `go generate ./internal/contract` from ContentKit's route catalog. Do not edit.\n\nimport type { ErrorCode } from \"./error-codes.js\";\n\nexport type { ErrorCode };\n\n// Upload sizes: one PUT up to MAX_SINGLE_PUT bytes, else multipart parts.\nexport const MAX_SINGLE_PUT = 67108864;\nexport const MIN_PART_SIZE = 8388608;\nexport const MAX_PART_SIZE = 16777216;\n\nexport type OpName = \"put\" | \"edit\" | \"move\" | \"rename\" | \"remove\" | \"attach\" | \"copy\" | \"frame\" | \"meta\" | \"regenerate\";\nexport type Access = \"full\" | \"none\";\nexport type ItemState = \"ready\" | \"processing\" | \"failed\";\nexport type EncodePhase = \"queued\" | \"downloading\" | \"probing\" | \"encoding\" | \"muxing\" | \"uploading\" | \"publishing\" | \"images\";\nexport type PollKind = \"multiple_choice\" | \"free_text\";\nexport type ModerationState = \"approved\" | \"held\" | \"rejected\";\nexport type ContentState = \"draft\" | \"published\" | \"deleted\";\nexport type VersionState = \"draft\" | \"published\";\nexport type Listing = \"listed\" | \"members\" | \"unlisted\";\nexport type AliasStatus = \"found\" | \"not_found\" | \"gone\";\n\nexport interface Activity {\n days: ActivityDay[];\n}\n\nexport interface ActivityContext {\n content_id: string;\n version_id?: string;\n token: string;\n occurred_at: string;\n}\n\nexport interface ActivityContexts {\n enabled: boolean;\n contexts: ActivityContext[];\n}\n\nexport interface ActivityContextsInput {\n session?: string;\n language?: string;\n targets: ActivityTarget[];\n}\n\nexport interface ActivityDay {\n date: string;\n views: number;\n viewers: number;\n users: number;\n}\n\nexport interface ActivityTarget {\n content_id: string;\n version_id?: string;\n}\n\nexport interface AdminComment {\n id: string;\n reply_to_id?: string;\n user_id?: string;\n anon_name?: string;\n language?: string;\n body: string;\n deleted: boolean;\n likes: number;\n dislikes: number;\n mine: number;\n reply_count: number;\n author?: PublicUser;\n moderation?: ModerationState;\n moderation_reason?: string;\n created_at: string;\n updated_at: string;\n tenant_id: string;\n content_kind: string;\n content_id: string;\n content_version_id?: string;\n deleted_at?: string;\n}\n\nexport interface AliasKey {\n source: string;\n kind: string;\n key: string;\n}\n\nexport interface AliasLookup {\n aliases: AliasKey[];\n}\n\nexport interface AliasRecord {\n kind: string;\n key: string;\n locator?: string;\n target: TargetRef;\n}\n\nexport interface AliasResult {\n source: string;\n kind: string;\n key: string;\n status: AliasStatus;\n resolved?: Resolved;\n locator?: string;\n}\n\nexport interface AliasResults {\n aliases: AliasResult[];\n}\n\nexport interface Anchor {\n id: string;\n page: string;\n offset_percent: number;\n duration_seconds?: number;\n}\n\nexport interface Anonymous {\n comments: boolean;\n reactions: boolean;\n votes: boolean;\n}\n\nexport interface AnswerGroup {\n id: string;\n label: string;\n count: number;\n}\n\nexport interface AnswerRecord {\n poll: Ref;\n user_id: string;\n text: string;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface Archive {\n name: string;\n size: number;\n sha256: string;\n}\n\nexport interface Attribute {\n type: string;\n values?: string[];\n filterable?: boolean;\n sortable?: boolean;\n}\n\nexport interface Avatar {\n image?: string;\n renditions?: Rendition[];\n}\n\nexport interface BackgroundCue {\n file: string;\n from_page?: string;\n to_page?: string;\n from_anchor?: string;\n to_anchor?: string;\n loop?: boolean;\n layer?: string;\n}\n\nexport interface BanInput {\n reason?: string;\n until?: string;\n}\n\nexport interface BanNotice {\n scope: string;\n reason?: string;\n until?: string;\n}\n\nexport interface BannedWord {\n word: string;\n action: \"mask\" | \"reject\";\n created_by: string;\n created_at: string;\n}\n\nexport interface BannedWordInput {\n word: string;\n action?: \"mask\" | \"reject\";\n}\n\nexport interface Batch {\n source: string;\n preference_floor?: number;\n provision_scopes?: boolean;\n entities?: GroupRecord[];\n contents?: ContentRecord[];\n memberships?: MembershipSet[];\n offers?: OfferRecord[];\n aliases?: AliasRecord[];\n comments?: CommentRecord[];\n reactions?: ReactionRecord[];\n favorites?: FavoriteRecord[];\n polls?: PollRecord[];\n votes?: VoteRecord[];\n answers?: AnswerRecord[];\n signals?: SignalRecord[];\n deletes?: DeleteRecord[];\n}\n\nexport interface BodyImageInput {\n image?: string;\n version: string;\n}\n\nexport interface Card {\n id: string;\n kind: string;\n code: string;\n path: string;\n title: string;\n language: string;\n cover: PublicRendition[];\n version: CardVersion;\n entities: Record<string, Chip[]>;\n owner?: GroupCard;\n counts: Counts;\n access: CardAccess;\n viewer?: ViewerState;\n published_at?: string;\n attributes: Record<string, unknown>;\n ranking?: ContentRanking;\n}\n\nexport interface CardAccess {\n allowed: boolean;\n level: \"group\" | \"group_ppv\" | \"ppv\" | \"public\" | \"tier\";\n tiers?: string[];\n unknown?: boolean;\n sell?: string[];\n requires?: string;\n preview?: Preview;\n free_after?: string;\n offers?: Sale[];\n}\n\nexport interface CardVersion {\n id: string;\n code: string;\n languages: string[];\n traits: string[];\n label?: string;\n pages?: number;\n duration_ms?: number;\n has_audio: boolean;\n hls?: string;\n}\n\nexport interface CatalogCover {\n image?: string;\n url?: string;\n renditions?: PublicRendition[];\n}\n\nexport interface CatalogText {\n title: string;\n slug?: string;\n description?: string;\n body?: string;\n sort_key?: string;\n aliases?: string[];\n}\n\nexport interface Chip {\n id: string;\n slug: string;\n name: string;\n path?: string;\n position?: number;\n}\n\nexport interface Comment {\n id: string;\n reply_to_id?: string;\n user_id?: string;\n anon_name?: string;\n language?: string;\n body: string;\n deleted: boolean;\n likes: number;\n dislikes: number;\n mine: number;\n reply_count: number;\n author?: PublicUser;\n moderation?: ModerationState;\n moderation_reason?: string;\n created_at: string;\n updated_at: string;\n}\n\nexport interface CommentBan {\n user_id: string;\n user?: PublicUser;\n scope: string;\n reason?: string;\n until?: string;\n banned_by: string;\n banned_at: string;\n expired: boolean;\n}\n\nexport interface CommentEdit {\n body: string;\n}\n\nexport interface CommentInput {\n body: string;\n reply_to_id?: string;\n anon_name?: string;\n language?: string;\n}\n\nexport interface CommentRecord {\n external_id: string;\n id?: string;\n target: TargetRef;\n language?: string;\n reply_to?: Ref;\n user_id?: string;\n anon_name?: string;\n body: string;\n deleted_at?: string;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface CommentStanding {\n can_comment: boolean;\n comments: string;\n count?: number;\n locked: boolean;\n ban?: BanNotice;\n anonymous: boolean;\n max_length: number;\n user_id?: string;\n moderate: boolean;\n ban_scopes: (\"global\" | \"owner\")[];\n}\n\nexport interface CommitBody {\n ref: RefBody;\n operation_id: string;\n ops: Op[];\n}\n\nexport interface CommitReply {\n files: FileInfo[];\n}\n\nexport interface CompleteReply {\n blob: string;\n type: string;\n size: number;\n}\n\nexport type CompleteRequest = Record<string, never>;\n\nexport interface Config {\n anonymous: Anonymous;\n comment_max_length: number;\n}\n\nexport interface Content {\n id: string;\n kind: string;\n code: string;\n path: string;\n language: string;\n title: string;\n slug?: string;\n description?: string;\n body?: string;\n decision: Decision;\n images?: Record<string, string>;\n cover?: CatalogCover;\n state: ContentState;\n listing: Listing;\n comments: string;\n publish_at?: string;\n published_at?: string;\n live: boolean;\n access: Rule;\n restrictions: string[];\n attributes: Record<string, unknown>;\n owner_group_id?: string;\n owner?: GroupCard;\n creators: Creator[];\n entities: GroupSummary[];\n versions: Version[];\n views?: number;\n viewer?: ViewerState;\n editor: boolean;\n text?: Record<string, CatalogText>;\n moderation?: ModerationState;\n moderation_reason?: string;\n ever_sold?: boolean;\n offer?: Offer;\n revision: number;\n created_at: string;\n updated_at: string;\n deleted_at?: string;\n}\n\nexport interface ContentFilterState {\n entity: GroupCard;\n default_visible: boolean;\n visible: boolean;\n overridden: boolean;\n}\n\nexport interface ContentFilters {\n applies_to: string[];\n filters: ContentFilterState[];\n include_deleted: boolean;\n}\n\nexport interface ContentFiltersInitialization {\n account_id: string;\n filters: GuestFilterSetting[];\n include_deleted: boolean;\n}\n\nexport interface ContentFiltersUpdate {\n filters?: GuestFilterSetting[];\n include_deleted?: boolean;\n}\n\nexport interface ContentGroups {\n kinds?: string[];\n memberships: Membership[];\n}\n\nexport interface ContentInput {\n kind: string;\n text?: Record<string, CatalogText>;\n listing?: Listing;\n comments?: string;\n access?: Rule;\n restrictions?: string[];\n attributes?: Record<string, unknown>;\n owner_group_id?: string;\n creators?: Creator[];\n versions?: VersionInput[];\n}\n\nexport interface ContentMemberships {\n content_id: string;\n memberships: Membership[];\n entities: GroupCard[];\n}\n\nexport interface ContentModel {\n languages: string[];\n tiers: string[];\n kinds: Record<string, Kind>;\n entity_kinds: Record<string, GroupKind>;\n signals: boolean;\n avatars?: PresetRule;\n}\n\nexport interface ContentPage {\n contents: Card[];\n next_cursor?: string;\n ranking?: RankingInfo;\n}\n\nexport interface ContentPatch {\n listing?: Listing;\n comments?: string;\n access?: Rule;\n restrictions?: string[];\n attributes?: Record<string, unknown>;\n creators?: Creator[];\n revision?: number;\n}\n\nexport interface ContentRanking {\n score: number;\n participation: number;\n adjusted_participation: number;\n}\n\nexport interface ContentRecord {\n external_id: string;\n id?: string;\n kind: string;\n state: string;\n publish_at?: string;\n published_at?: string;\n deleted_at?: string;\n listing?: string;\n comments?: string;\n view_baseline?: number;\n access?: Rule;\n restrictions?: string[];\n attributes?: Record<string, unknown>;\n owner_group?: Ref;\n creators?: Creator[];\n text?: Record<string, CatalogText>;\n versions?: VersionRecord[];\n code?: string;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface ContentRef {\n tenant_id: string;\n content_kind: string;\n content_id: string;\n content_version_id?: string;\n}\n\nexport interface CopyBody {\n ref: RefBody;\n files: CopyRequest[];\n}\n\nexport interface CopyFrom {\n id: string;\n version?: string;\n path: string;\n}\n\nexport interface CopyReply {\n files: StagedCopy[];\n}\n\nexport interface CopyRequest {\n path: string;\n type: string;\n from: string;\n size?: number;\n}\n\nexport interface Count {\n content_kind: string;\n language: string;\n count: number;\n}\n\nexport interface Counts {\n likes?: number;\n dislikes?: number;\n favorites?: number;\n views?: number;\n}\n\nexport interface Creator {\n user_id: string;\n role?: string;\n position: number;\n}\n\nexport interface CreatorsInput {\n creators: Creator[];\n}\n\nexport interface Crop {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport interface DailyReleases {\n time_zone: string;\n from_date: string;\n through_date: string;\n days: ReleaseDay[];\n}\n\nexport interface DateCount {\n date: string;\n count: number;\n free: number;\n}\n\nexport interface Decision {\n allowed: boolean;\n unknown?: boolean;\n sell?: string[];\n requires?: string;\n preview?: Preview;\n free_after?: string;\n offers?: Sale[];\n}\n\nexport interface DeleteRecord {\n entity: string;\n external_id: string;\n}\n\nexport interface Download {\n off?: boolean;\n serve?: string;\n}\n\nexport interface Edge {\n from: string;\n relation: string;\n to: string;\n}\n\nexport interface EdgeInput {\n relation: string;\n to: string;\n}\n\nexport interface EdgeRecord {\n relation: string;\n to: Ref;\n}\n\nexport interface Edit {\n crop?: Crop;\n rotate?: number;\n}\n\nexport interface EncodeProgress {\n phase: EncodePhase;\n queue_position?: number;\n segments_done?: number;\n segments_total?: number;\n percent: number;\n speed?: number;\n eta?: number;\n at: number;\n stalled?: boolean;\n stage?: number;\n stages?: number;\n}\n\nexport interface EntityReference {\n id?: string;\n kind?: string;\n name?: string;\n language?: string;\n scope?: EntityReference;\n}\n\nexport interface EntityResolution {\n id: string;\n kind: string;\n name: string;\n created: boolean;\n scope?: EntityResolution;\n}\n\nexport interface ErrorDetails {\n width?: number;\n height?: number;\n min_width?: number;\n max_pixels?: number;\n type?: string;\n allowed?: string[];\n size?: number;\n max_bytes?: number;\n frames?: number;\n max_frames?: number;\n seconds?: number;\n max_seconds?: number;\n min_aspect?: number;\n max_aspect?: number;\n max?: number;\n}\n\nexport interface ErrorReply {\n error: string;\n code: ErrorCode;\n retry_after?: number;\n action?: \"comment\" | \"comment_reaction\" | \"favorite\" | \"poll_vote\" | \"reaction\";\n ban?: BanNotice;\n blobs?: string[];\n details?: ErrorDetails;\n reason?: string;\n available_at?: string;\n}\n\nexport interface ExposureInput {\n render_id: string;\n stage: string;\n revision?: number;\n query_id?: string;\n surface?: string;\n ranker?: string;\n language?: string;\n occurred_at?: string;\n shown: Placement[];\n}\n\nexport interface Exposures {\n session?: string;\n exposures: ExposureInput[];\n}\n\nexport interface ExternalID {\n external_id: string;\n id: string;\n deleted: boolean;\n}\n\nexport interface ExternalIDList {\n entity: string;\n cursor?: string;\n limit?: number;\n}\n\nexport interface ExternalIDPage {\n entity: string;\n ids: ExternalID[];\n next_cursor?: string;\n}\n\nexport interface ExternalIDs {\n lists: ExternalIDPage[];\n}\n\nexport interface ExternalIDsQuery {\n source: string;\n lists: ExternalIDList[];\n}\n\nexport interface Failure {\n of: string;\n message: string;\n code?: ErrorCode;\n details?: ErrorDetails;\n}\n\nexport interface FavoriteRecord {\n target: TargetRef;\n user_id: string;\n created_at?: string;\n}\n\nexport interface FavoriteState {\n favorited: boolean;\n count?: number;\n}\n\nexport interface FeedItem {\n id: string;\n reply_to_id?: string;\n user_id?: string;\n anon_name?: string;\n language?: string;\n body: string;\n deleted: boolean;\n likes: number;\n dislikes: number;\n mine: number;\n reply_count: number;\n author?: PublicUser;\n moderation?: ModerationState;\n moderation_reason?: string;\n created_at: string;\n updated_at: string;\n tenant_id: string;\n content_kind: string;\n content_id: string;\n content_version_id?: string;\n}\n\nexport interface FileDownload {\n url: string;\n name: string;\n type: string;\n size?: number;\n expires_at: string;\n}\n\nexport interface FileInfo {\n path: string;\n type: string;\n size?: number;\n w?: number;\n h?: number;\n dur?: number;\n download?: string;\n url?: string;\n create_id?: string;\n upload?: boolean;\n staged?: boolean;\n from?: string;\n edit?: Edit;\n frame?: Frame;\n meta?: Record<string, unknown>;\n unattached?: boolean;\n pending?: string[];\n failed?: Failure;\n editor_url?: string;\n progress?: EncodeProgress;\n}\n\nexport interface ForegroundCue {\n file: string;\n page?: string;\n anchor?: string;\n}\n\nexport interface ForkBody {\n from: string;\n playback?: boolean;\n segments?: boolean;\n}\n\nexport interface Frame {\n t?: number;\n auto?: boolean;\n of?: string;\n}\n\nexport interface Group {\n id: string;\n kind: string;\n slug: string;\n internal: boolean;\n scope_id?: string;\n parent_id?: string;\n state: \"active\" | \"deleted\" | \"merged\";\n merged_into?: string;\n attributes: Record<string, unknown>;\n cover?: GroupsCover;\n avatar?: Avatar;\n owner_user_id?: string;\n auth_scope?: string;\n created_at: string;\n updated_at: string;\n revision: number;\n}\n\nexport interface GroupAccess {\n key: string;\n offer?: Sale;\n member: boolean;\n editor?: boolean;\n unknown?: boolean;\n}\n\nexport interface GroupCard {\n id: string;\n kind: string;\n slug: string;\n internal: boolean;\n scope_id?: string;\n parent_id?: string;\n name: string;\n name_language?: string;\n code?: string;\n path?: string;\n cover?: GroupsCover;\n avatar?: Avatar;\n count: number;\n attributes: Record<string, unknown>;\n access?: GroupAccess;\n created_at: string;\n}\n\nexport interface GroupDetail {\n id: string;\n kind: string;\n slug: string;\n internal: boolean;\n scope_id?: string;\n parent_id?: string;\n state: \"active\" | \"deleted\" | \"merged\";\n merged_into?: string;\n attributes: Record<string, unknown>;\n cover?: GroupsCover;\n avatar?: Avatar;\n owner_user_id?: string;\n auth_scope?: string;\n created_at: string;\n updated_at: string;\n revision: number;\n name: string;\n name_language?: string;\n code?: string;\n path?: string;\n names: Name[];\n text: GroupsText[];\n parent?: GroupCard;\n scope?: GroupCard;\n children: GroupCard[];\n edges: Edge[];\n counts: Count[];\n access?: GroupAccess;\n offer?: Offer;\n}\n\nexport interface GroupInput {\n id?: string;\n kind: string;\n slug: string;\n internal?: boolean;\n scope_id?: string;\n parent_id?: string;\n attributes?: Record<string, unknown>;\n cover?: GroupsCover;\n avatar?: Avatar;\n owner_user_id?: string;\n auth_scope?: string;\n names?: Name[];\n text?: GroupsText[];\n}\n\nexport interface GroupJoin {\n group_id: string;\n key: string;\n member: boolean;\n}\n\nexport interface GroupKind {\n route?: string;\n ordered?: boolean;\n parent?: string;\n scoped_by?: string;\n owner?: string;\n max_per_owner?: number;\n uploads?: UploadLimits;\n sellable?: boolean;\n auth_scope?: boolean;\n windows?: boolean;\n version_level?: boolean;\n roles?: string[];\n attributes?: Record<string, Attribute>;\n}\n\nexport interface GroupPage {\n entities: GroupCard[];\n next_cursor?: string;\n}\n\nexport interface GroupRecord {\n external_id: string;\n id?: string;\n kind: string;\n slug: string;\n internal?: boolean;\n scope?: Ref;\n parent?: Ref;\n state?: string;\n names?: Name[];\n text?: GroupsText[];\n attributes?: Record<string, unknown>;\n cover_image?: string;\n cover_content?: Ref;\n avatar?: string;\n owner_user_id?: string;\n auth_scope?: string;\n edges?: EdgeRecord[];\n code?: string;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface GroupSummary {\n id: string;\n kind: string;\n slug: string;\n name: string;\n code?: string;\n path?: string;\n}\n\nexport interface GroupUpdate {\n slug?: string;\n internal?: boolean;\n scope_id?: string;\n parent_id?: string;\n state?: \"active\" | \"deleted\" | \"merged\";\n attributes?: Record<string, unknown>;\n cover?: GroupsCover;\n avatar?: Avatar;\n owner_user_id?: string;\n auth_scope?: string;\n names?: Name[];\n text?: GroupsText[];\n}\n\nexport interface GroupsCover {\n image?: string;\n content_id?: string;\n auto?: boolean;\n renditions?: Rendition[];\n}\n\nexport interface GroupsText {\n language: string;\n description?: string;\n sort_key?: string;\n}\n\nexport interface GuestFilterSetting {\n entity_id: string;\n visible?: boolean;\n default?: boolean;\n}\n\nexport interface HeldItem {\n kind: string;\n revision: number;\n id: string;\n ref: ContentRef;\n author_id?: string;\n author?: PublicUser;\n anon_name?: string;\n title?: string;\n body: string;\n reason: string;\n model?: string;\n prompt_version?: string;\n confidence?: number;\n error?: string;\n held_at: string;\n created_at: string;\n}\n\nexport interface HeldPage {\n items: HeldItem[];\n next?: string;\n}\n\nexport interface IPBan {\n network: string;\n reason?: string;\n until?: string;\n banned_by: string;\n banned_at: string;\n expired: boolean;\n}\n\nexport interface IPBanInput {\n network: string;\n reason?: string;\n until?: string;\n}\n\nexport interface ImageInput {\n image?: string;\n}\n\nexport interface InlineImage {\n ref: string;\n url: string | null;\n}\n\nexport interface Input {\n recipient: Recipient;\n origin: Origin;\n kind: string;\n data: unknown;\n created_at: string;\n visibility?: string;\n app_id?: string;\n status?: string;\n action_requested?: boolean;\n severity?: string;\n}\n\nexport interface Interaction {\n content?: Card;\n entity?: GroupCard;\n value: number;\n at: string;\n}\n\nexport interface InteractionPage {\n items: Interaction[];\n next_cursor?: string;\n}\n\nexport interface Item {\n id: string;\n recipient: Recipient;\n origin: Origin;\n kind: string;\n data: unknown;\n created_at: string;\n visibility?: string;\n app_id?: string;\n status?: string;\n action_requested?: boolean;\n severity?: string;\n read_at: string | null;\n dismissed_at: string | null;\n resolved_at: string | null;\n updated_at: string;\n revision: number;\n}\n\nexport interface Kind {\n route: string;\n presentation: string;\n versions: VersionRules;\n segments?: boolean;\n entities?: string[];\n attributes?: Record<string, Attribute>;\n sort?: string;\n locked?: Locked;\n draft_ttl?: number;\n download?: Download;\n}\n\nexport interface LanguageTotal {\n public: number;\n tiers: Record<string, number>;\n}\n\nexport interface LibraryItem {\n content_id: string;\n kind: string;\n title: string;\n language?: string;\n deleted: boolean;\n whole: boolean;\n version_ids: string[];\n}\n\nexport interface LibraryPage {\n items: LibraryItem[];\n next_cursor?: string;\n complete: boolean;\n}\n\nexport interface Locked {\n show: string[];\n preview?: Preview;\n}\n\nexport interface MemberPage {\n members: Membership[];\n next_cursor?: string;\n}\n\nexport interface MemberRef {\n content_id: string;\n version_id?: string;\n}\n\nexport interface Membership {\n group_id?: string;\n content_id?: string;\n version_id?: string;\n role?: string;\n position?: number;\n active_from?: string;\n active_until?: string;\n state?: \"active\" | \"proposed\";\n}\n\nexport interface MembershipRecord {\n group: Ref;\n version?: Ref;\n role?: string;\n position?: number;\n active_from?: string;\n active_until?: string;\n state?: string;\n}\n\nexport interface MembershipSet {\n content: Ref;\n kinds: string[];\n memberships: MembershipRecord[];\n}\n\nexport interface MergeInput {\n into: string;\n}\n\nexport interface MergeReport {\n from: string;\n into: string;\n memberships_moved: number;\n names_moved: number;\n edges_moved: number;\n groups_moved: number;\n}\n\nexport interface MultipartReply {\n ticket: string;\n min_part_size: number;\n max_part_size: number;\n max_parts: number;\n}\n\nexport interface MyGroup {\n id: string;\n kind: string;\n slug: string;\n internal: boolean;\n scope_id?: string;\n parent_id?: string;\n name: string;\n name_language?: string;\n code?: string;\n path?: string;\n cover?: GroupsCover;\n avatar?: Avatar;\n count: number;\n attributes: Record<string, unknown>;\n access?: GroupAccess;\n created_at: string;\n owner: boolean;\n editor: boolean;\n writer: boolean;\n moderator: boolean;\n member: boolean;\n}\n\nexport interface MyGroupPage {\n entities: MyGroup[];\n next_cursor?: string;\n}\n\nexport interface MyStats {\n completed: Record<string, number>;\n access_seconds?: Record<string, number>;\n comments: number;\n comment_likes: number;\n comment_dislikes: number;\n}\n\nexport interface Name {\n language: string;\n kind: \"alias\" | \"name\";\n name: string;\n}\n\nexport interface Offer {\n id: string;\n target: Target;\n key: string;\n terms: Terms;\n state: \"active\" | \"withdrawn\";\n synced: boolean;\n product_id?: string;\n price_id?: string;\n last_error?: string;\n revision: number;\n updated_at: string;\n}\n\nexport interface OfferPage {\n offers: Offer[];\n next_cursor?: string;\n}\n\nexport interface OfferRecord {\n target: TargetRef;\n terms: Terms;\n}\n\nexport interface Op {\n op: OpName;\n source_name?: string;\n path?: string;\n blob?: string;\n create_id?: string;\n replace?: boolean;\n index?: number;\n meta?: Record<string, unknown>;\n edit?: Edit;\n unattached?: boolean;\n to?: string;\n from?: CopyFrom;\n t?: number;\n auto?: boolean;\n preset?: string;\n force?: boolean;\n takedown?: boolean;\n}\n\nexport interface Operation {\n id: string;\n state: \"awaiting_upload\" | \"blocked\" | \"failed\" | \"processing\" | \"published\" | \"publishing\" | \"ready\" | \"review_required\" | \"scheduled\";\n content_id: string;\n version_id: string;\n publish_at?: string;\n entities: EntityResolution[];\n progress: Progress;\n result?: OperationResult;\n error?: OperationError;\n upload?: PresignReply;\n created_at: string;\n updated_at: string;\n}\n\nexport interface OperationError {\n code: string;\n message: string;\n retryable: boolean;\n field?: string;\n}\n\nexport interface OperationResult {\n path: string;\n pages: number;\n page_review?: PageReviewSummary;\n}\n\nexport interface Order {\n members: MemberRef[];\n}\n\nexport interface OrderInput {\n ids: string[];\n}\n\nexport interface Origin {\n system: string;\n scope: string;\n id: string;\n subject?: string;\n}\n\nexport interface Page {\n items: Item[];\n next_cursor?: string;\n}\n\nexport interface PageAnalysis {\n recipe: string;\n source_sha256: string;\n status: string;\n width?: number;\n height?: number;\n frames?: number;\n pixel_sha256?: string;\n pixel_format?: string;\n profile_sha256?: string;\n blank: string;\n blank_reason?: string;\n confidence: string;\n metrics?: PageAnalysisMetrics;\n flags?: string[];\n}\n\nexport interface PageAnalysisMetrics {\n pixels: number;\n visible_pixels: number;\n opaque_pixels: number;\n foreground_pixels: number;\n min_rgb: number[];\n max_rgb: number[];\n}\n\nexport interface PageDecision {\n reason: string;\n confidence: string;\n related?: string[];\n}\n\nexport interface PageReview {\n revision: string;\n pages: PageReviewEntry[];\n selected: number;\n flagged: number;\n}\n\nexport interface PageReviewChange {\n id: string;\n mode: string;\n}\n\nexport interface PageReviewEntry {\n id: string;\n path: string;\n source_name: string;\n source_entry?: string;\n archive_sha256?: string;\n source_sha256: string;\n span?: PageSpan;\n included: boolean;\n mode: string;\n decision: PageDecision;\n flags: string[];\n analysis?: PageAnalysis;\n preview_url?: string;\n source_url?: string;\n}\n\nexport interface PageReviewPatch {\n revision: string;\n pages?: PageReviewChange[];\n order?: string[];\n}\n\nexport interface PageReviewSummary {\n sources: number;\n selected: number;\n excluded: number;\n flagged: number;\n}\n\nexport interface PageSpan {\n from: number;\n to: number;\n}\n\nexport interface PartBody {\n number: number;\n size: number;\n sha256: string;\n}\n\nexport interface PartReply {\n number: number;\n size?: number;\n sha256?: string;\n request?: RequestReply;\n}\n\nexport interface PartsBody {\n ticket: string;\n parts: PartBody[];\n}\n\nexport interface PartsReply {\n parts: PartReply[];\n}\n\nexport interface Pending {\n status: string;\n}\n\nexport interface Placement {\n content_id: string;\n position: number;\n version_id?: string;\n activity_token?: string;\n}\n\nexport interface PlanPage {\n name: string;\n span?: PageSpan;\n w: number;\n h: number;\n files: Record<string, string>;\n}\n\nexport interface PlanPlayback {\n item: RefBody;\n tracks: PlanTrack[];\n}\n\nexport interface PlanPreview {\n index: number;\n name: string;\n url: string;\n w: number;\n h: number;\n}\n\nexport interface PlanSegment {\n position?: number;\n title?: string;\n start: number;\n end: number;\n released: boolean;\n release_at?: string;\n locked: boolean;\n item?: RefBody;\n pages?: PlanPage[];\n}\n\nexport interface PlanTrack {\n name: string;\n path: string;\n duration?: number;\n}\n\nexport interface Poll {\n id: string;\n kind: PollKind;\n question: string;\n language: string;\n is_active: boolean;\n image_url?: string;\n live_at: string;\n closes_at?: string;\n closed: boolean;\n total_votes: number;\n options: PollOption[];\n voted: boolean;\n my_option?: string;\n answer_count?: number;\n groups?: AnswerGroup[];\n my_answer?: PollAnswer;\n}\n\nexport interface PollAnswer {\n id: string;\n text: string;\n classified: boolean;\n updated_at: string;\n}\n\nexport interface PollAnswerInput {\n text: string;\n}\n\nexport interface PollImage {\n image_url: string | null;\n}\n\nexport interface PollInput {\n kind?: PollKind;\n question: string;\n language: string;\n live_at?: string;\n closes_at?: string;\n options?: PollOptionInput[];\n}\n\nexport interface PollOption {\n id: string;\n label: string;\n image_url?: string;\n position: number;\n vote_count: number;\n}\n\nexport interface PollOptionInput {\n label: string;\n position: number;\n}\n\nexport interface PollOptionPatch {\n label?: string;\n position?: number;\n}\n\nexport interface PollOptionRecord {\n external_id: string;\n id?: string;\n label: string;\n position: number;\n}\n\nexport interface PollRecord {\n external_id: string;\n id?: string;\n kind?: string;\n question: string;\n language?: string;\n active?: boolean;\n live_at?: string;\n closes_at?: string;\n deleted_at?: string;\n created_at?: string;\n updated_at?: string;\n options?: PollOptionRecord[];\n}\n\nexport interface PollUpdate {\n question?: string;\n is_active?: boolean;\n live_at?: string;\n closes_at?: string | null;\n}\n\nexport interface PollVote {\n option_id: string;\n}\n\nexport interface PresetRule {\n kind: string;\n name: string;\n from: string;\n base: string;\n namespace: string;\n root?: string;\n to: string;\n widths: number[];\n aspect?: string;\n min_width?: number;\n first?: number;\n default: boolean;\n stable?: boolean;\n}\n\nexport interface PresignBody {\n ref: RefBody;\n path: string;\n type: string;\n size: number;\n sha256: string;\n}\n\nexport interface PresignReply {\n path: string;\n source_name?: string;\n blob: string;\n exists?: boolean;\n put?: RequestReply;\n multipart?: MultipartReply;\n process_on_upload?: boolean;\n}\n\nexport interface Preview {\n pages?: number;\n segments?: number;\n}\n\nexport interface Progress {\n stage: string;\n completed: number;\n total: number;\n}\n\nexport interface PublicImage {\n from: string;\n preset: string;\n renditions: PublicRendition[];\n}\n\nexport interface PublicRendition {\n url: string;\n w: number;\n h: number;\n}\n\nexport interface PublicUser {\n id: string;\n name?: string;\n username: string;\n avatar?: string;\n avatar_srcset?: string;\n}\n\nexport interface Publication {\n notifications: Input[];\n}\n\nexport interface PublishInput {\n publish_at?: string;\n}\n\nexport interface Published {\n items: Item[];\n}\n\nexport interface RankedContent {\n id: string;\n title: string;\n path?: string;\n value: number;\n}\n\nexport interface RankingInfo {\n policy: string;\n mode: string;\n requested_from?: string;\n requested_until?: string;\n covered_from?: string;\n covered_until?: string;\n}\n\nexport interface ReactionCounts {\n likes?: number;\n dislikes?: number;\n mine: number;\n}\n\nexport interface ReactionRecord {\n target: TargetRef;\n user_id?: string;\n ip?: string;\n value: number;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface ReadResult {\n access: Access;\n expires: number;\n meta?: Record<string, unknown>;\n previews?: string[];\n public?: PublicImage[];\n locked?: boolean;\n total: number;\n offset: number;\n limit: number;\n hls?: string[];\n state?: ItemState;\n full?: boolean;\n uploads?: UploadRule[];\n files: FileInfo[];\n}\n\nexport interface ReaderDefaults {\n auto_advance_seconds?: number;\n}\n\nexport interface ReaderMeta {\n schema_version: number;\n defaults?: ReaderDefaults;\n anchors?: Anchor[];\n background?: BackgroundCue[];\n foreground?: ForegroundCue[];\n}\n\nexport interface ReaderPlan {\n content_id: string;\n version_id: string;\n publication_id: string;\n pages?: number;\n segments: PlanSegment[];\n previews: PlanPreview[];\n playback?: PlanPlayback;\n reader?: ReaderMeta;\n}\n\nexport interface RecentSearch {\n query: string;\n results: number;\n searched_at: string;\n}\n\nexport interface RecentSearches {\n searches: RecentSearch[];\n}\n\nexport interface Recipient {\n audience: string;\n id: string;\n}\n\nexport interface RecordFailure {\n section: string;\n index: number;\n external_id?: string;\n code: string;\n error: string;\n}\n\nexport interface Ref {\n id?: string;\n external_id?: string;\n}\n\nexport interface RefBody {\n kind: string;\n id: string;\n version?: string;\n}\n\nexport interface ReleaseDates {\n dates: DateCount[];\n next_cursor?: string;\n}\n\nexport interface ReleaseDay {\n date: string;\n contents: Card[];\n filtered_count: number;\n filtered_entities: ReleaseFilteredEntity[];\n}\n\nexport interface ReleaseFilteredEntity {\n entity: GroupCard;\n count: number;\n}\n\nexport interface Rendition {\n url: string;\n w: number;\n h: number;\n}\n\nexport interface Request {\n content: ContentInput;\n entities?: EntityReference[];\n archive: Archive;\n publish?: \"draft\" | \"when_ready\";\n publish_at?: string;\n create_missing_entities?: boolean;\n source?: Source;\n}\n\nexport interface RequestReply {\n method: string;\n url: string;\n headers: Record<string, string>;\n expires: string;\n}\n\nexport interface ResolveInput {\n decision: \"approve\" | \"reject\" | \"review\";\n revision: number;\n reason?: string;\n}\n\nexport interface Resolved {\n tenant_id: string;\n content_kind: string;\n content_id: string;\n content_version_id?: string;\n code: string;\n slug: string;\n slugs?: Record<string, string>;\n path: string;\n version_id?: string;\n}\n\nexport interface Restored {\n restored: boolean;\n}\n\nexport interface Result {\n written: Record<string, number>;\n skipped?: Record<string, number>;\n failed: RecordFailure[];\n ids: Record<string, Record<string, string>>;\n}\n\nexport interface ReviewOutcome {\n decision: \"approve\" | \"reject\" | \"review\";\n}\n\nexport interface Rule {\n level: \"group\" | \"group_ppv\" | \"ppv\" | \"public\" | \"tier\";\n tiers?: string[];\n group_id?: string;\n preview?: Preview;\n free_after?: string;\n}\n\nexport interface Sale {\n key: string;\n target: Target;\n terms: Terms;\n price_id?: string;\n}\n\nexport interface Segment {\n position: number;\n title?: string;\n start: number;\n end: number;\n release_at?: string;\n released: boolean;\n}\n\nexport interface SegmentsInput {\n segments: Segment[];\n}\n\nexport interface SignalInput {\n content_id: string;\n version_id?: string;\n type: string;\n event_id: string;\n revision?: number;\n occurred_at: string;\n duration_s?: number;\n progress?: number;\n resume?: string;\n render_id?: string;\n surface?: string;\n position?: number;\n activity_token?: string;\n}\n\nexport interface SignalRecord {\n target: TargetRef;\n user_id?: string;\n anon_key?: string;\n type: string;\n event_id: string;\n revision?: number;\n occurred_at: string;\n duration_s?: number;\n progress?: number;\n resume?: string;\n}\n\nexport interface Signals {\n session?: string;\n signals: SignalInput[];\n}\n\nexport interface SitemapAlias {\n language: string;\n path: string;\n image?: string;\n}\n\nexport interface SitemapEntry {\n id: string;\n code: string;\n path: string;\n lastmod: string;\n languages: SitemapAlias[];\n}\n\nexport interface SitemapPage {\n entries: SitemapEntry[];\n next_cursor?: string;\n}\n\nexport interface Source {\n provider: string;\n id: string;\n url?: string;\n}\n\nexport interface StagedCopy {\n path: string;\n blob: string;\n size: number;\n}\n\nexport interface Target {\n kind: \"content\" | \"group\" | \"version\";\n id: string;\n content_id?: string;\n}\n\nexport interface TargetRef {\n content?: Ref;\n version?: Ref;\n group?: Ref;\n comment?: Ref;\n}\n\nexport interface Terms {\n amount: string;\n currency: string;\n access_hours?: number;\n renew_hours?: number;\n}\n\nexport interface TicketBody {\n ticket: string;\n}\n\nexport interface TopContents {\n contents: RankedContent[];\n}\n\nexport interface Total {\n public: number;\n tiers: Record<string, number>;\n languages: Record<string, LanguageTotal>;\n}\n\nexport interface Totals {\n kinds: Record<string, Total>;\n}\n\nexport interface Typeahead {\n contents: Card[];\n entities: GroupCard[];\n}\n\nexport interface UploadLimits {\n files_per_hour?: number;\n bytes_per_day?: number;\n quota_bytes?: number;\n}\n\nexport interface UploadRule {\n path: string;\n types: string[];\n max_bytes: number;\n max?: number;\n named?: boolean;\n page?: boolean;\n body?: boolean;\n frames?: string;\n aspect?: string;\n min_width?: number;\n video?: VideoLimits;\n min_aspect?: number;\n max_aspect?: number;\n}\n\nexport interface Version {\n id: string;\n code: string;\n position: number;\n languages: string[];\n traits: string[];\n label?: string;\n title?: string;\n description?: string;\n state?: ContentState;\n publish_at?: string;\n published_at?: string;\n live: boolean;\n access?: Rule;\n attributes: Record<string, unknown>;\n pages?: number;\n duration_ms?: number;\n width?: number;\n height?: number;\n has_audio: boolean;\n ordinal?: number;\n cover?: CatalogCover;\n segments: Segment[];\n decision: Decision;\n text?: Record<string, VersionText>;\n offer?: Offer;\n viewer?: ViewerState;\n}\n\nexport interface VersionFork {\n from: string;\n playback?: boolean;\n segments?: boolean;\n}\n\nexport interface VersionInput {\n languages?: string[];\n traits?: string[];\n label?: string;\n state?: VersionState;\n publish_at?: string;\n access?: Rule;\n clear_access?: boolean;\n attributes?: Record<string, unknown>;\n text?: Record<string, VersionText>;\n segments?: Segment[];\n ordinal?: number;\n cover?: string;\n fork?: VersionFork;\n}\n\nexport interface VersionRecord {\n external_id: string;\n id?: string;\n code?: string;\n languages: string[];\n traits?: string[];\n label?: string;\n state?: string;\n publish_at?: string;\n published_at?: string;\n deleted_at?: string;\n access?: Rule;\n attributes?: Record<string, unknown>;\n ordinal?: number;\n cover?: string;\n text?: Record<string, VersionText>;\n segments?: Segment[];\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface VersionRules {\n languages: string;\n traits?: string[];\n hidden?: boolean;\n}\n\nexport interface VersionText {\n title?: string;\n description?: string;\n}\n\nexport interface VideoLimits {\n max_seconds?: number;\n max_fps?: number;\n max_pixels?: number;\n max_work?: number;\n}\n\nexport interface ViewerState {\n favorited: boolean;\n seen: boolean;\n completed: boolean;\n progress: number;\n progress_max: number;\n resume?: string;\n last_view_at?: string;\n}\n\nexport interface VoteRecord {\n poll: Ref;\n option: Ref;\n user_id?: string;\n ip?: string;\n created_at?: string;\n}\n\nexport interface Written {\n count: number;\n}\n"],"mappings":";AAOA,IAAa,IAAiB,UACjB,IAAgB,SAChB,IAAgB"}
1
+ {"version":3,"file":"wire.js","names":[],"sources":["../../../src/client/generated/wire.ts"],"sourcesContent":["// Generated by `go generate ./internal/contract` from ContentKit's route catalog. Do not edit.\n\nimport type { ErrorCode } from \"./error-codes.js\";\n\nexport type { ErrorCode };\n\n// Upload sizes: one PUT up to MAX_SINGLE_PUT bytes, else multipart parts.\nexport const MAX_SINGLE_PUT = 67108864;\nexport const MIN_PART_SIZE = 8388608;\nexport const MAX_PART_SIZE = 16777216;\n\nexport type OpName = \"put\" | \"edit\" | \"move\" | \"rename\" | \"remove\" | \"attach\" | \"copy\" | \"frame\" | \"meta\" | \"regenerate\";\nexport type Access = \"full\" | \"none\";\nexport type ItemState = \"ready\" | \"processing\" | \"failed\";\nexport type EncodePhase = \"queued\" | \"downloading\" | \"probing\" | \"encoding\" | \"muxing\" | \"uploading\" | \"publishing\" | \"images\";\nexport type PollKind = \"multiple_choice\" | \"free_text\";\nexport type ModerationState = \"approved\" | \"held\" | \"rejected\";\nexport type ContentState = \"draft\" | \"published\" | \"deleted\";\nexport type VersionState = \"draft\" | \"published\";\nexport type Listing = \"listed\" | \"members\" | \"unlisted\";\nexport type AliasStatus = \"found\" | \"not_found\" | \"gone\";\n\nexport interface Activity {\n days: ActivityDay[];\n}\n\nexport interface ActivityContext {\n content_id: string;\n version_id?: string;\n token: string;\n occurred_at: string;\n}\n\nexport interface ActivityContexts {\n enabled: boolean;\n contexts: ActivityContext[];\n}\n\nexport interface ActivityContextsInput {\n session?: string;\n language?: string;\n targets: ActivityTarget[];\n}\n\nexport interface ActivityDay {\n date: string;\n readers: number;\n active_ms: number;\n users: number;\n}\n\nexport interface ActivityTarget {\n content_id: string;\n version_id?: string;\n}\n\nexport interface AdminComment {\n id: string;\n reply_to_id?: string;\n user_id?: string;\n anon_name?: string;\n language?: string;\n body: string;\n deleted: boolean;\n likes: number;\n dislikes: number;\n mine: number;\n reply_count: number;\n author?: PublicUser;\n moderation?: ModerationState;\n moderation_reason?: string;\n created_at: string;\n updated_at: string;\n tenant_id: string;\n content_kind: string;\n content_id: string;\n content_version_id?: string;\n deleted_at?: string;\n}\n\nexport interface AliasKey {\n source: string;\n kind: string;\n key: string;\n}\n\nexport interface AliasLookup {\n aliases: AliasKey[];\n}\n\nexport interface AliasRecord {\n kind: string;\n key: string;\n locator?: string;\n target: TargetRef;\n}\n\nexport interface AliasResult {\n source: string;\n kind: string;\n key: string;\n status: AliasStatus;\n resolved?: Resolved;\n locator?: string;\n}\n\nexport interface AliasResults {\n aliases: AliasResult[];\n}\n\nexport interface Anchor {\n id: string;\n page: string;\n offset_percent: number;\n duration_seconds?: number;\n}\n\nexport interface Anonymous {\n comments: boolean;\n reactions: boolean;\n votes: boolean;\n}\n\nexport interface AnswerGroup {\n id: string;\n label: string;\n count: number;\n}\n\nexport interface AnswerRecord {\n poll: Ref;\n user_id: string;\n text: string;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface Archive {\n name: string;\n size: number;\n sha256: string;\n}\n\nexport interface Attribute {\n type: string;\n values?: string[];\n filterable?: boolean;\n sortable?: boolean;\n}\n\nexport interface Avatar {\n image?: string;\n renditions?: Rendition[];\n}\n\nexport interface BackgroundCue {\n file: string;\n from_page?: string;\n to_page?: string;\n from_anchor?: string;\n to_anchor?: string;\n loop?: boolean;\n layer?: string;\n}\n\nexport interface BanInput {\n reason?: string;\n until?: string;\n}\n\nexport interface BanNotice {\n scope: string;\n reason?: string;\n until?: string;\n}\n\nexport interface BannedWord {\n word: string;\n action: \"mask\" | \"reject\";\n created_by: string;\n created_at: string;\n}\n\nexport interface BannedWordInput {\n word: string;\n action?: \"mask\" | \"reject\";\n}\n\nexport interface Batch {\n source: string;\n preference_floor?: number;\n provision_scopes?: boolean;\n entities?: GroupRecord[];\n contents?: ContentRecord[];\n memberships?: MembershipSet[];\n offers?: OfferRecord[];\n aliases?: AliasRecord[];\n comments?: CommentRecord[];\n reactions?: ReactionRecord[];\n favorites?: FavoriteRecord[];\n polls?: PollRecord[];\n votes?: VoteRecord[];\n answers?: AnswerRecord[];\n legacy_reading?: LegacyReadingRecord[];\n signals?: SignalRecord[];\n deletes?: DeleteRecord[];\n}\n\nexport interface BodyImageInput {\n image?: string;\n version: string;\n}\n\nexport interface Card {\n id: string;\n kind: string;\n code: string;\n path: string;\n title: string;\n language: string;\n cover: PublicRendition[];\n version: CardVersion;\n entities: Record<string, Chip[]>;\n owner?: GroupCard;\n counts: Counts;\n access: CardAccess;\n viewer?: ViewerState;\n published_at?: string;\n attributes: Record<string, unknown>;\n ranking?: ContentRanking;\n}\n\nexport interface CardAccess {\n allowed: boolean;\n level: \"group\" | \"group_ppv\" | \"ppv\" | \"public\" | \"tier\";\n tiers?: string[];\n unknown?: boolean;\n sell?: string[];\n requires?: string;\n preview?: Preview;\n free_after?: string;\n offers?: Sale[];\n}\n\nexport interface CardVersion {\n id: string;\n code: string;\n languages: string[];\n traits: string[];\n label?: string;\n pages?: number;\n duration_ms?: number;\n has_audio: boolean;\n hls?: string;\n}\n\nexport interface CatalogCover {\n image?: string;\n url?: string;\n renditions?: PublicRendition[];\n}\n\nexport interface CatalogText {\n title: string;\n slug?: string;\n description?: string;\n body?: string;\n sort_key?: string;\n aliases?: string[];\n}\n\nexport interface Chip {\n id: string;\n slug: string;\n name: string;\n path?: string;\n position?: number;\n}\n\nexport interface Comment {\n id: string;\n reply_to_id?: string;\n user_id?: string;\n anon_name?: string;\n language?: string;\n body: string;\n deleted: boolean;\n likes: number;\n dislikes: number;\n mine: number;\n reply_count: number;\n author?: PublicUser;\n moderation?: ModerationState;\n moderation_reason?: string;\n created_at: string;\n updated_at: string;\n}\n\nexport interface CommentBan {\n user_id: string;\n user?: PublicUser;\n scope: string;\n reason?: string;\n until?: string;\n banned_by: string;\n banned_at: string;\n expired: boolean;\n}\n\nexport interface CommentEdit {\n body: string;\n}\n\nexport interface CommentInput {\n body: string;\n reply_to_id?: string;\n anon_name?: string;\n language?: string;\n}\n\nexport interface CommentRecord {\n external_id: string;\n id?: string;\n target: TargetRef;\n language?: string;\n reply_to?: Ref;\n user_id?: string;\n anon_name?: string;\n body: string;\n deleted_at?: string;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface CommentStanding {\n can_comment: boolean;\n comments: string;\n count?: number;\n locked: boolean;\n ban?: BanNotice;\n anonymous: boolean;\n max_length: number;\n user_id?: string;\n moderate: boolean;\n ban_scopes: (\"global\" | \"owner\")[];\n}\n\nexport interface CommitBody {\n ref: RefBody;\n operation_id: string;\n ops: Op[];\n}\n\nexport interface CommitReply {\n files: FileInfo[];\n}\n\nexport interface CompleteReply {\n blob: string;\n type: string;\n size: number;\n}\n\nexport type CompleteRequest = Record<string, never>;\n\nexport interface Config {\n anonymous: Anonymous;\n comment_max_length: number;\n}\n\nexport interface Content {\n id: string;\n kind: string;\n code: string;\n path: string;\n language: string;\n title: string;\n slug?: string;\n description?: string;\n body?: string;\n decision: Decision;\n images?: Record<string, string>;\n cover?: CatalogCover;\n state: ContentState;\n listing: Listing;\n comments: string;\n publish_at?: string;\n published_at?: string;\n live: boolean;\n access: Rule;\n restrictions: string[];\n attributes: Record<string, unknown>;\n owner_group_id?: string;\n owner?: GroupCard;\n creators: Creator[];\n entities: GroupSummary[];\n versions: Version[];\n viewer?: ViewerState;\n editor: boolean;\n text?: Record<string, CatalogText>;\n moderation?: ModerationState;\n moderation_reason?: string;\n ever_sold?: boolean;\n offer?: Offer;\n revision: number;\n created_at: string;\n updated_at: string;\n deleted_at?: string;\n}\n\nexport interface ContentFilterState {\n entity: GroupCard;\n default_visible: boolean;\n visible: boolean;\n overridden: boolean;\n}\n\nexport interface ContentFilters {\n applies_to: string[];\n filters: ContentFilterState[];\n include_deleted: boolean;\n}\n\nexport interface ContentFiltersInitialization {\n account_id: string;\n filters: GuestFilterSetting[];\n include_deleted: boolean;\n}\n\nexport interface ContentFiltersUpdate {\n filters?: GuestFilterSetting[];\n include_deleted?: boolean;\n}\n\nexport interface ContentGroups {\n kinds?: string[];\n memberships: Membership[];\n}\n\nexport interface ContentInput {\n kind: string;\n text?: Record<string, CatalogText>;\n listing?: Listing;\n comments?: string;\n access?: Rule;\n restrictions?: string[];\n attributes?: Record<string, unknown>;\n owner_group_id?: string;\n creators?: Creator[];\n versions?: VersionInput[];\n}\n\nexport interface ContentMemberships {\n content_id: string;\n memberships: Membership[];\n entities: GroupCard[];\n}\n\nexport interface ContentModel {\n languages: string[];\n tiers: string[];\n kinds: Record<string, Kind>;\n entity_kinds: Record<string, GroupKind>;\n signals: boolean;\n avatars?: PresetRule;\n}\n\nexport interface ContentPage {\n contents: Card[];\n summary?: ListingSummary;\n next_cursor?: string;\n ranking?: RankingInfo;\n}\n\nexport interface ContentPatch {\n listing?: Listing;\n comments?: string;\n access?: Rule;\n restrictions?: string[];\n attributes?: Record<string, unknown>;\n creators?: Creator[];\n revision?: number;\n}\n\nexport interface ContentRanking {\n score: number;\n participation: number;\n adjusted_participation: number;\n}\n\nexport interface ContentRecord {\n external_id: string;\n id?: string;\n kind: string;\n state: string;\n publish_at?: string;\n published_at?: string;\n deleted_at?: string;\n listing?: string;\n comments?: string;\n access?: Rule;\n restrictions?: string[];\n attributes?: Record<string, unknown>;\n owner_group?: Ref;\n creators?: Creator[];\n text?: Record<string, CatalogText>;\n versions?: VersionRecord[];\n code?: string;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface ContentRef {\n tenant_id: string;\n content_kind: string;\n content_id: string;\n content_version_id?: string;\n}\n\nexport interface CopyBody {\n ref: RefBody;\n files: CopyRequest[];\n}\n\nexport interface CopyFrom {\n id: string;\n version?: string;\n path: string;\n}\n\nexport interface CopyReply {\n files: StagedCopy[];\n}\n\nexport interface CopyRequest {\n path: string;\n type: string;\n from: string;\n size?: number;\n}\n\nexport interface Count {\n content_kind: string;\n language: string;\n count: number;\n}\n\nexport interface Counts {\n likes?: number;\n dislikes?: number;\n favorites?: number;\n}\n\nexport interface CoverageRange {\n from: number;\n to: number;\n}\n\nexport interface Creator {\n user_id: string;\n role?: string;\n position: number;\n}\n\nexport interface CreatorsInput {\n creators: Creator[];\n}\n\nexport interface Crop {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport interface DailyReleases {\n time_zone: string;\n from_date: string;\n through_date: string;\n days: ReleaseDay[];\n}\n\nexport interface DateCount {\n date: string;\n count: number;\n free: number;\n}\n\nexport interface Decision {\n allowed: boolean;\n unknown?: boolean;\n sell?: string[];\n requires?: string;\n preview?: Preview;\n free_after?: string;\n offers?: Sale[];\n}\n\nexport interface DeleteRecord {\n entity: string;\n external_id: string;\n}\n\nexport interface Download {\n off?: boolean;\n serve?: string;\n}\n\nexport interface Edge {\n from: string;\n relation: string;\n to: string;\n}\n\nexport interface EdgeInput {\n relation: string;\n to: string;\n}\n\nexport interface EdgeRecord {\n relation: string;\n to: Ref;\n}\n\nexport interface Edit {\n crop?: Crop;\n rotate?: number;\n}\n\nexport interface EncodeProgress {\n phase: EncodePhase;\n queue_position?: number;\n segments_done?: number;\n segments_total?: number;\n percent: number;\n speed?: number;\n eta?: number;\n at: number;\n stalled?: boolean;\n stage?: number;\n stages?: number;\n}\n\nexport interface EngagementBatch {\n session?: string;\n snapshots: EngagementSnapshot[];\n}\n\nexport interface EngagementSnapshot {\n content_id: string;\n version_id?: string;\n visit_id: string;\n segment_id: string;\n revision: number;\n activity_token: string;\n active_ms: number;\n resume?: string;\n pages?: PageEngagement[];\n watched?: WatchedRange[];\n}\n\nexport interface EntityReference {\n id?: string;\n kind?: string;\n name?: string;\n language?: string;\n scope?: EntityReference;\n}\n\nexport interface EntityResolution {\n id: string;\n kind: string;\n name: string;\n created: boolean;\n scope?: EntityResolution;\n}\n\nexport interface ErrorDetails {\n width?: number;\n height?: number;\n min_width?: number;\n max_pixels?: number;\n type?: string;\n allowed?: string[];\n size?: number;\n max_bytes?: number;\n frames?: number;\n max_frames?: number;\n seconds?: number;\n max_seconds?: number;\n min_aspect?: number;\n max_aspect?: number;\n max?: number;\n}\n\nexport interface ErrorReply {\n error: string;\n code: ErrorCode;\n retry_after?: number;\n action?: \"comment\" | \"comment_reaction\" | \"favorite\" | \"poll_vote\" | \"reaction\";\n ban?: BanNotice;\n blobs?: string[];\n details?: ErrorDetails;\n reason?: string;\n available_at?: string;\n}\n\nexport interface ExposureInput {\n render_id: string;\n stage: string;\n revision?: number;\n query_id?: string;\n surface?: string;\n ranker?: string;\n language?: string;\n occurred_at?: string;\n shown: Placement[];\n}\n\nexport interface Exposures {\n session?: string;\n exposures: ExposureInput[];\n}\n\nexport interface ExternalID {\n external_id: string;\n id: string;\n deleted: boolean;\n}\n\nexport interface ExternalIDList {\n entity: string;\n cursor?: string;\n limit?: number;\n}\n\nexport interface ExternalIDPage {\n entity: string;\n ids: ExternalID[];\n next_cursor?: string;\n}\n\nexport interface ExternalIDs {\n lists: ExternalIDPage[];\n}\n\nexport interface ExternalIDsQuery {\n source: string;\n lists: ExternalIDList[];\n}\n\nexport interface Failure {\n of: string;\n message: string;\n code?: ErrorCode;\n details?: ErrorDetails;\n}\n\nexport interface FavoriteRecord {\n target: TargetRef;\n user_id: string;\n created_at?: string;\n}\n\nexport interface FavoriteState {\n favorited: boolean;\n count?: number;\n}\n\nexport interface FeedItem {\n id: string;\n reply_to_id?: string;\n user_id?: string;\n anon_name?: string;\n language?: string;\n body: string;\n deleted: boolean;\n likes: number;\n dislikes: number;\n mine: number;\n reply_count: number;\n author?: PublicUser;\n moderation?: ModerationState;\n moderation_reason?: string;\n created_at: string;\n updated_at: string;\n tenant_id: string;\n content_kind: string;\n content_id: string;\n content_version_id?: string;\n}\n\nexport interface FileDownload {\n url: string;\n name: string;\n type: string;\n size?: number;\n expires_at: string;\n}\n\nexport interface FileInfo {\n path: string;\n type: string;\n size?: number;\n w?: number;\n h?: number;\n dur?: number;\n download?: string;\n url?: string;\n create_id?: string;\n upload?: boolean;\n staged?: boolean;\n from?: string;\n edit?: Edit;\n frame?: Frame;\n meta?: Record<string, unknown>;\n unattached?: boolean;\n pending?: string[];\n failed?: Failure;\n editor_url?: string;\n progress?: EncodeProgress;\n}\n\nexport interface ForegroundCue {\n file: string;\n page?: string;\n anchor?: string;\n}\n\nexport interface ForkBody {\n from: string;\n playback?: boolean;\n segments?: boolean;\n}\n\nexport interface Frame {\n t?: number;\n auto?: boolean;\n of?: string;\n}\n\nexport interface Group {\n id: string;\n kind: string;\n slug: string;\n internal: boolean;\n scope_id?: string;\n parent_id?: string;\n state: \"active\" | \"deleted\" | \"merged\";\n merged_into?: string;\n attributes: Record<string, unknown>;\n cover?: GroupsCover;\n avatar?: Avatar;\n owner_user_id?: string;\n auth_scope?: string;\n created_at: string;\n updated_at: string;\n revision: number;\n}\n\nexport interface GroupAccess {\n key: string;\n offer?: Sale;\n member: boolean;\n editor?: boolean;\n unknown?: boolean;\n}\n\nexport interface GroupCard {\n id: string;\n kind: string;\n slug: string;\n internal: boolean;\n scope_id?: string;\n parent_id?: string;\n name: string;\n name_language?: string;\n code?: string;\n path?: string;\n cover?: GroupsCover;\n avatar?: Avatar;\n count: number;\n attributes: Record<string, unknown>;\n access?: GroupAccess;\n created_at: string;\n}\n\nexport interface GroupDetail {\n id: string;\n kind: string;\n slug: string;\n internal: boolean;\n scope_id?: string;\n parent_id?: string;\n state: \"active\" | \"deleted\" | \"merged\";\n merged_into?: string;\n attributes: Record<string, unknown>;\n cover?: GroupsCover;\n avatar?: Avatar;\n owner_user_id?: string;\n auth_scope?: string;\n created_at: string;\n updated_at: string;\n revision: number;\n name: string;\n name_language?: string;\n code?: string;\n path?: string;\n names: Name[];\n text: GroupsText[];\n parent?: GroupCard;\n scope?: GroupCard;\n children: GroupCard[];\n edges: Edge[];\n counts: Count[];\n access?: GroupAccess;\n offer?: Offer;\n}\n\nexport interface GroupInput {\n id?: string;\n kind: string;\n slug: string;\n internal?: boolean;\n scope_id?: string;\n parent_id?: string;\n attributes?: Record<string, unknown>;\n cover?: GroupsCover;\n avatar?: Avatar;\n owner_user_id?: string;\n auth_scope?: string;\n names?: Name[];\n text?: GroupsText[];\n}\n\nexport interface GroupJoin {\n group_id: string;\n key: string;\n member: boolean;\n}\n\nexport interface GroupKind {\n route?: string;\n ordered?: boolean;\n parent?: string;\n scoped_by?: string;\n owner?: string;\n max_per_owner?: number;\n uploads?: UploadLimits;\n sellable?: boolean;\n auth_scope?: boolean;\n windows?: boolean;\n version_level?: boolean;\n roles?: string[];\n attributes?: Record<string, Attribute>;\n}\n\nexport interface GroupPage {\n entities: GroupCard[];\n next_cursor?: string;\n}\n\nexport interface GroupRecord {\n external_id: string;\n id?: string;\n kind: string;\n slug: string;\n internal?: boolean;\n scope?: Ref;\n parent?: Ref;\n state?: string;\n names?: Name[];\n text?: GroupsText[];\n attributes?: Record<string, unknown>;\n cover_image?: string;\n cover_content?: Ref;\n avatar?: string;\n owner_user_id?: string;\n auth_scope?: string;\n edges?: EdgeRecord[];\n code?: string;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface GroupSummary {\n id: string;\n kind: string;\n slug: string;\n name: string;\n code?: string;\n path?: string;\n}\n\nexport interface GroupUpdate {\n slug?: string;\n internal?: boolean;\n scope_id?: string;\n parent_id?: string;\n state?: \"active\" | \"deleted\" | \"merged\";\n attributes?: Record<string, unknown>;\n cover?: GroupsCover;\n avatar?: Avatar;\n owner_user_id?: string;\n auth_scope?: string;\n names?: Name[];\n text?: GroupsText[];\n}\n\nexport interface GroupsCover {\n image?: string;\n content_id?: string;\n auto?: boolean;\n renditions?: Rendition[];\n}\n\nexport interface GroupsText {\n language: string;\n description?: string;\n sort_key?: string;\n}\n\nexport interface GuestFilterSetting {\n entity_id: string;\n visible?: boolean;\n default?: boolean;\n}\n\nexport interface HeldItem {\n kind: string;\n revision: number;\n id: string;\n ref: ContentRef;\n author_id?: string;\n author?: PublicUser;\n anon_name?: string;\n title?: string;\n body: string;\n reason: string;\n model?: string;\n prompt_version?: string;\n confidence?: number;\n error?: string;\n held_at: string;\n created_at: string;\n}\n\nexport interface HeldPage {\n items: HeldItem[];\n next?: string;\n}\n\nexport interface IPBan {\n network: string;\n reason?: string;\n until?: string;\n banned_by: string;\n banned_at: string;\n expired: boolean;\n}\n\nexport interface IPBanInput {\n network: string;\n reason?: string;\n until?: string;\n}\n\nexport interface ImageInput {\n image?: string;\n}\n\nexport interface InlineImage {\n ref: string;\n url: string | null;\n}\n\nexport interface Input {\n recipient: Recipient;\n origin: Origin;\n kind: string;\n data: unknown;\n created_at: string;\n visibility?: string;\n app_id?: string;\n status?: string;\n action_requested?: boolean;\n severity?: string;\n}\n\nexport interface Interaction {\n content?: Card;\n entity?: GroupCard;\n value: number;\n at: string;\n}\n\nexport interface InteractionPage {\n items: Interaction[];\n next_cursor?: string;\n summary?: ListingSummary;\n}\n\nexport interface Item {\n id: string;\n recipient: Recipient;\n origin: Origin;\n kind: string;\n data: unknown;\n created_at: string;\n visibility?: string;\n app_id?: string;\n status?: string;\n action_requested?: boolean;\n severity?: string;\n read_at: string | null;\n dismissed_at: string | null;\n resolved_at: string | null;\n updated_at: string;\n revision: number;\n}\n\nexport interface Kind {\n route: string;\n presentation: string;\n versions: VersionRules;\n segments?: boolean;\n entities?: string[];\n attributes?: Record<string, Attribute>;\n sort?: string;\n locked?: Locked;\n draft_ttl?: number;\n download?: Download;\n}\n\nexport interface LanguageTotal {\n public: number;\n tiers: Record<string, number>;\n}\n\nexport interface LegacyReadingRecord {\n target: TargetRef;\n user_id?: string;\n anon_key?: string;\n first_read_at?: string;\n last_read_at: string;\n progress: number;\n progress_max: number;\n completed: boolean;\n resume?: string;\n revision?: number;\n}\n\nexport interface LibraryItem {\n content_id: string;\n kind: string;\n title: string;\n language?: string;\n deleted: boolean;\n whole: boolean;\n version_ids: string[];\n}\n\nexport interface LibraryPage {\n items: LibraryItem[];\n next_cursor?: string;\n complete: boolean;\n}\n\nexport interface ListingSummary {\n filtered_count: number;\n filtered_entities: ReleaseFilteredEntity[];\n locked_count: number;\n truncated?: boolean;\n}\n\nexport interface Locked {\n show: string[];\n preview?: Preview;\n}\n\nexport interface MemberPage {\n members: Membership[];\n next_cursor?: string;\n}\n\nexport interface MemberRef {\n content_id: string;\n version_id?: string;\n}\n\nexport interface Membership {\n group_id?: string;\n content_id?: string;\n version_id?: string;\n role?: string;\n position?: number;\n active_from?: string;\n active_until?: string;\n state?: \"active\" | \"proposed\";\n}\n\nexport interface MembershipRecord {\n group: Ref;\n version?: Ref;\n role?: string;\n position?: number;\n active_from?: string;\n active_until?: string;\n state?: string;\n}\n\nexport interface MembershipSet {\n content: Ref;\n kinds: string[];\n memberships: MembershipRecord[];\n}\n\nexport interface MergeInput {\n into: string;\n}\n\nexport interface MergeReport {\n from: string;\n into: string;\n memberships_moved: number;\n names_moved: number;\n edges_moved: number;\n groups_moved: number;\n}\n\nexport interface MultipartReply {\n ticket: string;\n min_part_size: number;\n max_part_size: number;\n max_parts: number;\n}\n\nexport interface MyGroup {\n id: string;\n kind: string;\n slug: string;\n internal: boolean;\n scope_id?: string;\n parent_id?: string;\n name: string;\n name_language?: string;\n code?: string;\n path?: string;\n cover?: GroupsCover;\n avatar?: Avatar;\n count: number;\n attributes: Record<string, unknown>;\n access?: GroupAccess;\n created_at: string;\n owner: boolean;\n editor: boolean;\n writer: boolean;\n moderator: boolean;\n member: boolean;\n}\n\nexport interface MyGroupPage {\n entities: MyGroup[];\n next_cursor?: string;\n}\n\nexport interface MyStats {\n completed: Record<string, number>;\n access_seconds?: Record<string, number>;\n comments: number;\n comment_likes: number;\n comment_dislikes: number;\n}\n\nexport interface Name {\n language: string;\n kind: \"alias\" | \"name\";\n name: string;\n}\n\nexport interface Offer {\n id: string;\n target: Target;\n key: string;\n terms: Terms;\n state: \"active\" | \"withdrawn\";\n synced: boolean;\n product_id?: string;\n price_id?: string;\n last_error?: string;\n revision: number;\n updated_at: string;\n}\n\nexport interface OfferPage {\n offers: Offer[];\n next_cursor?: string;\n}\n\nexport interface OfferRecord {\n target: TargetRef;\n terms: Terms;\n}\n\nexport interface Op {\n op: OpName;\n source_name?: string;\n path?: string;\n blob?: string;\n create_id?: string;\n replace?: boolean;\n index?: number;\n meta?: Record<string, unknown>;\n edit?: Edit;\n unattached?: boolean;\n to?: string;\n from?: CopyFrom;\n t?: number;\n auto?: boolean;\n preset?: string;\n force?: boolean;\n takedown?: boolean;\n}\n\nexport interface Operation {\n id: string;\n state: \"awaiting_upload\" | \"blocked\" | \"failed\" | \"processing\" | \"published\" | \"publishing\" | \"ready\" | \"review_required\" | \"scheduled\";\n content_id: string;\n version_id: string;\n publish_at?: string;\n entities: EntityResolution[];\n progress: Progress;\n result?: OperationResult;\n error?: OperationError;\n upload?: PresignReply;\n created_at: string;\n updated_at: string;\n}\n\nexport interface OperationError {\n code: string;\n message: string;\n retryable: boolean;\n field?: string;\n}\n\nexport interface OperationResult {\n path: string;\n pages: number;\n page_review?: PageReviewSummary;\n}\n\nexport interface Order {\n members: MemberRef[];\n}\n\nexport interface OrderInput {\n ids: string[];\n}\n\nexport interface Origin {\n system: string;\n scope: string;\n id: string;\n subject?: string;\n}\n\nexport interface Page {\n items: Item[];\n next_cursor?: string;\n}\n\nexport interface PageAnalysis {\n recipe: string;\n source_sha256: string;\n status: string;\n width?: number;\n height?: number;\n frames?: number;\n pixel_sha256?: string;\n pixel_format?: string;\n profile_sha256?: string;\n blank: string;\n blank_reason?: string;\n confidence: string;\n metrics?: PageAnalysisMetrics;\n flags?: string[];\n}\n\nexport interface PageAnalysisMetrics {\n pixels: number;\n visible_pixels: number;\n opaque_pixels: number;\n foreground_pixels: number;\n min_rgb: number[];\n max_rgb: number[];\n}\n\nexport interface PageDecision {\n reason: string;\n confidence: string;\n related?: string[];\n}\n\nexport interface PageEngagement {\n index: number;\n ranges: CoverageRange[];\n active_ms: number;\n}\n\nexport interface PageReview {\n revision: string;\n pages: PageReviewEntry[];\n selected: number;\n flagged: number;\n}\n\nexport interface PageReviewChange {\n id: string;\n mode: string;\n}\n\nexport interface PageReviewEntry {\n id: string;\n path: string;\n source_name: string;\n source_entry?: string;\n archive_sha256?: string;\n source_sha256: string;\n span?: PageSpan;\n included: boolean;\n mode: string;\n decision: PageDecision;\n flags: string[];\n analysis?: PageAnalysis;\n preview_url?: string;\n source_url?: string;\n}\n\nexport interface PageReviewPatch {\n revision: string;\n pages?: PageReviewChange[];\n order?: string[];\n}\n\nexport interface PageReviewSummary {\n sources: number;\n selected: number;\n excluded: number;\n flagged: number;\n}\n\nexport interface PageSpan {\n from: number;\n to: number;\n}\n\nexport interface PartBody {\n number: number;\n size: number;\n sha256: string;\n}\n\nexport interface PartReply {\n number: number;\n size?: number;\n sha256?: string;\n request?: RequestReply;\n}\n\nexport interface PartsBody {\n ticket: string;\n parts: PartBody[];\n}\n\nexport interface PartsReply {\n parts: PartReply[];\n}\n\nexport interface Pending {\n status: string;\n}\n\nexport interface Placement {\n content_id: string;\n position: number;\n version_id?: string;\n activity_token?: string;\n}\n\nexport interface PlanPage {\n name: string;\n span?: PageSpan;\n w: number;\n h: number;\n files: Record<string, string>;\n}\n\nexport interface PlanPlayback {\n item: RefBody;\n tracks: PlanTrack[];\n}\n\nexport interface PlanPreview {\n index: number;\n name: string;\n url: string;\n w: number;\n h: number;\n}\n\nexport interface PlanSegment {\n position?: number;\n title?: string;\n start: number;\n end: number;\n released: boolean;\n release_at?: string;\n locked: boolean;\n item?: RefBody;\n pages?: PlanPage[];\n}\n\nexport interface PlanTrack {\n name: string;\n path: string;\n duration?: number;\n}\n\nexport interface Poll {\n id: string;\n kind: PollKind;\n question: string;\n language: string;\n is_active: boolean;\n image_url?: string;\n live_at: string;\n closes_at?: string;\n closed: boolean;\n total_votes: number;\n options: PollOption[];\n voted: boolean;\n my_option?: string;\n answer_count?: number;\n groups?: AnswerGroup[];\n my_answer?: PollAnswer;\n}\n\nexport interface PollAnswer {\n id: string;\n text: string;\n classified: boolean;\n updated_at: string;\n}\n\nexport interface PollAnswerInput {\n text: string;\n}\n\nexport interface PollImage {\n image_url: string | null;\n}\n\nexport interface PollInput {\n kind?: PollKind;\n question: string;\n language: string;\n live_at?: string;\n closes_at?: string;\n options?: PollOptionInput[];\n}\n\nexport interface PollOption {\n id: string;\n label: string;\n image_url?: string;\n position: number;\n vote_count: number;\n}\n\nexport interface PollOptionInput {\n label: string;\n position: number;\n}\n\nexport interface PollOptionPatch {\n label?: string;\n position?: number;\n}\n\nexport interface PollOptionRecord {\n external_id: string;\n id?: string;\n label: string;\n position: number;\n}\n\nexport interface PollRecord {\n external_id: string;\n id?: string;\n kind?: string;\n question: string;\n language?: string;\n active?: boolean;\n live_at?: string;\n closes_at?: string;\n deleted_at?: string;\n created_at?: string;\n updated_at?: string;\n options?: PollOptionRecord[];\n}\n\nexport interface PollUpdate {\n question?: string;\n is_active?: boolean;\n live_at?: string;\n closes_at?: string | null;\n}\n\nexport interface PollVote {\n option_id: string;\n}\n\nexport interface PresetRule {\n kind: string;\n name: string;\n from: string;\n base: string;\n namespace: string;\n root?: string;\n to: string;\n widths: number[];\n aspect?: string;\n min_width?: number;\n first?: number;\n default: boolean;\n stable?: boolean;\n}\n\nexport interface PresignBody {\n ref: RefBody;\n path: string;\n type: string;\n size: number;\n sha256: string;\n}\n\nexport interface PresignReply {\n path: string;\n source_name?: string;\n blob: string;\n exists?: boolean;\n put?: RequestReply;\n multipart?: MultipartReply;\n process_on_upload?: boolean;\n}\n\nexport interface Preview {\n pages?: number;\n segments?: number;\n}\n\nexport interface Progress {\n stage: string;\n completed: number;\n total: number;\n}\n\nexport interface PublicImage {\n from: string;\n preset: string;\n renditions: PublicRendition[];\n}\n\nexport interface PublicRendition {\n url: string;\n w: number;\n h: number;\n}\n\nexport interface PublicUser {\n id: string;\n name?: string;\n username: string;\n avatar?: string;\n avatar_srcset?: string;\n}\n\nexport interface Publication {\n notifications: Input[];\n}\n\nexport interface PublishInput {\n publish_at?: string;\n}\n\nexport interface Published {\n items: Item[];\n}\n\nexport interface RankedContent {\n id: string;\n title: string;\n path?: string;\n value: number;\n}\n\nexport interface RankingInfo {\n policy: string;\n mode: string;\n requested_from?: string;\n requested_until?: string;\n covered_from?: string;\n covered_until?: string;\n}\n\nexport interface ReactionCounts {\n likes?: number;\n dislikes?: number;\n mine: number;\n}\n\nexport interface ReactionRecord {\n target: TargetRef;\n user_id?: string;\n ip?: string;\n value: number;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface ReadResult {\n access: Access;\n expires: number;\n meta?: Record<string, unknown>;\n previews?: string[];\n public?: PublicImage[];\n locked?: boolean;\n total: number;\n offset: number;\n limit: number;\n hls?: string[];\n state?: ItemState;\n full?: boolean;\n uploads?: UploadRule[];\n files: FileInfo[];\n}\n\nexport interface ReaderDefaults {\n auto_advance_seconds?: number;\n}\n\nexport interface ReaderMeta {\n schema_version: number;\n defaults?: ReaderDefaults;\n anchors?: Anchor[];\n background?: BackgroundCue[];\n foreground?: ForegroundCue[];\n}\n\nexport interface ReaderPlan {\n content_id: string;\n version_id: string;\n publication_id: string;\n pages?: number;\n segments: PlanSegment[];\n previews: PlanPreview[];\n playback?: PlanPlayback;\n reader?: ReaderMeta;\n}\n\nexport interface RecentSearch {\n query: string;\n results: number;\n searched_at: string;\n}\n\nexport interface RecentSearches {\n searches: RecentSearch[];\n}\n\nexport interface Recipient {\n audience: string;\n id: string;\n}\n\nexport interface RecordFailure {\n section: string;\n index: number;\n external_id?: string;\n code: string;\n error: string;\n}\n\nexport interface Ref {\n id?: string;\n external_id?: string;\n}\n\nexport interface RefBody {\n kind: string;\n id: string;\n version?: string;\n}\n\nexport interface ReleaseDates {\n dates: DateCount[];\n next_cursor?: string;\n}\n\nexport interface ReleaseDay {\n date: string;\n contents: Card[];\n filtered_count: number;\n filtered_entities: ReleaseFilteredEntity[];\n}\n\nexport interface ReleaseFilteredEntity {\n entity: GroupCard;\n count: number;\n}\n\nexport interface Rendition {\n url: string;\n w: number;\n h: number;\n}\n\nexport interface Request {\n content: ContentInput;\n entities?: EntityReference[];\n archive: Archive;\n publish?: \"draft\" | \"when_ready\";\n publish_at?: string;\n create_missing_entities?: boolean;\n source?: Source;\n}\n\nexport interface RequestReply {\n method: string;\n url: string;\n headers: Record<string, string>;\n expires: string;\n}\n\nexport interface ResolveInput {\n decision: \"approve\" | \"reject\" | \"review\";\n revision: number;\n reason?: string;\n}\n\nexport interface Resolved {\n tenant_id: string;\n content_kind: string;\n content_id: string;\n content_version_id?: string;\n code: string;\n slug: string;\n slugs?: Record<string, string>;\n path: string;\n version_id?: string;\n}\n\nexport interface Restored {\n restored: boolean;\n}\n\nexport interface Result {\n written: Record<string, number>;\n skipped?: Record<string, number>;\n failed: RecordFailure[];\n ids: Record<string, Record<string, string>>;\n}\n\nexport interface ReviewOutcome {\n decision: \"approve\" | \"reject\" | \"review\";\n}\n\nexport interface Rule {\n level: \"group\" | \"group_ppv\" | \"ppv\" | \"public\" | \"tier\";\n tiers?: string[];\n group_id?: string;\n preview?: Preview;\n free_after?: string;\n}\n\nexport interface Sale {\n key: string;\n target: Target;\n terms: Terms;\n price_id?: string;\n}\n\nexport interface Segment {\n position: number;\n title?: string;\n start: number;\n end: number;\n release_at?: string;\n released: boolean;\n}\n\nexport interface SegmentsInput {\n segments: Segment[];\n}\n\nexport interface SignalInput {\n content_id: string;\n version_id?: string;\n type: string;\n event_id: string;\n revision?: number;\n occurred_at: string;\n render_id?: string;\n surface?: string;\n position?: number;\n activity_token?: string;\n}\n\nexport interface SignalRecord {\n target: TargetRef;\n user_id?: string;\n anon_key?: string;\n type: string;\n event_id: string;\n revision?: number;\n occurred_at: string;\n}\n\nexport interface Signals {\n session?: string;\n signals: SignalInput[];\n}\n\nexport interface SitemapAlias {\n language: string;\n path: string;\n image?: string;\n}\n\nexport interface SitemapEntry {\n id: string;\n code: string;\n path: string;\n lastmod: string;\n languages: SitemapAlias[];\n}\n\nexport interface SitemapPage {\n entries: SitemapEntry[];\n next_cursor?: string;\n}\n\nexport interface Source {\n provider: string;\n id: string;\n url?: string;\n}\n\nexport interface StagedCopy {\n path: string;\n blob: string;\n size: number;\n}\n\nexport interface Target {\n kind: \"content\" | \"group\" | \"version\";\n id: string;\n content_id?: string;\n}\n\nexport interface TargetRef {\n content?: Ref;\n version?: Ref;\n group?: Ref;\n comment?: Ref;\n}\n\nexport interface Terms {\n amount: string;\n currency: string;\n access_hours?: number;\n renew_hours?: number;\n}\n\nexport interface TicketBody {\n ticket: string;\n}\n\nexport interface TopContents {\n contents: RankedContent[];\n}\n\nexport interface Total {\n public: number;\n tiers: Record<string, number>;\n languages: Record<string, LanguageTotal>;\n}\n\nexport interface Totals {\n kinds: Record<string, Total>;\n}\n\nexport interface Typeahead {\n contents: Card[];\n entities: GroupCard[];\n}\n\nexport interface UploadLimits {\n files_per_hour?: number;\n bytes_per_day?: number;\n quota_bytes?: number;\n}\n\nexport interface UploadRule {\n path: string;\n types: string[];\n max_bytes: number;\n max?: number;\n named?: boolean;\n page?: boolean;\n body?: boolean;\n frames?: string;\n aspect?: string;\n min_width?: number;\n video?: VideoLimits;\n min_aspect?: number;\n max_aspect?: number;\n}\n\nexport interface Version {\n id: string;\n code: string;\n position: number;\n languages: string[];\n traits: string[];\n label?: string;\n title?: string;\n description?: string;\n state?: ContentState;\n publish_at?: string;\n published_at?: string;\n live: boolean;\n access?: Rule;\n attributes: Record<string, unknown>;\n pages?: number;\n duration_ms?: number;\n width?: number;\n height?: number;\n has_audio: boolean;\n ordinal?: number;\n cover?: CatalogCover;\n segments: Segment[];\n decision: Decision;\n text?: Record<string, VersionText>;\n offer?: Offer;\n viewer?: ViewerState;\n}\n\nexport interface VersionFork {\n from: string;\n playback?: boolean;\n segments?: boolean;\n}\n\nexport interface VersionInput {\n languages?: string[];\n traits?: string[];\n label?: string;\n state?: VersionState;\n publish_at?: string;\n access?: Rule;\n clear_access?: boolean;\n attributes?: Record<string, unknown>;\n text?: Record<string, VersionText>;\n segments?: Segment[];\n ordinal?: number;\n cover?: string;\n fork?: VersionFork;\n}\n\nexport interface VersionRecord {\n external_id: string;\n id?: string;\n code?: string;\n languages: string[];\n traits?: string[];\n label?: string;\n state?: string;\n publish_at?: string;\n published_at?: string;\n deleted_at?: string;\n access?: Rule;\n attributes?: Record<string, unknown>;\n ordinal?: number;\n cover?: string;\n text?: Record<string, VersionText>;\n segments?: Segment[];\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface VersionRules {\n languages: string;\n traits?: string[];\n hidden?: boolean;\n}\n\nexport interface VersionText {\n title?: string;\n description?: string;\n}\n\nexport interface VideoLimits {\n max_seconds?: number;\n max_fps?: number;\n max_pixels?: number;\n max_work?: number;\n}\n\nexport interface ViewerState {\n favorited: boolean;\n seen: boolean;\n completed: boolean;\n progress: number;\n progress_max: number;\n resume?: string;\n last_read_at?: string;\n}\n\nexport interface VoteRecord {\n poll: Ref;\n option: Ref;\n user_id?: string;\n ip?: string;\n created_at?: string;\n}\n\nexport interface WatchedRange {\n from_ms: number;\n to_ms: number;\n}\n\nexport interface Written {\n count: number;\n}\n"],"mappings":";AAOA,IAAa,IAAiB,UACjB,IAAgB,SAChB,IAAgB"}
@@ -0,0 +1,40 @@
1
+ import { Card, EngagementSnapshot, ViewerState } from './generated/wire.js';
2
+ export type GuestReadingSnapshot = EngagementSnapshot & {
3
+ kind?: string;
4
+ };
5
+ interface Checkpoint extends Omit<GuestReadingSnapshot, "activity_token"> {
6
+ saved_at: number;
7
+ }
8
+ export interface GuestReadingItem {
9
+ id: string;
10
+ kind?: string;
11
+ at: number;
12
+ checkpoints: readonly Checkpoint[];
13
+ }
14
+ /** A separate key per cumulative segment avoids cross-tab read/modify/write loss. No titles, media URLs or account data are stored. */
15
+ export declare class GuestReadingHistory {
16
+ private readonly prefix;
17
+ private readonly browser?;
18
+ private rows;
19
+ private encoded;
20
+ private memory;
21
+ private readonly listeners;
22
+ constructor(prefix: string, browser?: Window | undefined);
23
+ readonly snapshot: () => readonly GuestReadingItem[];
24
+ readonly subscribe: (listener: () => void) => (() => void);
25
+ record(snapshot: GuestReadingSnapshot): void;
26
+ clear(filter?: {
27
+ content_id?: string;
28
+ kind?: string;
29
+ }): void;
30
+ private readonly storage;
31
+ private read;
32
+ private write;
33
+ private remove;
34
+ private prune;
35
+ private sync;
36
+ }
37
+ /** Hydrate through ordinary public discovery before applying local progress: cached IDs never bypass current domain/access restrictions. */
38
+ export declare function guestStanding(card: Card, item: GuestReadingItem): ViewerState;
39
+ export declare function guestReadingHistory(mount: string): GuestReadingHistory;
40
+ export {};
@@ -0,0 +1,144 @@
1
+ //#region src/client/guest-reading-history.ts
2
+ var e = Object.freeze([]), t = 100, n = 2e3, r = (e, t = 2 ** 53 - 1) => typeof e == "number" && Number.isSafeInteger(e) && e >= 0 && e <= t, i = class {
3
+ prefix;
4
+ browser;
5
+ rows = e;
6
+ encoded = "[]";
7
+ memory = /* @__PURE__ */ new Map();
8
+ listeners = /* @__PURE__ */ new Set();
9
+ constructor(e, t) {
10
+ this.prefix = e, this.browser = t, this.sync();
11
+ }
12
+ snapshot = () => this.rows;
13
+ subscribe = (e) => (this.sync(), this.listeners.size || this.browser?.addEventListener("storage", this.storage), this.listeners.add(e), () => {
14
+ this.listeners.delete(e), this.listeners.size || this.browser?.removeEventListener("storage", this.storage);
15
+ });
16
+ record(e) {
17
+ if (!e.content_id || !e.visit_id || !e.segment_id || !r(e.revision) || !r(e.active_ms, 6e5) || !e.active_ms || (e.pages?.length ?? 0) > 128 || (e.watched?.length ?? 0) > 256 || e.pages?.some((e) => !r(e.index) || !r(e.active_ms, 6e5) || e.ranges.length > 16 || e.ranges.some((e) => !r(e.from, 1e4) || !r(e.to, 1e4) || e.from >= e.to)) || e.watched?.some((e) => !r(e.from_ms, 864e5) || !r(e.to_ms, 864e5) || e.from_ms >= e.to_ms)) return;
18
+ let { activity_token: t, ...n } = e, i = this.prefix + encodeURIComponent(JSON.stringify([
19
+ e.content_id,
20
+ e.version_id ?? "",
21
+ e.visit_id,
22
+ e.segment_id
23
+ ])), a = this.read().get(i);
24
+ if (a && a.revision >= e.revision) return;
25
+ let o = {
26
+ ...n,
27
+ saved_at: Date.now()
28
+ };
29
+ JSON.stringify(o).length > 65536 || (this.write(i, o), this.prune(), this.sync());
30
+ }
31
+ clear(e = {}) {
32
+ for (let [t, n] of this.read()) (!e.content_id || e.content_id === n.content_id) && (!e.kind || e.kind === n.kind) && this.remove(t);
33
+ this.sync();
34
+ }
35
+ storage = (e) => {
36
+ (e.key === null || e.key.startsWith(this.prefix)) && this.sync();
37
+ };
38
+ read() {
39
+ if (!this.browser) return new Map(this.memory);
40
+ let e = new Map(this.memory);
41
+ try {
42
+ for (let t = 0; t < this.browser.localStorage.length; t++) {
43
+ let n = this.browser.localStorage.key(t);
44
+ if (n?.startsWith(this.prefix)) try {
45
+ let t = this.browser.localStorage.getItem(n);
46
+ if (!t || t.length > 65536) continue;
47
+ let i = JSON.parse(t);
48
+ i && (!i.pages || Array.isArray(i.pages) && i.pages.length <= 128 && i.pages.every((e) => e && r(e.index) && r(e.active_ms, 6e5) && Array.isArray(e.ranges) && e.ranges.length <= 16 && e.ranges.every((e) => e && r(e.from, 1e4) && r(e.to, 1e4) && e.from < e.to))) && (!i.watched || Array.isArray(i.watched) && i.watched.length <= 256 && i.watched.every((e) => e && r(e.from_ms, 864e5) && r(e.to_ms, 864e5) && e.from_ms < e.to_ms)) && typeof i.content_id == "string" && typeof i.visit_id == "string" && typeof i.segment_id == "string" && r(i.revision) && r(i.saved_at) && r(i.active_ms, 6e5) && i.active_ms > 0 && e.set(n, i);
49
+ } catch {}
50
+ }
51
+ } catch {}
52
+ return e;
53
+ }
54
+ write(e, t) {
55
+ try {
56
+ if (this.browser) {
57
+ this.browser.localStorage.setItem(e, JSON.stringify(t)), this.memory.delete(e);
58
+ return;
59
+ }
60
+ } catch {}
61
+ this.memory.set(e, t);
62
+ }
63
+ remove(e) {
64
+ this.memory.delete(e);
65
+ try {
66
+ this.browser?.localStorage.removeItem(e);
67
+ } catch {}
68
+ }
69
+ prune() {
70
+ let e = /* @__PURE__ */ new Map();
71
+ for (let [t, n] of this.read()) {
72
+ let r = e.get(n.content_id) ?? {
73
+ keys: [],
74
+ at: n.saved_at
75
+ };
76
+ r.keys.push(t), r.at = Math.max(r.at, n.saved_at), e.set(n.content_id, r);
77
+ }
78
+ let r = 0, i = 0;
79
+ for (let a of [...e.values()].sort((e, t) => t.at - e.at)) if (r >= t || i + a.keys.length > n) for (let e of a.keys) this.remove(e);
80
+ else r++, i += a.keys.length;
81
+ }
82
+ sync() {
83
+ let e = /* @__PURE__ */ new Map();
84
+ for (let t of this.read().values()) {
85
+ let n = e.get(t.content_id) ?? {
86
+ id: t.content_id,
87
+ kind: t.kind,
88
+ at: t.saved_at,
89
+ checkpoints: []
90
+ };
91
+ n.at = Math.max(n.at, t.saved_at), n.checkpoints.push(t), e.set(n.id, n);
92
+ }
93
+ for (let t of e.values()) t.checkpoints.sort((e, t) => e.visit_id.localeCompare(t.visit_id) || e.segment_id.localeCompare(t.segment_id));
94
+ let t = [...e.values()].sort((e, t) => t.at - e.at || e.id.localeCompare(t.id)), n = JSON.stringify(t);
95
+ if (n !== this.encoded) {
96
+ this.encoded = n, this.rows = Object.freeze(t.map((e) => Object.freeze(e)));
97
+ for (let e of this.listeners) try {
98
+ e();
99
+ } catch {}
100
+ }
101
+ }
102
+ };
103
+ function a(e, t) {
104
+ let n = t.checkpoints.filter((t) => !t.version_id || t.version_id === e.version.id), r = /* @__PURE__ */ new Map(), i = [];
105
+ for (let e of n) {
106
+ for (let t of e.pages ?? []) {
107
+ let e = r.get(t.index) ?? {
108
+ active: 0,
109
+ ranges: []
110
+ };
111
+ e.active += t.active_ms, e.ranges.push(...t.ranges), r.set(t.index, e);
112
+ }
113
+ i.push(...(e.watched ?? []).map((e) => ({
114
+ from: e.from_ms,
115
+ to: e.to_ms
116
+ })));
117
+ }
118
+ let a = (e) => {
119
+ let t = 0, n = 0;
120
+ for (let r of e.sort((e, t) => e.from - t.from)) n += Math.max(0, r.to - Math.max(t, r.from)), t = Math.max(t, r.to);
121
+ return n;
122
+ }, o = e.version.pages ?? 0, s = o ? o * 100 : Math.ceil((e.version.duration_ms ?? 0) / 1e3), c = o ? [...r].reduce((e, [t, n]) => e + (t < o && n.active >= 1e3 ? a(n.ranges) / 100 : 0), 0) : a(i) / 1e3, l = n.toSorted((e, t) => t.saved_at - e.saved_at)[0];
123
+ return {
124
+ favorited: e.viewer?.favorited ?? !1,
125
+ seen: n.some((e) => e.active_ms > 0),
126
+ completed: s > 0 && c >= s * .9,
127
+ progress: Math.min(s, Math.floor(c)),
128
+ progress_max: s,
129
+ resume: l?.resume
130
+ };
131
+ }
132
+ var o = /* @__PURE__ */ new WeakMap();
133
+ function s(e) {
134
+ let t = typeof window > "u" ? void 0 : window, n = `contentkit.reading.v1:${encodeURIComponent(e)}:`;
135
+ if (!t) return new i(n);
136
+ let r = o.get(t);
137
+ r || (r = /* @__PURE__ */ new Map(), o.set(t, r));
138
+ let a = r.get(n);
139
+ return a || (a = new i(n, t), r.set(n, a)), a;
140
+ }
141
+ //#endregion
142
+ export { i as GuestReadingHistory, s as guestReadingHistory, a as guestStanding };
143
+
144
+ //# sourceMappingURL=guest-reading-history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guest-reading-history.js","names":[],"sources":["../../src/client/guest-reading-history.ts"],"sourcesContent":["import type { Card, EngagementSnapshot, ViewerState } from \"./generated/wire.js\";\n\nexport type GuestReadingSnapshot = EngagementSnapshot & { kind?: string };\ninterface Checkpoint extends Omit<GuestReadingSnapshot, \"activity_token\"> { saved_at: number }\nexport interface GuestReadingItem { id: string; kind?: string; at: number; checkpoints: readonly Checkpoint[] }\nconst NONE: readonly GuestReadingItem[] = Object.freeze([]);\nconst MAX_CONTENTS = 100, MAX_SEGMENTS = 2000;\nconst integer = (n: unknown, max = Number.MAX_SAFE_INTEGER): n is number => typeof n === \"number\" && Number.isSafeInteger(n) && n >= 0 && n <= max;\n\n/** A separate key per cumulative segment avoids cross-tab read/modify/write loss. No titles, media URLs or account data are stored. */\nexport class GuestReadingHistory {\n private rows: readonly GuestReadingItem[] = NONE;\n private encoded = \"[]\";\n private memory = new Map<string, Checkpoint>();\n private readonly listeners = new Set<() => void>();\n constructor(private readonly prefix: string, private readonly browser?: Window) { this.sync(); }\n readonly snapshot = (): readonly GuestReadingItem[] => this.rows;\n readonly subscribe = (listener: () => void): (() => void) => {\n this.sync();\n if (!this.listeners.size) this.browser?.addEventListener(\"storage\", this.storage);\n this.listeners.add(listener);\n return () => { this.listeners.delete(listener); if (!this.listeners.size) this.browser?.removeEventListener(\"storage\", this.storage); };\n };\n record(snapshot: GuestReadingSnapshot): void {\n if (!snapshot.content_id || !snapshot.visit_id || !snapshot.segment_id || !integer(snapshot.revision) || !integer(snapshot.active_ms, 600_000) || !snapshot.active_ms) return;\n if ((snapshot.pages?.length ?? 0) > 128 || (snapshot.watched?.length ?? 0) > 256) return;\n if (snapshot.pages?.some(p => !integer(p.index) || !integer(p.active_ms, 600_000) || p.ranges.length > 16 || p.ranges.some(r => !integer(r.from, 10_000) || !integer(r.to, 10_000) || r.from >= r.to))) return;\n if (snapshot.watched?.some(r => !integer(r.from_ms, 86_400_000) || !integer(r.to_ms, 86_400_000) || r.from_ms >= r.to_ms)) return;\n const { activity_token: _token, ...local } = snapshot;\n const key = this.prefix + encodeURIComponent(JSON.stringify([snapshot.content_id, snapshot.version_id ?? \"\", snapshot.visit_id, snapshot.segment_id]));\n const existing = this.read().get(key);\n if (existing && existing.revision >= snapshot.revision) return;\n const value = { ...local, saved_at: Date.now() };\n if (JSON.stringify(value).length > 64 * 1024) return;\n this.write(key, value);\n this.prune(); this.sync();\n }\n clear(filter: { content_id?: string; kind?: string } = {}): void {\n for (const [key, row] of this.read()) if ((!filter.content_id || filter.content_id === row.content_id) && (!filter.kind || filter.kind === row.kind)) this.remove(key);\n this.sync();\n }\n private readonly storage = (event: StorageEvent): void => { if (event.key === null || event.key.startsWith(this.prefix)) this.sync(); };\n private read(): Map<string, Checkpoint> {\n if (!this.browser) return new Map(this.memory);\n const out = new Map(this.memory);\n try {\n for (let i = 0; i < this.browser.localStorage.length; i++) {\n const key = this.browser.localStorage.key(i);\n if (!key?.startsWith(this.prefix)) continue;\n try {\n const raw = this.browser.localStorage.getItem(key);\n if (!raw || raw.length > 64 * 1024) continue;\n const row = JSON.parse(raw) as Checkpoint | null;\n if (row && (!row.pages || Array.isArray(row.pages) && row.pages.length <= 128 && row.pages.every(p => p && integer(p.index) && integer(p.active_ms, 600_000) && Array.isArray(p.ranges) && p.ranges.length <= 16 && p.ranges.every(r => r && integer(r.from, 10_000) && integer(r.to, 10_000) && r.from < r.to))) && (!row.watched || Array.isArray(row.watched) && row.watched.length <= 256 && row.watched.every(r => r && integer(r.from_ms, 86_400_000) && integer(r.to_ms, 86_400_000) && r.from_ms < r.to_ms)) && typeof row.content_id === \"string\" && typeof row.visit_id === \"string\" && typeof row.segment_id === \"string\" && integer(row.revision) && integer(row.saved_at) && integer(row.active_ms, 600_000) && row.active_ms > 0) out.set(key, row);\n } catch { /* Ignore a malformed browser-only checkpoint. */ }\n }\n } catch { /* Storage can be unavailable; this client keeps bounded memory. */ }\n return out;\n }\n private write(key: string, row: Checkpoint): void {\n try { if (this.browser) { this.browser.localStorage.setItem(key, JSON.stringify(row)); this.memory.delete(key); return; } } catch { /* Quota/privacy mode. */ }\n this.memory.set(key, row);\n }\n private remove(key: string): void { this.memory.delete(key); try { this.browser?.localStorage.removeItem(key); } catch { /* Browser policy. */ } }\n private prune(): void {\n const groups = new Map<string, { keys: string[]; at: number }>();\n for (const [key, row] of this.read()) {\n const value = groups.get(row.content_id) ?? { keys: [], at: row.saved_at };\n value.keys.push(key); value.at = Math.max(value.at, row.saved_at); groups.set(row.content_id, value);\n }\n let contents = 0, segments = 0;\n for (const value of [...groups.values()].sort((a, b) => b.at - a.at)) {\n // Evict a whole older content item; never silently turn a retained history item into partial coverage.\n if (contents >= MAX_CONTENTS || segments + value.keys.length > MAX_SEGMENTS) {\n for (const key of value.keys) this.remove(key);\n } else { contents++; segments += value.keys.length; }\n }\n }\n\n private sync(): void {\n const byContent = new Map<string, { id: string; kind?: string; at: number; checkpoints: Checkpoint[] }>();\n for (const row of this.read().values()) {\n const item = byContent.get(row.content_id) ?? { id: row.content_id, kind: row.kind, at: row.saved_at, checkpoints: [] };\n item.at = Math.max(item.at, row.saved_at); item.checkpoints.push(row); byContent.set(item.id, item);\n }\n for (const row of byContent.values()) row.checkpoints.sort((a, b) => a.visit_id.localeCompare(b.visit_id) || a.segment_id.localeCompare(b.segment_id));\n const rows = [...byContent.values()].sort((a, b) => b.at - a.at || a.id.localeCompare(b.id));\n const encoded = JSON.stringify(rows);\n if (encoded === this.encoded) return;\n this.encoded = encoded; this.rows = Object.freeze(rows.map(row => Object.freeze(row)));\n for (const listener of this.listeners) { try { listener(); } catch { /* Observers do not own persistence. */ } }\n }\n}\n\n/** Hydrate through ordinary public discovery before applying local progress: cached IDs never bypass current domain/access restrictions. */\nexport function guestStanding(card: Card, item: GuestReadingItem): ViewerState {\n const rows = item.checkpoints.filter(row => !row.version_id || row.version_id === card.version.id);\n const pages = new Map<number, { active: number; ranges: { from: number; to: number }[] }>();\n const watched: { from: number; to: number }[] = [];\n for (const row of rows) {\n for (const page of row.pages ?? []) {\n const value = pages.get(page.index) ?? { active: 0, ranges: [] };\n value.active += page.active_ms; value.ranges.push(...page.ranges); pages.set(page.index, value);\n }\n watched.push(...(row.watched ?? []).map(r => ({ from: r.from_ms, to: r.to_ms })));\n }\n const unionLength = (ranges: { from: number; to: number }[]) => {\n let end = 0, n = 0;\n for (const r of ranges.sort((a, b) => a.from - b.from)) { n += Math.max(0, r.to - Math.max(end, r.from)); end = Math.max(end, r.to); }\n return n;\n };\n const pageCount = card.version.pages ?? 0;\n const total = pageCount ? pageCount * 100 : Math.ceil((card.version.duration_ms ?? 0) / 1000);\n const progress = pageCount ? [...pages].reduce((n, [index, page]) => n + (index < pageCount && page.active >= 1000 ? unionLength(page.ranges) / 100 : 0), 0) : unionLength(watched) / 1000;\n const newest = rows.toSorted((a, b) => b.saved_at - a.saved_at)[0];\n return { favorited: card.viewer?.favorited ?? false, seen: rows.some(row => row.active_ms > 0), completed: total > 0 && progress >= total * 0.9,\n progress: Math.min(total, Math.floor(progress)), progress_max: total, resume: newest?.resume };\n}\n\nconst stores = new WeakMap<Window, Map<string, GuestReadingHistory>>();\nexport function guestReadingHistory(mount: string): GuestReadingHistory {\n const browser = typeof window === \"undefined\" ? undefined : window;\n const key = `contentkit.reading.v1:${encodeURIComponent(mount)}:`;\n if (!browser) return new GuestReadingHistory(key);\n let scoped = stores.get(browser); if (!scoped) { scoped = new Map(); stores.set(browser, scoped); }\n let store = scoped.get(key); if (!store) { store = new GuestReadingHistory(key, browser); scoped.set(key, store); }\n return store;\n}\n"],"mappings":"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"}
@@ -11,12 +11,12 @@ export { BansClient } from './content/bans.js';
11
11
  export { ModerationClient, type HeldQuery } from './content/moderation.js';
12
12
  export { reactionVerb, sameTarget, type BanScope, type ContentChange, type Decision, type HeldKind, type Reaction, type RuleSet, type Sort, type Target } from './content/types.js';
13
13
  export { EntitiesClient, type EntityImageSlot, type EntityQuery, type ManageEntityQuery, type MemberQuery, type MyEntityQuery } from './entities.js';
14
- export { DiscoveryClient, popularQuery, popularBetween, type AccessMode, type CardQuery, type ContentFilterQuery, type ContentQuery, type HistoryQuery, type ListSort, type Period, type PopularPeriod, type PopularDateRange, type PopularQuery, type RailQuery, type ReaderQuery, type RecentSearchesQuery, type ReleaseDatesQuery, type DailyReleasesQuery, type SearchQuery, type TypeaheadQuery, } from './discovery.js';
14
+ export { DiscoveryClient, popularQuery, popularBetween, type AccessMode, type AdminSuggestionsQuery, type CardQuery, type ContentFilterQuery, type ContentQuery, type HistoryQuery, type ListSort, type Period, type PopularPeriod, type PopularDateRange, type PopularQuery, type RailQuery, type ReaderQuery, type RecentSearchesQuery, type ReleaseDatesQuery, type DailyReleasesQuery, type SearchQuery, type TypeaheadQuery, } from './discovery.js';
15
15
  export { VersionsClient, isPending } from './versions.js';
16
16
  export { emptyReaderMeta, matchAudio, readerMetaProblems, readerNames, type AudioMatch, type ReaderMetaProblem, type ReaderNames } from './reader-meta.js';
17
17
  export { OffersClient } from './offers.js';
18
18
  export { StatsClient, type ActivityQuery, type TopQuery } from './stats.js';
19
- export { Beacons, eventId, readerSession, type Attribution, type BeaconOptions, type ViewSession } from './beacons.js';
19
+ export { Beacons, eventId, readerSession, type Attribution, type BeaconOptions } from './beacons.js';
20
20
  export { LETTERS, attributeInput, fold, fromLocalInput, humanize, letterOf, parseAttribute, parseAttributes, slugify, toLocalInput } from './group-fields.js';
21
21
  export { CodesClient } from './codes.js';
22
22
  export { NotificationsClient, type NotificationItem } from './notifications.js';
@@ -42,3 +42,5 @@ export { formatDuration, galleryItems, isAudioType, isImageType, isVideoType, is
42
42
  export { ABR_DEFAULTS, NETWORK_FAILURES_BEFORE_ERROR, abrHlsConfig, capRung, classifyHlsError, classifyMediaError, hlsConfig, initialEstimate, expiryDelay, REFRESH_BEFORE_EXPIRY, refreshable, startRung, statusKind, type AbrPolicy, type ConnectionHint, type HlsErrorLike, type Rung, type PlaybackError, type PlaybackErrorKind, } from './playback.js';
43
43
  export { PLAYBACK_SPEEDS, PLAYER_TRACKS_KEY, PLAYER_VOLUME_KEY, parseSpriteVtt, playerKeyAction, resumeAt, type PlayerAction, type PlayerTrack, type SpriteCue, type TrackPrefs, type VolumePrefs, } from './player.js';
44
44
  export * from './generated/wire.js';
45
+ export { EngagementTracker, type EngagementTrackerOptions, type ReadingObservation, type VisiblePage } from './engagement.js';
46
+ export { GuestReadingHistory, guestStanding, type GuestReadingItem, type GuestReadingSnapshot } from './guest-reading-history.js';
@@ -8,8 +8,8 @@ export interface ActivityQuery {
8
8
  }
9
9
  export interface TopQuery {
10
10
  kind: string;
11
- /** views (the default) or comments. */
12
- metric?: "views" | "comments";
11
+ /** Distinct people with measured attention (the default), or published comments. */
12
+ metric?: "readers" | "comments";
13
13
  /** 30d by default. */
14
14
  period?: Period;
15
15
  access?: readonly ("public" | "tier" | "group" | "ppv" | "group_ppv")[];
@@ -19,13 +19,13 @@ export interface TopQuery {
19
19
  /** 10 by default, at most 100. */
20
20
  limit?: number;
21
21
  }
22
- /** Content statistics: staff activity and rankings (root:content:view-restricted), and the signed-in reader's own. */
22
+ /** Content statistics: staff activity and rankings (content statistics permission), and the signed-in reader's own. */
23
23
  export declare class StatsClient {
24
24
  private readonly http;
25
25
  constructor(http: Http);
26
- /** A kind's views per UTC day, newest first: view sessions, distinct viewers and signed-in viewers. */
26
+ /** A kind's measured activity per UTC day: distinct engaged people, signed-in people and focused active milliseconds. */
27
27
  activity(q: ActivityQuery, signal?: AbortSignal): Promise<Activity>;
28
- /** A kind's live, listed content ranked by views or published comments over a period. */
28
+ /** A kind's live, listed content ranked by distinct engaged people or published comments over a period. */
29
29
  top(q: TopQuery, signal?: AbortSignal): Promise<TopContents>;
30
30
  /** The signed-in reader's statistics: contents finished per kind, comments, reactions received and elapsed access per tier when billing supplies its history. */
31
31
  mine(signal?: AbortSignal): Promise<MyStats>;