@openrails/contentkit-ui 0.82.0 → 0.85.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 (124) hide show
  1. package/README.md +11 -3
  2. package/dist/client/beacons.d.ts +8 -5
  3. package/dist/client/beacons.js +15 -7
  4. package/dist/client/beacons.js.map +1 -1
  5. package/dist/client/content/moderation.d.ts +14 -2
  6. package/dist/client/content/moderation.js +34 -0
  7. package/dist/client/content/moderation.js.map +1 -1
  8. package/dist/client/content/types.d.ts +13 -0
  9. package/dist/client/content/types.js.map +1 -1
  10. package/dist/client/discovery.d.ts +7 -1
  11. package/dist/client/discovery.js.map +1 -1
  12. package/dist/client/generated/error-codes.d.ts +1 -1
  13. package/dist/client/generated/error-codes.js +8 -0
  14. package/dist/client/generated/error-codes.js.map +1 -1
  15. package/dist/client/generated/routes.d.ts +90 -12
  16. package/dist/client/generated/routes.js +118 -1
  17. package/dist/client/generated/routes.js.map +1 -1
  18. package/dist/client/generated/wire.d.ts +74 -0
  19. package/dist/client/generated/wire.js.map +1 -1
  20. package/dist/client/index.d.ts +2 -1
  21. package/dist/client/reader-meta.d.ts +27 -0
  22. package/dist/client/reader-meta.js +99 -0
  23. package/dist/client/reader-meta.js.map +1 -0
  24. package/dist/client/versions.d.ts +1 -1
  25. package/dist/client/versions.js +7 -2
  26. package/dist/client/versions.js.map +1 -1
  27. package/dist/client.js +2 -1
  28. package/dist/components/admin/reader-manifest.d.ts +18 -0
  29. package/dist/components/admin/reader-manifest.js +490 -0
  30. package/dist/components/admin/reader-manifest.js.map +1 -0
  31. package/dist/components/content/card.js +1 -1
  32. package/dist/components/content/card.js.map +1 -1
  33. package/dist/components/content/editors.d.ts +2 -1
  34. package/dist/components/content/editors.js +291 -256
  35. package/dist/components/content/editors.js.map +1 -1
  36. package/dist/components/groups/banner.d.ts +1 -1
  37. package/dist/components/groups/banner.js +1 -1
  38. package/dist/components/groups/banner.js.map +1 -1
  39. package/dist/components/groups/editor.js +3 -3
  40. package/dist/components/groups/editor.js.map +1 -1
  41. package/dist/components/groups/parts.d.ts +2 -2
  42. package/dist/components/groups/parts.js +71 -72
  43. package/dist/components/groups/parts.js.map +1 -1
  44. package/dist/components/social/comments.js +59 -45
  45. package/dist/components/social/comments.js.map +1 -1
  46. package/dist/components/social/index.d.ts +1 -0
  47. package/dist/components/social/moderation.d.ts +5 -4
  48. package/dist/components/social/moderation.js +143 -130
  49. package/dist/components/social/moderation.js.map +1 -1
  50. package/dist/components/social/parts.js +22 -14
  51. package/dist/components/social/parts.js.map +1 -1
  52. package/dist/components/social/rules.d.ts +23 -0
  53. package/dist/components/social/rules.js +261 -0
  54. package/dist/components/social/rules.js.map +1 -0
  55. package/dist/index.d.ts +1 -0
  56. package/dist/index.js +26 -24
  57. package/dist/locales/admin/de.js +78 -0
  58. package/dist/locales/admin/de.js.map +1 -1
  59. package/dist/locales/admin/en.d.ts +78 -0
  60. package/dist/locales/admin/en.js +78 -0
  61. package/dist/locales/admin/en.js.map +1 -1
  62. package/dist/locales/admin/es.js +78 -0
  63. package/dist/locales/admin/es.js.map +1 -1
  64. package/dist/locales/admin/ja.js +78 -0
  65. package/dist/locales/admin/ja.js.map +1 -1
  66. package/dist/locales/admin/ko.js +78 -0
  67. package/dist/locales/admin/ko.js.map +1 -1
  68. package/dist/locales/admin/zh.js +78 -0
  69. package/dist/locales/admin/zh.js.map +1 -1
  70. package/dist/locales/de.js +3 -1
  71. package/dist/locales/de.js.map +1 -1
  72. package/dist/locales/discovery/de.js +2 -0
  73. package/dist/locales/discovery/de.js.map +1 -1
  74. package/dist/locales/discovery/en.d.ts +2 -0
  75. package/dist/locales/discovery/en.js +2 -0
  76. package/dist/locales/discovery/en.js.map +1 -1
  77. package/dist/locales/discovery/es.js +2 -0
  78. package/dist/locales/discovery/es.js.map +1 -1
  79. package/dist/locales/discovery/ja.js +2 -0
  80. package/dist/locales/discovery/ja.js.map +1 -1
  81. package/dist/locales/discovery/ko.js +2 -0
  82. package/dist/locales/discovery/ko.js.map +1 -1
  83. package/dist/locales/discovery/zh.js +2 -0
  84. package/dist/locales/discovery/zh.js.map +1 -1
  85. package/dist/locales/en.d.ts +85 -0
  86. package/dist/locales/en.js +3 -1
  87. package/dist/locales/en.js.map +1 -1
  88. package/dist/locales/es.js +3 -1
  89. package/dist/locales/es.js.map +1 -1
  90. package/dist/locales/ja.js +3 -1
  91. package/dist/locales/ja.js.map +1 -1
  92. package/dist/locales/ko.js +3 -1
  93. package/dist/locales/ko.js.map +1 -1
  94. package/dist/locales/social/de.js +3 -0
  95. package/dist/locales/social/de.js.map +1 -1
  96. package/dist/locales/social/en.d.ts +3 -0
  97. package/dist/locales/social/en.js +3 -0
  98. package/dist/locales/social/en.js.map +1 -1
  99. package/dist/locales/social/es.js +3 -0
  100. package/dist/locales/social/es.js.map +1 -1
  101. package/dist/locales/social/ja.js +3 -0
  102. package/dist/locales/social/ja.js.map +1 -1
  103. package/dist/locales/social/ko.js +3 -0
  104. package/dist/locales/social/ko.js.map +1 -1
  105. package/dist/locales/social/zh.js +3 -0
  106. package/dist/locales/social/zh.js.map +1 -1
  107. package/dist/locales/zh.js +3 -1
  108. package/dist/locales/zh.js.map +1 -1
  109. package/dist/react/admin.d.ts +1 -1
  110. package/dist/react/admin.js +2 -0
  111. package/dist/react/admin.js.map +1 -1
  112. package/dist/react/comments.d.ts +29 -1
  113. package/dist/react/comments.js +30 -2
  114. package/dist/react/comments.js.map +1 -1
  115. package/dist/react/context.d.ts +1 -1
  116. package/dist/react/context.js.map +1 -1
  117. package/dist/react/discovery.js +1 -1
  118. package/dist/react/discovery.js.map +1 -1
  119. package/dist/react/index.d.ts +1 -1
  120. package/dist/react/resources.js +6 -0
  121. package/dist/react/resources.js.map +1 -1
  122. package/dist/react.js +14 -14
  123. package/dist/styles.css +1 -1
  124. package/package.json +1 -1
@@ -12,6 +12,16 @@ export type ModerationState = "approved" | "held" | "rejected";
12
12
  export type ContentState = "draft" | "published" | "deleted";
13
13
  export type VersionState = "draft" | "published";
14
14
  export type Listing = "listed" | "members" | "unlisted";
15
+ export type AliasStatus = "found" | "not_found" | "gone";
16
+ export interface Activity {
17
+ days: ActivityDay[];
18
+ }
19
+ export interface ActivityDay {
20
+ date: string;
21
+ views: number;
22
+ viewers: number;
23
+ users: number;
24
+ }
15
25
  export interface AdminComment {
16
26
  id: string;
17
27
  reply_to_id?: string;
@@ -35,12 +45,31 @@ export interface AdminComment {
35
45
  content_version_id?: string;
36
46
  deleted_at?: string;
37
47
  }
48
+ export interface AliasKey {
49
+ source: string;
50
+ kind: string;
51
+ key: string;
52
+ }
53
+ export interface AliasLookup {
54
+ aliases: AliasKey[];
55
+ }
38
56
  export interface AliasRecord {
39
57
  kind: string;
40
58
  key: string;
41
59
  locator?: string;
42
60
  target: TargetRef;
43
61
  }
62
+ export interface AliasResult {
63
+ source: string;
64
+ kind: string;
65
+ key: string;
66
+ status: AliasStatus;
67
+ resolved?: Resolved;
68
+ locator?: string;
69
+ }
70
+ export interface AliasResults {
71
+ aliases: AliasResult[];
72
+ }
44
73
  export interface Anchor {
45
74
  id: string;
46
75
  page: string;
@@ -118,6 +147,7 @@ export interface Batch {
118
147
  votes?: VoteRecord[];
119
148
  answers?: AnswerRecord[];
120
149
  signals?: SignalRecord[];
150
+ deletes?: DeleteRecord[];
121
151
  }
122
152
  export interface Card {
123
153
  id: string;
@@ -224,6 +254,7 @@ export interface CommentRecord {
224
254
  export interface CommentStanding {
225
255
  can_comment: boolean;
226
256
  comments: string;
257
+ locked: boolean;
227
258
  ban?: BanNotice;
228
259
  anonymous: boolean;
229
260
  max_length: number;
@@ -275,6 +306,8 @@ export interface Content {
275
306
  creators: Creator[];
276
307
  groups: GroupSummary[];
277
308
  versions: Version[];
309
+ views: number;
310
+ viewer?: ViewerState;
278
311
  editor: boolean;
279
312
  text?: Record<string, CatalogText>;
280
313
  moderation?: ModerationState;
@@ -333,6 +366,7 @@ export interface ContentModel {
333
366
  kinds: Record<string, Kind>;
334
367
  group_kinds: Record<string, GroupKind>;
335
368
  content_filters: ContentFilter[];
369
+ signals: boolean;
336
370
  }
337
371
  export interface ContentPage {
338
372
  contents: Card[];
@@ -357,6 +391,8 @@ export interface ContentRecord {
357
391
  published_at?: string;
358
392
  deleted_at?: string;
359
393
  listing?: string;
394
+ comments?: string;
395
+ view_baseline?: number;
360
396
  access?: Rule;
361
397
  restrictions?: string[];
362
398
  attributes?: Record<string, unknown>;
@@ -432,6 +468,10 @@ export interface Decision {
432
468
  free_after?: string;
433
469
  offers?: Sale[];
434
470
  }
471
+ export interface DeleteRecord {
472
+ entity: string;
473
+ external_id: string;
474
+ }
435
475
  export interface Edge {
436
476
  from: string;
437
477
  relation: string;
@@ -650,6 +690,7 @@ export interface GroupDetail {
650
690
  edges: Edge[];
651
691
  counts: Count[];
652
692
  access?: GroupAccess;
693
+ offer?: Offer;
653
694
  }
654
695
  export interface GroupInput {
655
696
  id?: string;
@@ -719,6 +760,8 @@ export interface GroupSummary {
719
760
  kind: string;
720
761
  slug: string;
721
762
  name: string;
763
+ code?: string;
764
+ path?: string;
722
765
  }
723
766
  export interface GroupUpdate {
724
767
  slug?: string;
@@ -925,6 +968,12 @@ export interface MyGroupPage {
925
968
  groups: MyGroup[];
926
969
  next_cursor?: string;
927
970
  }
971
+ export interface MyStats {
972
+ completed: Record<string, number>;
973
+ comments: number;
974
+ comment_likes: number;
975
+ comment_dislikes: number;
976
+ }
928
977
  export interface Name {
929
978
  language: string;
930
979
  kind: "alias" | "name";
@@ -1182,6 +1231,12 @@ export interface PublishInput {
1182
1231
  export interface Published {
1183
1232
  items: Item[];
1184
1233
  }
1234
+ export interface RankedContent {
1235
+ id: string;
1236
+ title: string;
1237
+ path?: string;
1238
+ value: number;
1239
+ }
1185
1240
  export interface ReactionCounts {
1186
1241
  likes: number;
1187
1242
  dislikes: number;
@@ -1354,6 +1409,21 @@ export interface Signals {
1354
1409
  session?: string;
1355
1410
  signals: SignalInput[];
1356
1411
  }
1412
+ export interface SitemapAlias {
1413
+ language: string;
1414
+ path: string;
1415
+ }
1416
+ export interface SitemapEntry {
1417
+ id: string;
1418
+ code: string;
1419
+ path: string;
1420
+ lastmod: string;
1421
+ languages: SitemapAlias[];
1422
+ }
1423
+ export interface SitemapPage {
1424
+ entries: SitemapEntry[];
1425
+ next_cursor?: string;
1426
+ }
1357
1427
  export interface StagedCopy {
1358
1428
  path: string;
1359
1429
  blob: string;
@@ -1379,6 +1449,9 @@ export interface Terms {
1379
1449
  export interface TicketBody {
1380
1450
  ticket: string;
1381
1451
  }
1452
+ export interface TopContents {
1453
+ contents: RankedContent[];
1454
+ }
1382
1455
  export interface Total {
1383
1456
  public: number;
1384
1457
  tiers: Record<string, number>;
@@ -1433,6 +1506,7 @@ export interface Version {
1433
1506
  decision: Decision;
1434
1507
  text?: Record<string, VersionText>;
1435
1508
  offer?: Offer;
1509
+ viewer?: ViewerState;
1436
1510
  }
1437
1511
  export interface VersionFork {
1438
1512
  from: string;
@@ -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\";\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 AliasRecord {\n kind: string;\n key: string;\n locator?: string;\n target: TargetRef;\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 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 groups?: 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}\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 groups: 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}\n\nexport interface CardAccess {\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 CardVersion {\n id: string;\n languages: string[];\n traits: string[];\n label?: string;\n pages?: number;\n duration_ms?: number;\n}\n\nexport interface CatalogCover {\n image: string;\n url?: string;\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}\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 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 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 groups: GroupSummary[];\n versions: Version[];\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 ContentFilter {\n group: GroupRef;\n default_visible: boolean;\n labels?: Record<string, string>;\n}\n\nexport interface ContentFilterState {\n group: GroupCard;\n label: string;\n default_visible: boolean;\n visible: boolean;\n overridden: boolean;\n}\n\nexport interface ContentFilters {\n filters: ContentFilterState[];\n include_deleted: boolean;\n}\n\nexport interface ContentFiltersUpdate {\n filters: FilterSetting[];\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 groups: GroupCard[];\n}\n\nexport interface ContentModel {\n languages: string[];\n tiers: string[];\n kinds: Record<string, Kind>;\n group_kinds: Record<string, GroupKind>;\n content_filters: ContentFilter[];\n}\n\nexport interface ContentPage {\n contents: Card[];\n next_cursor?: string;\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 cover?: string;\n revision?: 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 access?: Rule;\n restrictions?: string[];\n attributes?: Record<string, unknown>;\n owner_group?: Ref;\n cover?: string;\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 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 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 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}\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 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 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 locked?: boolean;\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 FilterSetting {\n group_id: string;\n visible: boolean;\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 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 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 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}\n\nexport interface GroupInput {\n id?: string;\n kind: string;\n slug: string;\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 groups: GroupCard[];\n next_cursor?: string;\n}\n\nexport interface GroupRecord {\n external_id: string;\n id?: string;\n kind: string;\n slug: string;\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 GroupRef {\n kind: string;\n slug: string;\n}\n\nexport interface GroupSummary {\n id: string;\n kind: string;\n slug: string;\n name: string;\n}\n\nexport interface GroupUpdate {\n slug?: string;\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 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 status?: string;\n action_requested?: boolean;\n severity?: string;\n}\n\nexport interface Interaction {\n content?: Card;\n group?: 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 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 groups?: string[];\n attributes?: Record<string, Attribute>;\n sort?: string;\n draft_ttl?: number;\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 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 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 groups: MyGroup[];\n next_cursor?: string;\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 path?: string;\n blob?: string;\n create_id?: string;\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 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 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}\n\nexport interface PlanPage {\n name: string;\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 to: string;\n widths: number[];\n aspect?: string;\n min_width?: number;\n first?: number;\n default: 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 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 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 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 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 Rendition {\n url: string;\n w: number;\n h: number;\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}\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}\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 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 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 groups: 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 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 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 segments: Segment[];\n decision: Decision;\n text?: Record<string, VersionText>;\n offer?: Offer;\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 fork?: VersionFork;\n}\n\nexport interface VersionRecord {\n external_id: string;\n id?: 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 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 ActivityDay {\n date: string;\n views: number;\n viewers: number;\n users: number;\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 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 groups?: 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 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 groups: 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}\n\nexport interface CardAccess {\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 CardVersion {\n id: string;\n languages: string[];\n traits: string[];\n label?: string;\n pages?: number;\n duration_ms?: number;\n}\n\nexport interface CatalogCover {\n image: string;\n url?: string;\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}\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 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 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 groups: 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 ContentFilter {\n group: GroupRef;\n default_visible: boolean;\n labels?: Record<string, string>;\n}\n\nexport interface ContentFilterState {\n group: GroupCard;\n label: string;\n default_visible: boolean;\n visible: boolean;\n overridden: boolean;\n}\n\nexport interface ContentFilters {\n filters: ContentFilterState[];\n include_deleted: boolean;\n}\n\nexport interface ContentFiltersUpdate {\n filters: FilterSetting[];\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 groups: GroupCard[];\n}\n\nexport interface ContentModel {\n languages: string[];\n tiers: string[];\n kinds: Record<string, Kind>;\n group_kinds: Record<string, GroupKind>;\n content_filters: ContentFilter[];\n signals: boolean;\n}\n\nexport interface ContentPage {\n contents: Card[];\n next_cursor?: string;\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 cover?: string;\n revision?: 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 cover?: string;\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 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 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 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}\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 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 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 locked?: boolean;\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 FilterSetting {\n group_id: string;\n visible: boolean;\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 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 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 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 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 groups: GroupCard[];\n next_cursor?: string;\n}\n\nexport interface GroupRecord {\n external_id: string;\n id?: string;\n kind: string;\n slug: string;\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 GroupRef {\n kind: string;\n slug: 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 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 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 status?: string;\n action_requested?: boolean;\n severity?: string;\n}\n\nexport interface Interaction {\n content?: Card;\n group?: 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 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 groups?: string[];\n attributes?: Record<string, Attribute>;\n sort?: string;\n draft_ttl?: number;\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 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 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 groups: MyGroup[];\n next_cursor?: string;\n}\n\nexport interface MyStats {\n completed: 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 path?: string;\n blob?: string;\n create_id?: string;\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 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 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}\n\nexport interface PlanPage {\n name: string;\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 to: string;\n widths: number[];\n aspect?: string;\n min_width?: number;\n first?: number;\n default: 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 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 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 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 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 Rendition {\n url: string;\n w: number;\n h: number;\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}\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}\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}\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 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 groups: 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 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 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 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 fork?: VersionFork;\n}\n\nexport interface VersionRecord {\n external_id: string;\n id?: 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 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"}
@@ -9,10 +9,11 @@ export { FavoritesClient, type MineQuery } from './content/favorites.js';
9
9
  export { PollsClient, type PollAdminQuery, type PollQuery, type PollState } from './content/polls.js';
10
10
  export { BansClient } from './content/bans.js';
11
11
  export { ModerationClient, type HeldQuery } from './content/moderation.js';
12
- export { reactionVerb, sameTarget, type BanScope, type ContentChange, type Decision, type HeldKind, type Reaction, type Sort, type Target } from './content/types.js';
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 { GroupsClient, type GroupImageSlot, type GroupQuery, type MemberQuery, type MyGroupQuery } from './groups.js';
14
14
  export { DiscoveryClient, type AccessMode, type CardQuery, type ContentFilterQuery, type ContentQuery, type HistoryQuery, type ListSort, type Period, type RailQuery, type ReaderQuery, type RecentSearchesQuery, type ReleaseDatesQuery, type SearchQuery, type TypeaheadQuery, } from './discovery.js';
15
15
  export { VersionsClient, isPending } from './versions.js';
16
+ export { emptyReaderMeta, matchAudio, readerMetaProblems, readerNames, type AudioMatch, type ReaderMetaProblem, type ReaderNames } from './reader-meta.js';
16
17
  export { OffersClient } from './offers.js';
17
18
  export { Beacons, eventId, readerSession, type Attribution, type BeaconOptions, type ViewSession } from './beacons.js';
18
19
  export { LETTERS, attributeInput, fold, fromLocalInput, humanize, letterOf, parseAttribute, parseAttributes, slugify, toLocalInput } from './group-fields.js';
@@ -0,0 +1,27 @@
1
+ import { ForegroundCue, ReaderMeta, ReaderPlan } from './generated/wire.js';
2
+ /** What a version's reader metadata may name: its pages in reading order and its audio tracks. */
3
+ export interface ReaderNames {
4
+ pages: string[];
5
+ files: string[];
6
+ }
7
+ /** The names an editor's reader plan lists: every page of every segment, in order, and the playback tracks. */
8
+ export declare function readerNames(plan: ReaderPlan): ReaderNames;
9
+ /** An empty schema-1 reader metadata. */
10
+ export declare const emptyReaderMeta: () => ReaderMeta;
11
+ export interface AudioMatch {
12
+ /** One cue per matched file: on the anchor its stem names, else the page. */
13
+ foreground: ForegroundCue[];
14
+ unmatchedPages: string[];
15
+ unmatchedFiles: string[];
16
+ }
17
+ /** One foreground cue per audio file whose stem names an anchor (first) or a page, case-insensitively ("0002.mp3" plays at page "0002"). */
18
+ export declare function matchAudio(names: ReaderNames, anchors?: readonly string[]): AudioMatch;
19
+ /** Where a problem is: an anchor, a cue or the defaults, by index. */
20
+ export interface ReaderMetaProblem {
21
+ at: "anchors" | "background" | "foreground" | "defaults";
22
+ index: number;
23
+ /** id: empty or repeated; offset: outside 0-100; duration, seconds: not positive; page, anchor, file: names nothing; target: a foreground cue without a page or an anchor. */
24
+ problem: "id" | "offset" | "duration" | "seconds" | "page" | "anchor" | "file" | "target";
25
+ }
26
+ /** What the server refuses, and a foreground cue without a place: so an editor sees it before saving. */
27
+ export declare function readerMetaProblems(meta: ReaderMeta, names: ReaderNames): ReaderMetaProblem[];
@@ -0,0 +1,99 @@
1
+ //#region src/client/reader-meta.ts
2
+ function e(e) {
3
+ return {
4
+ pages: e.segments.flatMap((e) => (e.pages ?? []).map((e) => e.name)),
5
+ files: (e.playback?.tracks ?? []).map((e) => e.name)
6
+ };
7
+ }
8
+ var t = () => ({
9
+ schema_version: 1,
10
+ anchors: [],
11
+ background: [],
12
+ foreground: []
13
+ }), n = (e) => {
14
+ let t = e.lastIndexOf(".");
15
+ return (t > 0 ? e.slice(0, t) : e).toLowerCase();
16
+ };
17
+ function r(e, t = []) {
18
+ let r = /* @__PURE__ */ new Map();
19
+ for (let t of e.files) r.has(n(t)) || r.set(n(t), t);
20
+ let i = /* @__PURE__ */ new Set(), a = [];
21
+ for (let e of t) {
22
+ let t = r.get(n(e));
23
+ t && !i.has(t) && (a.push({
24
+ file: t,
25
+ anchor: e
26
+ }), i.add(t));
27
+ }
28
+ let o = [];
29
+ for (let t of e.pages) {
30
+ let e = r.get(n(t));
31
+ e && !i.has(e) ? (a.push({
32
+ file: e,
33
+ page: t
34
+ }), i.add(e)) : o.push(t);
35
+ }
36
+ return {
37
+ foreground: a,
38
+ unmatchedPages: o,
39
+ unmatchedFiles: e.files.filter((e) => !i.has(e))
40
+ };
41
+ }
42
+ function i(e, t) {
43
+ let n = [], r = new Set(t.pages), i = new Set(t.files), a = /* @__PURE__ */ new Set(), o = e.defaults?.auto_advance_seconds;
44
+ o !== void 0 && !(o > 0) && n.push({
45
+ at: "defaults",
46
+ index: 0,
47
+ problem: "seconds"
48
+ }), (e.anchors ?? []).forEach((e, t) => {
49
+ (!e.id.trim() || a.has(e.id)) && n.push({
50
+ at: "anchors",
51
+ index: t,
52
+ problem: "id"
53
+ }), a.add(e.id), r.has(e.page) || n.push({
54
+ at: "anchors",
55
+ index: t,
56
+ problem: "page"
57
+ }), e.offset_percent >= 0 && e.offset_percent <= 100 || n.push({
58
+ at: "anchors",
59
+ index: t,
60
+ problem: "offset"
61
+ }), e.duration_seconds !== void 0 && !(e.duration_seconds > 0) && n.push({
62
+ at: "anchors",
63
+ index: t,
64
+ problem: "duration"
65
+ });
66
+ });
67
+ let s = (e, t, i, o) => {
68
+ i !== void 0 && !r.has(i) && n.push({
69
+ at: e,
70
+ index: t,
71
+ problem: "page"
72
+ }), o !== void 0 && !a.has(o) && n.push({
73
+ at: e,
74
+ index: t,
75
+ problem: "anchor"
76
+ });
77
+ };
78
+ return (e.background ?? []).forEach((e, t) => {
79
+ i.has(e.file) || n.push({
80
+ at: "background",
81
+ index: t,
82
+ problem: "file"
83
+ }), s("background", t, e.from_page, e.from_anchor), s("background", t, e.to_page, e.to_anchor);
84
+ }), (e.foreground ?? []).forEach((e, t) => {
85
+ i.has(e.file) || n.push({
86
+ at: "foreground",
87
+ index: t,
88
+ problem: "file"
89
+ }), e.page === void 0 == (e.anchor === void 0) && n.push({
90
+ at: "foreground",
91
+ index: t,
92
+ problem: "target"
93
+ }), s("foreground", t, e.page, e.anchor);
94
+ }), n;
95
+ }
96
+ //#endregion
97
+ export { t as emptyReaderMeta, r as matchAudio, i as readerMetaProblems, e as readerNames };
98
+
99
+ //# sourceMappingURL=reader-meta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reader-meta.js","names":[],"sources":["../../src/client/reader-meta.ts"],"sourcesContent":["import type { ForegroundCue, ReaderMeta, ReaderPlan } from \"./generated/wire.js\";\n\n/** What a version's reader metadata may name: its pages in reading order and its audio tracks. */\nexport interface ReaderNames {\n pages: string[];\n files: string[];\n}\n\n/** The names an editor's reader plan lists: every page of every segment, in order, and the playback tracks. */\nexport function readerNames(plan: ReaderPlan): ReaderNames {\n return { pages: plan.segments.flatMap((s) => (s.pages ?? []).map((p) => p.name)), files: (plan.playback?.tracks ?? []).map((t) => t.name) };\n}\n\n/** An empty schema-1 reader metadata. */\nexport const emptyReaderMeta = (): ReaderMeta => ({ schema_version: 1, anchors: [], background: [], foreground: [] });\n\nconst stem = (name: string) => {\n const i = name.lastIndexOf(\".\");\n return (i > 0 ? name.slice(0, i) : name).toLowerCase();\n};\n\nexport interface AudioMatch {\n /** One cue per matched file: on the anchor its stem names, else the page. */\n foreground: ForegroundCue[];\n unmatchedPages: string[];\n unmatchedFiles: string[];\n}\n\n/** One foreground cue per audio file whose stem names an anchor (first) or a page, case-insensitively (\"0002.mp3\" plays at page \"0002\"). */\nexport function matchAudio(names: ReaderNames, anchors: readonly string[] = []): AudioMatch {\n const byStem = new Map<string, string>();\n for (const f of names.files) if (!byStem.has(stem(f))) byStem.set(stem(f), f);\n const used = new Set<string>();\n const foreground: ForegroundCue[] = [];\n for (const anchor of anchors) {\n const file = byStem.get(stem(anchor));\n if (file && !used.has(file)) {\n foreground.push({ file, anchor });\n used.add(file);\n }\n }\n const unmatchedPages: string[] = [];\n for (const page of names.pages) {\n const file = byStem.get(stem(page));\n if (file && !used.has(file)) {\n foreground.push({ file, page });\n used.add(file);\n } else unmatchedPages.push(page);\n }\n return { foreground, unmatchedPages, unmatchedFiles: names.files.filter((f) => !used.has(f)) };\n}\n\n/** Where a problem is: an anchor, a cue or the defaults, by index. */\nexport interface ReaderMetaProblem {\n at: \"anchors\" | \"background\" | \"foreground\" | \"defaults\";\n index: number;\n /** id: empty or repeated; offset: outside 0-100; duration, seconds: not positive; page, anchor, file: names nothing; target: a foreground cue without a page or an anchor. */\n problem: \"id\" | \"offset\" | \"duration\" | \"seconds\" | \"page\" | \"anchor\" | \"file\" | \"target\";\n}\n\n/** What the server refuses, and a foreground cue without a place: so an editor sees it before saving. */\nexport function readerMetaProblems(meta: ReaderMeta, names: ReaderNames): ReaderMetaProblem[] {\n const out: ReaderMetaProblem[] = [];\n const pages = new Set(names.pages);\n const files = new Set(names.files);\n const ids = new Set<string>();\n const auto = meta.defaults?.auto_advance_seconds;\n if (auto !== undefined && !(auto > 0)) out.push({ at: \"defaults\", index: 0, problem: \"seconds\" });\n (meta.anchors ?? []).forEach((a, index) => {\n if (!a.id.trim() || ids.has(a.id)) out.push({ at: \"anchors\", index, problem: \"id\" });\n ids.add(a.id);\n if (!pages.has(a.page)) out.push({ at: \"anchors\", index, problem: \"page\" });\n if (!(a.offset_percent >= 0 && a.offset_percent <= 100)) out.push({ at: \"anchors\", index, problem: \"offset\" });\n if (a.duration_seconds !== undefined && !(a.duration_seconds > 0)) out.push({ at: \"anchors\", index, problem: \"duration\" });\n });\n const place = (at: ReaderMetaProblem[\"at\"], index: number, page?: string, anchor?: string) => {\n if (page !== undefined && !pages.has(page)) out.push({ at, index, problem: \"page\" });\n if (anchor !== undefined && !ids.has(anchor)) out.push({ at, index, problem: \"anchor\" });\n };\n (meta.background ?? []).forEach((c, index) => {\n if (!files.has(c.file)) out.push({ at: \"background\", index, problem: \"file\" });\n place(\"background\", index, c.from_page, c.from_anchor);\n place(\"background\", index, c.to_page, c.to_anchor);\n });\n (meta.foreground ?? []).forEach((c, index) => {\n if (!files.has(c.file)) out.push({ at: \"foreground\", index, problem: \"file\" });\n if ((c.page === undefined) === (c.anchor === undefined)) out.push({ at: \"foreground\", index, problem: \"target\" });\n place(\"foreground\", index, c.page, c.anchor);\n });\n return out;\n}\n"],"mappings":";AASA,SAAgB,EAAY,GAA+B;CACzD,OAAO;EAAE,OAAO,EAAK,SAAS,SAAS,OAAO,EAAE,SAAS,CAAC,EAAA,CAAG,KAAK,MAAM,EAAE,IAAI,CAAC;EAAG,QAAQ,EAAK,UAAU,UAAU,CAAC,EAAA,CAAG,KAAK,MAAM,EAAE,IAAI;CAAE;AAC5I;AAGA,IAAa,WAAqC;CAAE,gBAAgB;CAAG,SAAS,CAAC;CAAG,YAAY,CAAC;CAAG,YAAY,CAAC;AAAE,IAE7G,KAAQ,MAAiB;CAC7B,IAAM,IAAI,EAAK,YAAY,GAAG;CAC9B,QAAQ,IAAI,IAAI,EAAK,MAAM,GAAG,CAAC,IAAI,EAAA,CAAM,YAAY;AACvD;AAUA,SAAgB,EAAW,GAAoB,IAA6B,CAAC,GAAe;CAC1F,IAAM,oBAAS,IAAI,IAAoB;CACvC,KAAK,IAAM,KAAK,EAAM,OAAO,AAAK,EAAO,IAAI,EAAK,CAAC,CAAC,KAAG,EAAO,IAAI,EAAK,CAAC,GAAG,CAAC;CAC5E,IAAM,oBAAO,IAAI,IAAY,GACvB,IAA8B,CAAC;CACrC,KAAK,IAAM,KAAU,GAAS;EAC5B,IAAM,IAAO,EAAO,IAAI,EAAK,CAAM,CAAC;EACpC,AAAI,KAAQ,CAAC,EAAK,IAAI,CAAI,MACxB,EAAW,KAAK;GAAE;GAAM;EAAO,CAAC,GAChC,EAAK,IAAI,CAAI;CAEjB;CACA,IAAM,IAA2B,CAAC;CAClC,KAAK,IAAM,KAAQ,EAAM,OAAO;EAC9B,IAAM,IAAO,EAAO,IAAI,EAAK,CAAI,CAAC;EAClC,AAAI,KAAQ,CAAC,EAAK,IAAI,CAAI,KACxB,EAAW,KAAK;GAAE;GAAM;EAAK,CAAC,GAC9B,EAAK,IAAI,CAAI,KACR,EAAe,KAAK,CAAI;CACjC;CACA,OAAO;EAAE;EAAY;EAAgB,gBAAgB,EAAM,MAAM,QAAQ,MAAM,CAAC,EAAK,IAAI,CAAC,CAAC;CAAE;AAC/F;AAWA,SAAgB,EAAmB,GAAkB,GAAyC;CAC5F,IAAM,IAA2B,CAAC,GAC5B,IAAQ,IAAI,IAAI,EAAM,KAAK,GAC3B,IAAQ,IAAI,IAAI,EAAM,KAAK,GAC3B,oBAAM,IAAI,IAAY,GACtB,IAAO,EAAK,UAAU;CAE5B,AADI,MAAS,KAAA,KAAa,EAAE,IAAO,MAAI,EAAI,KAAK;EAAE,IAAI;EAAY,OAAO;EAAG,SAAS;CAAU,CAAC,IAC/F,EAAK,WAAW,CAAC,EAAA,CAAG,SAAS,GAAG,MAAU;EAKzC,CAJI,CAAC,EAAE,GAAG,KAAK,KAAK,EAAI,IAAI,EAAE,EAAE,MAAG,EAAI,KAAK;GAAE,IAAI;GAAW;GAAO,SAAS;EAAK,CAAC,GACnF,EAAI,IAAI,EAAE,EAAE,GACP,EAAM,IAAI,EAAE,IAAI,KAAG,EAAI,KAAK;GAAE,IAAI;GAAW;GAAO,SAAS;EAAO,CAAC,GACpE,EAAE,kBAAkB,KAAK,EAAE,kBAAkB,OAAM,EAAI,KAAK;GAAE,IAAI;GAAW;GAAO,SAAS;EAAS,CAAC,GACzG,EAAE,qBAAqB,KAAA,KAAa,EAAE,EAAE,mBAAmB,MAAI,EAAI,KAAK;GAAE,IAAI;GAAW;GAAO,SAAS;EAAW,CAAC;CAC3H,CAAC;CACD,IAAM,KAAS,GAA6B,GAAe,GAAe,MAAoB;EAE5F,AADI,MAAS,KAAA,KAAa,CAAC,EAAM,IAAI,CAAI,KAAG,EAAI,KAAK;GAAE;GAAI;GAAO,SAAS;EAAO,CAAC,GAC/E,MAAW,KAAA,KAAa,CAAC,EAAI,IAAI,CAAM,KAAG,EAAI,KAAK;GAAE;GAAI;GAAO,SAAS;EAAS,CAAC;CACzF;CAWA,QAVC,EAAK,cAAc,CAAC,EAAA,CAAG,SAAS,GAAG,MAAU;EAG5C,AAFK,EAAM,IAAI,EAAE,IAAI,KAAG,EAAI,KAAK;GAAE,IAAI;GAAc;GAAO,SAAS;EAAO,CAAC,GAC7E,EAAM,cAAc,GAAO,EAAE,WAAW,EAAE,WAAW,GACrD,EAAM,cAAc,GAAO,EAAE,SAAS,EAAE,SAAS;CACnD,CAAC,IACA,EAAK,cAAc,CAAC,EAAA,CAAG,SAAS,GAAG,MAAU;EAG5C,AAFK,EAAM,IAAI,EAAE,IAAI,KAAG,EAAI,KAAK;GAAE,IAAI;GAAc;GAAO,SAAS;EAAO,CAAC,GACxE,EAAE,SAAS,KAAA,MAAgB,EAAE,WAAW,KAAA,MAAY,EAAI,KAAK;GAAE,IAAI;GAAc;GAAO,SAAS;EAAS,CAAC,GAChH,EAAM,cAAc,GAAO,EAAE,MAAM,EAAE,MAAM;CAC7C,CAAC,GACM;AACT"}
@@ -8,7 +8,7 @@ export declare class VersionsClient {
8
8
  constructor(http: Http);
9
9
  /** The version's reader plan for this viewer; Pending while it has no current publication. */
10
10
  reader(content: string, version: string, signal?: AbortSignal): Promise<ReaderPlan | Pending>;
11
- /** Editors: the version's anchors and audio cues. */
11
+ /** Editors: replaces the version's reader metadata (anchors, audio cues, defaults). */
12
12
  setReader(content: string, version: string, meta: ReaderMeta): Promise<void>;
13
13
  /** Editors: fills a version without media from a sibling, in a durable job. */
14
14
  fork(content: string, version: string, body: ForkBody): Promise<Pending>;
@@ -15,13 +15,18 @@ var r = (e) => !!e && typeof e == "object" && "status" in e && !("pages" in e),
15
15
  signal: r
16
16
  });
17
17
  }
18
- setReader(e, n, r) {
19
- return t(this.http, "PUT", "/contents/{id}/versions/{version}/reader", {
18
+ async setReader(e, n, r) {
19
+ let i = this.http.captureChanges();
20
+ await t(this.http, "PUT", "/contents/{id}/versions/{version}/reader", {
20
21
  params: {
21
22
  id: e,
22
23
  version: n
23
24
  },
24
25
  body: r
26
+ }), i({
27
+ type: "reader.changed",
28
+ content: e,
29
+ version: n
25
30
  });
26
31
  }
27
32
  fork(e, n, r) {
@@ -1 +1 @@
1
- {"version":3,"file":"versions.js","names":[],"sources":["../../src/client/versions.ts"],"sourcesContent":["import { ContentKitError } from \"./errors.js\";\nimport type { ForkBody, Pending, ReaderMeta, ReaderPlan } from \"./generated/wire.js\";\nimport type { Http } from \"./http.js\";\nimport { call, routeURL } from \"./route.js\";\n\n/** A version's answer while it is prepared (202). */\nexport const isPending = (x: unknown): x is Pending => !!x && typeof x === \"object\" && \"status\" in x && !(\"pages\" in x);\n\n/** Content versions: reader plans, reader metadata, forks and downloads. */\nexport class VersionsClient {\n constructor(private readonly http: Http) {}\n\n /** The version's reader plan for this viewer; Pending while it has no current publication. */\n reader(content: string, version: string, signal?: AbortSignal): Promise<ReaderPlan | Pending> {\n return call(this.http, \"GET\", \"/contents/{id}/versions/{version}/reader\", { params: { id: content, version }, signal });\n }\n /** Editors: the version's anchors and audio cues. */\n setReader(content: string, version: string, meta: ReaderMeta): Promise<void> {\n return call(this.http, \"PUT\", \"/contents/{id}/versions/{version}/reader\", { params: { id: content, version }, body: meta });\n }\n /** Editors: fills a version without media from a sibling, in a durable job. */\n fork(content: string, version: string, body: ForkBody): Promise<Pending> {\n return call(this.http, \"POST\", \"/contents/{id}/versions/{version}/fork\", { params: { id: content, version }, body });\n }\n /**\n * The version's pages as a zip, charged to the viewer's download quota;\n * Pending while it is prepared (ask again).\n */\n async download(content: string, version: string, signal?: AbortSignal): Promise<Blob | Pending> {\n const url = routeURL(this.http, \"GET\", \"/contents/{id}/versions/{version}/download\", { params: { id: content, version } });\n const out = await this.http.request<Blob>(url, { signal, blob: true });\n if (!out.type.startsWith(\"application/json\")) return out;\n const body: unknown = JSON.parse(await out.text());\n if (isPending(body)) return body;\n throw new ContentKitError(\"internal_error\", \"unexpected download answer\");\n }\n}\n"],"mappings":";;;AAMA,IAAa,KAAa,MAA6B,CAAC,CAAC,KAAK,OAAO,KAAM,YAAY,YAAY,KAAK,EAAE,WAAW,IAGxG,IAAb,MAA4B;CACG;CAA7B,YAAY,GAA6B;EAAZ,KAAA,OAAA;CAAa;CAG1C,OAAO,GAAiB,GAAiB,GAAqD;EAC5F,OAAO,EAAK,KAAK,MAAM,OAAO,4CAA4C;GAAE,QAAQ;IAAE,IAAI;IAAS;GAAQ;GAAG;EAAO,CAAC;CACxH;CAEA,UAAU,GAAiB,GAAiB,GAAiC;EAC3E,OAAO,EAAK,KAAK,MAAM,OAAO,4CAA4C;GAAE,QAAQ;IAAE,IAAI;IAAS;GAAQ;GAAG,MAAM;EAAK,CAAC;CAC5H;CAEA,KAAK,GAAiB,GAAiB,GAAkC;EACvE,OAAO,EAAK,KAAK,MAAM,QAAQ,0CAA0C;GAAE,QAAQ;IAAE,IAAI;IAAS;GAAQ;GAAG;EAAK,CAAC;CACrH;CAKA,MAAM,SAAS,GAAiB,GAAiB,GAA+C;EAC9F,IAAM,IAAM,EAAS,KAAK,MAAM,OAAO,8CAA8C,EAAE,QAAQ;GAAE,IAAI;GAAS;EAAQ,EAAE,CAAC,GACnH,IAAM,MAAM,KAAK,KAAK,QAAc,GAAK;GAAE;GAAQ,MAAM;EAAK,CAAC;EACrE,IAAI,CAAC,EAAI,KAAK,WAAW,kBAAkB,GAAG,OAAO;EACrD,IAAM,IAAgB,KAAK,MAAM,MAAM,EAAI,KAAK,CAAC;EACjD,IAAI,EAAU,CAAI,GAAG,OAAO;EAC5B,MAAM,IAAI,EAAgB,kBAAkB,4BAA4B;CAC1E;AACF"}
1
+ {"version":3,"file":"versions.js","names":[],"sources":["../../src/client/versions.ts"],"sourcesContent":["import { ContentKitError } from \"./errors.js\";\nimport type { ForkBody, Pending, ReaderMeta, ReaderPlan } from \"./generated/wire.js\";\nimport type { Http } from \"./http.js\";\nimport { call, routeURL } from \"./route.js\";\n\n/** A version's answer while it is prepared (202). */\nexport const isPending = (x: unknown): x is Pending => !!x && typeof x === \"object\" && \"status\" in x && !(\"pages\" in x);\n\n/** Content versions: reader plans, reader metadata, forks and downloads. */\nexport class VersionsClient {\n constructor(private readonly http: Http) {}\n\n /** The version's reader plan for this viewer; Pending while it has no current publication. */\n reader(content: string, version: string, signal?: AbortSignal): Promise<ReaderPlan | Pending> {\n return call(this.http, \"GET\", \"/contents/{id}/versions/{version}/reader\", { params: { id: content, version }, signal });\n }\n /** Editors: replaces the version's reader metadata (anchors, audio cues, defaults). */\n async setReader(content: string, version: string, meta: ReaderMeta): Promise<void> {\n const emit = this.http.captureChanges();\n await call(this.http, \"PUT\", \"/contents/{id}/versions/{version}/reader\", { params: { id: content, version }, body: meta });\n emit({ type: \"reader.changed\", content, version });\n }\n /** Editors: fills a version without media from a sibling, in a durable job. */\n fork(content: string, version: string, body: ForkBody): Promise<Pending> {\n return call(this.http, \"POST\", \"/contents/{id}/versions/{version}/fork\", { params: { id: content, version }, body });\n }\n /**\n * The version's pages as a zip, charged to the viewer's download quota;\n * Pending while it is prepared (ask again).\n */\n async download(content: string, version: string, signal?: AbortSignal): Promise<Blob | Pending> {\n const url = routeURL(this.http, \"GET\", \"/contents/{id}/versions/{version}/download\", { params: { id: content, version } });\n const out = await this.http.request<Blob>(url, { signal, blob: true });\n if (!out.type.startsWith(\"application/json\")) return out;\n const body: unknown = JSON.parse(await out.text());\n if (isPending(body)) return body;\n throw new ContentKitError(\"internal_error\", \"unexpected download answer\");\n }\n}\n"],"mappings":";;;AAMA,IAAa,KAAa,MAA6B,CAAC,CAAC,KAAK,OAAO,KAAM,YAAY,YAAY,KAAK,EAAE,WAAW,IAGxG,IAAb,MAA4B;CACG;CAA7B,YAAY,GAA6B;EAAZ,KAAA,OAAA;CAAa;CAG1C,OAAO,GAAiB,GAAiB,GAAqD;EAC5F,OAAO,EAAK,KAAK,MAAM,OAAO,4CAA4C;GAAE,QAAQ;IAAE,IAAI;IAAS;GAAQ;GAAG;EAAO,CAAC;CACxH;CAEA,MAAM,UAAU,GAAiB,GAAiB,GAAiC;EACjF,IAAM,IAAO,KAAK,KAAK,eAAe;EAEtC,AADA,MAAM,EAAK,KAAK,MAAM,OAAO,4CAA4C;GAAE,QAAQ;IAAE,IAAI;IAAS;GAAQ;GAAG,MAAM;EAAK,CAAC,GACzH,EAAK;GAAE,MAAM;GAAkB;GAAS;EAAQ,CAAC;CACnD;CAEA,KAAK,GAAiB,GAAiB,GAAkC;EACvE,OAAO,EAAK,KAAK,MAAM,QAAQ,0CAA0C;GAAE,QAAQ;IAAE,IAAI;IAAS;GAAQ;GAAG;EAAK,CAAC;CACrH;CAKA,MAAM,SAAS,GAAiB,GAAiB,GAA+C;EAC9F,IAAM,IAAM,EAAS,KAAK,MAAM,OAAO,8CAA8C,EAAE,QAAQ;GAAE,IAAI;GAAS;EAAQ,EAAE,CAAC,GACnH,IAAM,MAAM,KAAK,KAAK,QAAc,GAAK;GAAE;GAAQ,MAAM;EAAK,CAAC;EACrE,IAAI,CAAC,EAAI,KAAK,WAAW,kBAAkB,GAAG,OAAO;EACrD,IAAM,IAAgB,KAAK,MAAM,MAAM,EAAI,KAAK,CAAC;EACjD,IAAI,EAAU,CAAI,GAAG,OAAO;EAC5B,MAAM,IAAI,EAAgB,kBAAkB,4BAA4B;CAC1E;AACF"}
package/dist/client.js CHANGED
@@ -37,4 +37,5 @@ import { VersionsClient as it, isPending as at } from "./client/versions.js";
37
37
  import { NotificationsClient as ot } from "./client/notifications.js";
38
38
  import { createContentKitClient as st } from "./client/client.js";
39
39
  import { LETTERS as ct, attributeInput as lt, fold as ut, fromLocalInput as dt, humanize as ft, letterOf as pt, parseAttribute as mt, parseAttributes as ht, slugify as gt, toLocalInput as _t } from "./client/group-fields.js";
40
- export { de as ABR_DEFAULTS, Ve as BODY_SUFFIX, Ke as BansClient, Je as Beacons, i as CLIENT_ERROR_CODES, ze as CatalogClient, Be as CodesClient, qe as CommentsClient, a as ContentKitError, He as ContentsClient, e as DEFAULT_DENSITY, Ze as DiscoveryClient, o as ERROR_CODES, Qe as FavoritesClient, nt as GroupsClient, Ue as IMAGE_SCHEME, re as ItemUploadQueue, ct as LETTERS, w as MAX_PART_SIZE, T as MAX_SINGLE_PUT, E as MIN_PART_SIZE, C as MediaApi, M as MediaClient, $e as ModerationClient, fe as NETWORK_FAILURES_BEFORE_ERROR, ot as NotificationsClient, rt as OffersClient, je as PLAYBACK_SPEEDS, Me as PLAYER_TRACKS_KEY, Ne as PLAYER_VOLUME_KEY, O as Pacer, et as PollsClient, oe as READ_CHUNK, pe as REFRESH_BEFORE_EXPIRY, tt as ReactionsClient, it as VersionsClient, me as abrHlsConfig, I as acceptOf, h as aspectOf, lt as attributeInput, N as backoff, _ as call, he as capRung, q as centeredCrop, y as checkRef, se as chunkOffsets, ge as classifyHlsError, _e as classifyMediaError, J as constrainCrop, st as createContentKitClient, ie as decodeImage, L as defaultImage, k as defaultTransport, t as densityFor, Y as editOf, X as editedSize, ne as encodeRemaining, Ye as eventId, ve as expiryDelay, s as failureError, A as fetchTransport, R as filesFor, d as fill, ut as fold, we as formatDuration, dt as fromLocalInput, Z as fromRotated, Te as galleryItems, ye as hlsConfig, ft as humanize, We as imageRef, Ge as imageRefs, be as initialEstimate, ae as isAnimatedImage, Ee as isAudioType, b as isContentId, c as isContentKitError, De as isImageType, z as isPattern, at as isPending, ce as isProcessing, Oe as isSubtitleType, ke as isVideoType, x as itemKey, pt as letterOf, le as mergeReads, mt as parseAttribute, ht as parseAttributes, Pe as parseSpriteVtt, n as pickRendition, Fe as playerKeyAction, ue as processing, f as publicRenditions, p as publicURL, g as ratio, B as ratioLabel, Le as reactionVerb, l as readContentKitError, Xe as readerSession, xe as refreshable, Ie as resumeAt, Q as rotation, v as routeURL, V as ruleDir, H as ruleFor, $ as sameEdit, S as sameItem, P as samePath, Re as sameTarget, U as screenFiles, D as sha256Hex, gt as slugify, r as sortRenditions, m as srcSet, Ae as stageAspect, Se as startRung, Ce as statusKind, F as stem, u as toContentKitError, _t as toLocalInput, ee as toOriginal, te as toRotated, W as uniqueName, G as uploadRules, K as withMediaType, j as xhrTransport };
40
+ import { emptyReaderMeta as vt, matchAudio as yt, readerMetaProblems as bt, readerNames as xt } from "./client/reader-meta.js";
41
+ export { de as ABR_DEFAULTS, Ve as BODY_SUFFIX, Ke as BansClient, Je as Beacons, i as CLIENT_ERROR_CODES, ze as CatalogClient, Be as CodesClient, qe as CommentsClient, a as ContentKitError, He as ContentsClient, e as DEFAULT_DENSITY, Ze as DiscoveryClient, o as ERROR_CODES, Qe as FavoritesClient, nt as GroupsClient, Ue as IMAGE_SCHEME, re as ItemUploadQueue, ct as LETTERS, w as MAX_PART_SIZE, T as MAX_SINGLE_PUT, E as MIN_PART_SIZE, C as MediaApi, M as MediaClient, $e as ModerationClient, fe as NETWORK_FAILURES_BEFORE_ERROR, ot as NotificationsClient, rt as OffersClient, je as PLAYBACK_SPEEDS, Me as PLAYER_TRACKS_KEY, Ne as PLAYER_VOLUME_KEY, O as Pacer, et as PollsClient, oe as READ_CHUNK, pe as REFRESH_BEFORE_EXPIRY, tt as ReactionsClient, it as VersionsClient, me as abrHlsConfig, I as acceptOf, h as aspectOf, lt as attributeInput, N as backoff, _ as call, he as capRung, q as centeredCrop, y as checkRef, se as chunkOffsets, ge as classifyHlsError, _e as classifyMediaError, J as constrainCrop, st as createContentKitClient, ie as decodeImage, L as defaultImage, k as defaultTransport, t as densityFor, Y as editOf, X as editedSize, vt as emptyReaderMeta, ne as encodeRemaining, Ye as eventId, ve as expiryDelay, s as failureError, A as fetchTransport, R as filesFor, d as fill, ut as fold, we as formatDuration, dt as fromLocalInput, Z as fromRotated, Te as galleryItems, ye as hlsConfig, ft as humanize, We as imageRef, Ge as imageRefs, be as initialEstimate, ae as isAnimatedImage, Ee as isAudioType, b as isContentId, c as isContentKitError, De as isImageType, z as isPattern, at as isPending, ce as isProcessing, Oe as isSubtitleType, ke as isVideoType, x as itemKey, pt as letterOf, yt as matchAudio, le as mergeReads, mt as parseAttribute, ht as parseAttributes, Pe as parseSpriteVtt, n as pickRendition, Fe as playerKeyAction, ue as processing, f as publicRenditions, p as publicURL, g as ratio, B as ratioLabel, Le as reactionVerb, l as readContentKitError, bt as readerMetaProblems, xt as readerNames, Xe as readerSession, xe as refreshable, Ie as resumeAt, Q as rotation, v as routeURL, V as ruleDir, H as ruleFor, $ as sameEdit, S as sameItem, P as samePath, Re as sameTarget, U as screenFiles, D as sha256Hex, gt as slugify, r as sortRenditions, m as srcSet, Ae as stageAspect, Se as startRung, Ce as statusKind, F as stem, u as toContentKitError, _t as toLocalInput, ee as toOriginal, te as toRotated, W as uniqueName, G as uploadRules, K as withMediaType, j as xhrTransport };
@@ -0,0 +1,18 @@
1
+ import { ContentKitUiAppearance } from '../../appearance.js';
2
+ import { ContentKitClient } from '../../client/client.js';
3
+ import { ContentKitErrorHandler } from '../../react/context.js';
4
+ export interface ReaderManifestEditorProps {
5
+ content: string;
6
+ version: string;
7
+ client?: ContentKitClient;
8
+ onError?: ContentKitErrorHandler;
9
+ className?: string;
10
+ appearance?: ContentKitUiAppearance;
11
+ }
12
+ /**
13
+ * Editors: a reader version's manifest over its published pages and audio:
14
+ * scroll anchors, foreground cues (one track at a page or anchor, matched
15
+ * from file names in one step), background tracks over a range, and the
16
+ * auto-advance default. Page order is the version's media order.
17
+ */
18
+ export declare function ReaderManifestEditor({ content, version, client: own, onError, className, appearance }: ReaderManifestEditorProps): import('react').JSX.Element;