@ttt-productions/ttt-core 0.79.61 → 0.79.63
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.
- package/dist/constants/admin-labels.d.ts +5 -1
- package/dist/constants/admin-labels.d.ts.map +1 -1
- package/dist/constants/admin-labels.js +9 -0
- package/dist/constants/admin-labels.js.map +1 -1
- package/dist/constants/audition-deadlines.d.ts +58 -0
- package/dist/constants/audition-deadlines.d.ts.map +1 -0
- package/dist/constants/audition-deadlines.js +92 -0
- package/dist/constants/audition-deadlines.js.map +1 -0
- package/dist/constants/chat.d.ts +0 -11
- package/dist/constants/chat.d.ts.map +1 -1
- package/dist/constants/chat.js +0 -11
- package/dist/constants/chat.js.map +1 -1
- package/dist/constants/index.d.ts +1 -0
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/constants/index.js +1 -0
- package/dist/constants/index.js.map +1 -1
- package/dist/constants/options.d.ts +4 -4
- package/dist/constants/options.js +1 -1
- package/dist/constants/options.js.map +1 -1
- package/dist/constants/pagination.d.ts +12 -0
- package/dist/constants/pagination.d.ts.map +1 -1
- package/dist/constants/pagination.js +14 -0
- package/dist/constants/pagination.js.map +1 -1
- package/dist/doc-schemas/admin-dispatch-read-markers.d.ts +16 -0
- package/dist/doc-schemas/admin-dispatch-read-markers.d.ts.map +1 -0
- package/dist/doc-schemas/admin-dispatch-read-markers.js +23 -0
- package/dist/doc-schemas/admin-dispatch-read-markers.js.map +1 -0
- package/dist/doc-schemas/chat-sync.d.ts +26 -1
- package/dist/doc-schemas/chat-sync.d.ts.map +1 -1
- package/dist/doc-schemas/chat-sync.js +25 -3
- package/dist/doc-schemas/chat-sync.js.map +1 -1
- package/dist/doc-schemas/commissions.d.ts +12 -3
- package/dist/doc-schemas/commissions.d.ts.map +1 -1
- package/dist/doc-schemas/commissions.js +21 -11
- package/dist/doc-schemas/commissions.js.map +1 -1
- package/dist/doc-schemas/erasure-fates.d.ts +2 -0
- package/dist/doc-schemas/erasure-fates.d.ts.map +1 -1
- package/dist/doc-schemas/erasure-fates.js +5 -0
- package/dist/doc-schemas/erasure-fates.js.map +1 -1
- package/dist/doc-schemas/index.d.ts +1 -0
- package/dist/doc-schemas/index.d.ts.map +1 -1
- package/dist/doc-schemas/index.js +1 -0
- package/dist/doc-schemas/index.js.map +1 -1
- package/dist/doc-schemas/messaging.d.ts +11 -3
- package/dist/doc-schemas/messaging.d.ts.map +1 -1
- package/dist/doc-schemas/messaging.js +17 -4
- package/dist/doc-schemas/messaging.js.map +1 -1
- package/dist/doc-schemas/registry.d.ts +41 -6
- package/dist/doc-schemas/registry.d.ts.map +1 -1
- package/dist/doc-schemas/registry.js +4 -1
- package/dist/doc-schemas/registry.js.map +1 -1
- package/dist/doc-schemas/user.d.ts +1 -0
- package/dist/doc-schemas/user.d.ts.map +1 -1
- package/dist/doc-schemas/user.js +5 -0
- package/dist/doc-schemas/user.js.map +1 -1
- package/dist/ids/chat-ids.d.ts +13 -14
- package/dist/ids/chat-ids.d.ts.map +1 -1
- package/dist/ids/chat-ids.js +15 -8
- package/dist/ids/chat-ids.js.map +1 -1
- package/dist/ids/guild-chat-conversation.d.ts +43 -0
- package/dist/ids/guild-chat-conversation.d.ts.map +1 -0
- package/dist/ids/guild-chat-conversation.js +60 -0
- package/dist/ids/guild-chat-conversation.js.map +1 -0
- package/dist/ids/index.d.ts +1 -0
- package/dist/ids/index.d.ts.map +1 -1
- package/dist/ids/index.js +1 -0
- package/dist/ids/index.js.map +1 -1
- package/dist/media/target-info.d.ts +22 -9
- package/dist/media/target-info.d.ts.map +1 -1
- package/dist/media/target-info.js +37 -14
- package/dist/media/target-info.js.map +1 -1
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +12 -0
- package/dist/notifications/index.js.map +1 -1
- package/dist/paths/collection-refs.d.ts +1 -0
- package/dist/paths/collection-refs.d.ts.map +1 -1
- package/dist/paths/collection-refs.js +1 -0
- package/dist/paths/collection-refs.js.map +1 -1
- package/dist/paths/collections.d.ts +2 -0
- package/dist/paths/collections.d.ts.map +1 -1
- package/dist/paths/collections.js +4 -0
- package/dist/paths/collections.js.map +1 -1
- package/dist/paths/path-builders.d.ts +2 -0
- package/dist/paths/path-builders.d.ts.map +1 -1
- package/dist/paths/path-builders.js +2 -0
- package/dist/paths/path-builders.js.map +1 -1
- package/dist/permissions/work-project-permissions-data.d.ts +23 -24
- package/dist/permissions/work-project-permissions-data.d.ts.map +1 -1
- package/dist/permissions/work-project-permissions-data.js +48 -34
- package/dist/permissions/work-project-permissions-data.js.map +1 -1
- package/dist/permissions/work-project-permissions.d.ts +15 -0
- package/dist/permissions/work-project-permissions.d.ts.map +1 -1
- package/dist/permissions/work-project-permissions.js +20 -1
- package/dist/permissions/work-project-permissions.js.map +1 -1
- package/dist/report/chat-report-channel-ref.d.ts +3 -10
- package/dist/report/chat-report-channel-ref.d.ts.map +1 -1
- package/dist/report/chat-report-channel-ref.js +8 -20
- package/dist/report/chat-report-channel-ref.js.map +1 -1
- package/dist/schemas/admin-dispatch-actions.d.ts +13 -0
- package/dist/schemas/admin-dispatch-actions.d.ts.map +1 -1
- package/dist/schemas/admin-dispatch-actions.js +14 -1
- package/dist/schemas/admin-dispatch-actions.js.map +1 -1
- package/dist/schemas/admin.d.ts +4 -0
- package/dist/schemas/admin.d.ts.map +1 -1
- package/dist/schemas/admin.js +4 -5
- package/dist/schemas/admin.js.map +1 -1
- package/dist/schemas/atoms.d.ts +2 -0
- package/dist/schemas/atoms.d.ts.map +1 -1
- package/dist/schemas/atoms.js +3 -1
- package/dist/schemas/atoms.js.map +1 -1
- package/dist/schemas/auditions.d.ts +21 -0
- package/dist/schemas/auditions.d.ts.map +1 -1
- package/dist/schemas/auditions.js +14 -0
- package/dist/schemas/auditions.js.map +1 -1
- package/dist/schemas/chat.d.ts +65 -11
- package/dist/schemas/chat.d.ts.map +1 -1
- package/dist/schemas/chat.js +62 -20
- package/dist/schemas/chat.js.map +1 -1
- package/dist/schemas/craft-skills.d.ts +6 -0
- package/dist/schemas/craft-skills.d.ts.map +1 -1
- package/dist/schemas/craft-skills.js +7 -0
- package/dist/schemas/craft-skills.js.map +1 -1
- package/dist/schemas/notification.d.ts +21 -1
- package/dist/schemas/notification.d.ts.map +1 -1
- package/dist/schemas/notification.js +21 -0
- package/dist/schemas/notification.js.map +1 -1
- package/dist/schemas/safety.d.ts +4209 -0
- package/dist/schemas/safety.d.ts.map +1 -1
- package/dist/schemas/safety.js +115 -7
- package/dist/schemas/safety.js.map +1 -1
- package/dist/schemas/utility.d.ts +4 -0
- package/dist/schemas/utility.d.ts.map +1 -1
- package/dist/schemas/utility.js +18 -2
- package/dist/schemas/utility.js.map +1 -1
- package/dist/schemas/voting.d.ts +2 -3
- package/dist/schemas/voting.d.ts.map +1 -1
- package/dist/schemas/voting.js +2 -4
- package/dist/schemas/voting.js.map +1 -1
- package/dist/schemas/work-project-management.d.ts +135 -0
- package/dist/schemas/work-project-management.d.ts.map +1 -1
- package/dist/schemas/work-project-management.js +38 -0
- package/dist/schemas/work-project-management.js.map +1 -1
- package/dist/upload-variables/create-admin-audition-variables.d.ts +34 -8
- package/dist/upload-variables/create-admin-audition-variables.d.ts.map +1 -1
- package/dist/upload-variables/create-admin-audition-variables.js +22 -6
- package/dist/upload-variables/create-admin-audition-variables.js.map +1 -1
- package/dist/upload-variables/create-commission-variables.d.ts.map +1 -1
- package/dist/upload-variables/create-commission-variables.js +3 -3
- package/dist/upload-variables/create-commission-variables.js.map +1 -1
- package/dist/upload-variables/create-work-project-audition-variables.d.ts +2 -1
- package/dist/upload-variables/create-work-project-audition-variables.d.ts.map +1 -1
- package/dist/upload-variables/create-work-project-audition-variables.js +8 -5
- package/dist/upload-variables/create-work-project-audition-variables.js.map +1 -1
- package/dist/utils/guild-chat-access.d.ts +71 -0
- package/dist/utils/guild-chat-access.d.ts.map +1 -0
- package/dist/utils/guild-chat-access.js +89 -0
- package/dist/utils/guild-chat-access.js.map +1 -0
- package/dist/utils/guild-invite-system-message.d.ts +56 -0
- package/dist/utils/guild-invite-system-message.d.ts.map +1 -0
- package/dist/utils/guild-invite-system-message.js +98 -0
- package/dist/utils/guild-invite-system-message.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -1
- package/package.json +4 -3
|
@@ -8,7 +8,7 @@ import type { ChildSafetyWorkStatus } from '../doc-schemas/safety/case.js';
|
|
|
8
8
|
import type { BroadcastAudienceSelector } from '../schemas/notification.js';
|
|
9
9
|
import type { DeadLetterCollection } from '../schemas/admin.js';
|
|
10
10
|
import type { GuildInviteConversationStatus, ShortLinkTargetType } from '../schemas/atoms.js';
|
|
11
|
-
import type { AdminDispatch } from '../doc-schemas/messaging.js';
|
|
11
|
+
import type { AdminDispatch, AdminDispatchSenderRole } from '../doc-schemas/messaging.js';
|
|
12
12
|
import type { CommissionProposalStatus } from '../schemas/commissions.js';
|
|
13
13
|
import type { InviteSourceType } from '../schemas/work-project-management.js';
|
|
14
14
|
import type { Audition } from '../doc-schemas/commissions.js';
|
|
@@ -74,6 +74,8 @@ export declare const CLEARABLE_TEXT_FIELD_LABEL_OVERRIDES: {
|
|
|
74
74
|
* overrides and falls through to the base map.
|
|
75
75
|
*/
|
|
76
76
|
export declare function clearableTextFieldLabel(field: string, surface?: string): string;
|
|
77
|
+
/** What the admin screens show for a thread whose `awaitingAdminReply` is set. */
|
|
78
|
+
export declare const ADMIN_DISPATCH_AWAITING_REPLY_LABEL = "Awaiting reply";
|
|
77
79
|
/** Human labels for the dead-letter replay ledgers (Ops Repairs dead-letter table). */
|
|
78
80
|
export declare const DEAD_LETTER_COLLECTION_LABELS: Record<DeadLetterCollection, string>;
|
|
79
81
|
/** Operator-settable report dispositions with their console copy. 'undetermined' is the
|
|
@@ -115,6 +117,8 @@ export declare const INVITE_SOURCE_TYPE_LABELS: Record<InviteSourceType, string>
|
|
|
115
117
|
export declare const SHORT_LINK_TARGET_TYPE_LABELS: Record<ShortLinkTargetType, string>;
|
|
116
118
|
/** Support-thread statuses (a member's Messages, a Work's Correspondence, the admin browse list). */
|
|
117
119
|
export declare const ADMIN_DISPATCH_STATUS_LABELS: Record<AdminDispatch['status'], string>;
|
|
120
|
+
/** Who a support-thread message is from, as the admin thread preview labels it. */
|
|
121
|
+
export declare const ADMIN_DISPATCH_SENDER_ROLE_LABELS: Record<AdminDispatchSenderRole, string>;
|
|
118
122
|
/** Child-safety case work statuses (the safety case console's case rows and closed-case lookup). */
|
|
119
123
|
export declare const CHILD_SAFETY_CASE_WORK_STATUS_LABELS: Record<ChildSafetyWorkStatus, string>;
|
|
120
124
|
/** NCII case statuses (the safety case console's case rows and closed-case lookup). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-labels.d.ts","sourceRoot":"","sources":["../../src/constants/admin-labels.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAGpE,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACjG,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,KAAK,EAAE,6BAA6B,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"admin-labels.d.ts","sourceRoot":"","sources":["../../src/constants/admin-labels.ts"],"names":[],"mappings":"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"}
|
|
@@ -82,6 +82,8 @@ export function clearableTextFieldLabel(field, surface) {
|
|
|
82
82
|
: undefined;
|
|
83
83
|
return (overrides?.[field] ?? CLEARABLE_TEXT_FIELD_LABELS[field] ?? field);
|
|
84
84
|
}
|
|
85
|
+
/** What the admin screens show for a thread whose `awaitingAdminReply` is set. */
|
|
86
|
+
export const ADMIN_DISPATCH_AWAITING_REPLY_LABEL = 'Awaiting reply';
|
|
85
87
|
/** Human labels for the dead-letter replay ledgers (Ops Repairs dead-letter table). */
|
|
86
88
|
export const DEAD_LETTER_COLLECTION_LABELS = {
|
|
87
89
|
chatSyncEvents: 'Chat sync event',
|
|
@@ -97,6 +99,7 @@ export const DEAD_LETTER_COLLECTION_LABELS = {
|
|
|
97
99
|
accountActionCommands: 'Account safety action',
|
|
98
100
|
activeReportGroups: 'Report edge sync',
|
|
99
101
|
hallSubItemEdgeSync: 'Hall sub-item edge sync',
|
|
102
|
+
chatParkedDeliveries: 'Chat room delivery',
|
|
100
103
|
};
|
|
101
104
|
/** Operator-settable report dispositions with their console copy. 'undetermined' is the
|
|
102
105
|
* initial state, never a settable target, so it carries no option entry. */
|
|
@@ -204,6 +207,12 @@ export const ADMIN_DISPATCH_STATUS_LABELS = {
|
|
|
204
207
|
closed_resolved: 'Resolved',
|
|
205
208
|
closed_unresolved: 'Closed',
|
|
206
209
|
};
|
|
210
|
+
/** Who a support-thread message is from, as the admin thread preview labels it. */
|
|
211
|
+
export const ADMIN_DISPATCH_SENDER_ROLE_LABELS = {
|
|
212
|
+
user: 'User',
|
|
213
|
+
admin: 'Admin',
|
|
214
|
+
system: 'System',
|
|
215
|
+
};
|
|
207
216
|
/** Child-safety case work statuses (the safety case console's case rows and closed-case lookup). */
|
|
208
217
|
export const CHILD_SAFETY_CASE_WORK_STATUS_LABELS = {
|
|
209
218
|
new: 'new',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-labels.js","sourceRoot":"","sources":["../../src/constants/admin-labels.ts"],"names":[],"mappings":"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","sourcesContent":["// ============================================================================\n// ADMIN-SURFACE DISPLAY LABELS — the ONE home for business display copy keyed\n// by canonical ttt-core enums (ARCH-102, extended 2026-07-13). Consolidated from\n// the former component-local maps in ttt-prod (admin-user-management-view,\n// admin-announcements-view, guided-resolution-flow). Any client (web, phone,\n// TV, admin app) renders the same labels by importing these.\n//\n// A few entries here are copy for ADMIN-MANAGED content that a PUBLIC surface also\n// renders (the rules-page group titles at the bottom of this file). The organizing\n// principle is one declaration, not one consumer.\n// ============================================================================\n\nimport type { UserAccountStatus } from '../doc-schemas/user.js';\nimport type { FeedbackType } from './business-admin.js';\nimport type { ClearableTextFieldName } from './business-content.js';\n// Value import: the per-surface override type below indexes this map to restrict each surface's\n// override keys to the fields that surface actually exposes.\nimport { HALL_CONTENT_TEXT_FIELDS } from './business-content.js';\nimport type { HallContentTextSurface } from '../doc-schemas/content.js';\nimport type { ReportDisposition, NciiInternalStatus } from '../doc-schemas/safety/foundation.js';\nimport type { ChildSafetyWorkStatus } from '../doc-schemas/safety/case.js';\nimport type { BroadcastAudienceSelector } from '../schemas/notification.js';\nimport type { DeadLetterCollection } from '../schemas/admin.js';\nimport type { GuildInviteConversationStatus, ShortLinkTargetType } from '../schemas/atoms.js';\nimport type { AdminDispatch } from '../doc-schemas/messaging.js';\nimport type { CommissionProposalStatus } from '../schemas/commissions.js';\nimport type { InviteSourceType } from '../schemas/work-project-management.js';\nimport type { Audition } from '../doc-schemas/commissions.js';\nimport type { WorkProjectType } from '../types/content.js';\nimport type { HallSubItemStatus } from '../utils/hall-content.js';\n\n/** Moderation status labels (user-management view, status badges). */\nexport const USER_ACCOUNT_STATUS_LABELS: Record<UserAccountStatus, string> = {\n active: 'Active',\n suspended: 'Suspended',\n banned: 'Banned',\n};\n\n/** Broadcast audience selector labels (announcement composer). */\nexport const BROADCAST_AUDIENCE_KIND_LABELS: Record<BroadcastAudienceSelector['kind'], string> = {\n allActiveUsers: 'All active users',\n allArtisans: 'All artisan creators',\n explicitUids: 'Specific users (paste uids)',\n workMembers: \"A Work's guild members\",\n realmMembers: \"A Realm's members\",\n};\n\n/** Human labels for the canonical feedback types — the admin feedback-suggestions views and\n * the user-facing feedback-submission surface render these instead of restating copy. Keyed\n * by FeedbackType, so a new FEEDBACK_TYPES member fails the build until its label exists.\n * UI copy uses the SHORT settled terms (Trade → \"Trades\", Craft → \"Craft Tags\", Genre →\n * \"<Kind> Genres\"), never the compound code identifiers (ARCH-107). */\nexport const FEEDBACK_TYPE_LABELS: Record<FeedbackType, string> = {\n tradeProfessionSuggestions: 'Trades',\n craftSkillTagSuggestions: 'Craft Tags',\n talesWorkGenreSuggestions: 'Tales Genres',\n tunesWorkGenreSuggestions: 'Tunes Genres',\n televisionWorkGenreSuggestions: 'Television Genres',\n};\n\n/**\n * Human labels for the raw clearable/changeable TEXT-FIELD names the moderation text-clear\n * remedy and the published \"Update details\" change-request flow work in. The backend stores and\n * validates the raw doc field names (`workingTitle`, `description`, `content`); these are the\n * only display strings for them — rendered by the member-facing \"text removed by moderation\"\n * banners, every admin clear-text field picker, the change-request dialog, and the admin\n * change-request work view. Keyed by the derived ClearableTextFieldName union, so a new\n * clearable field fails the build here until it has a label (ARCH-102).\n *\n * The `working*` pair belongs to the Work shell and the Realm doc; the labels stay the plain\n * short terms (ARCH-107 — the code identifier carries `working`, the UI never shows it).\n */\nexport const CLEARABLE_TEXT_FIELD_LABELS: Record<ClearableTextFieldName, string> = {\n workingTitle: 'Title',\n workingDescription: 'Description',\n title: 'Title',\n description: 'Description',\n content: 'Content',\n};\n\n/**\n * Per-surface label overrides for the field labels above: `[surface][field] → label`. Only a\n * surface that genuinely names a field differently appears here; everything else resolves to the\n * base map. Each surface's override keys are restricted to the fields THAT surface exposes\n * (indexed off `HALL_CONTENT_TEXT_FIELDS`), so an override for a field the surface does not have\n * is a compile error — as is an override for a surface outside `HallContentTextSurface`.\n */\nexport type ClearableTextFieldLabelOverrides = {\n [S in HallContentTextSurface]?: {\n [F in (typeof HALL_CONTENT_TEXT_FIELDS)[S][number]]?: string;\n };\n};\n\n/**\n * A Realm's identity field is called **Name** on every Realm surface (DJ ruling 2026-07-29,\n * settling a four-surface Name/Title conflict: the creation flow said \"Realm Name\", the inline\n * edit form \"Working Title\", the moderation-cleared banner \"Title\", and the request-update\n * dialog \"Name\"). The `workingTitle` doc field is shared with the Work shell, where it IS a\n * Title — so the difference is per-surface, not per-field, and lives here rather than flattening\n * one of the two settled terms.\n */\nexport const CLEARABLE_TEXT_FIELD_LABEL_OVERRIDES = {\n workRealm: { workingTitle: 'Name' },\n} as const satisfies ClearableTextFieldLabelOverrides;\n\n/**\n * The display label for one raw clearable text-field name: the surface's override when it has\n * one, otherwise the base label, otherwise the raw name. This is the ONE accessor every surface\n * calls — pass the surface whenever the caller knows it (a Realm surface must, or it renders\n * \"Title\" for a Name); omit it only for a genuinely surface-agnostic caller.\n *\n * Both parameters tolerate a plain `string` because callers read field names off stored documents\n * (`moderationClearedFields`) and callable payloads, and the surface may be the `workProject`\n * shell — which is a clearable surface but not a `HallContentTextSurface`, so it simply has no\n * overrides and falls through to the base map.\n */\nexport function clearableTextFieldLabel(field: string, surface?: string): string {\n const overrides = surface\n ? (CLEARABLE_TEXT_FIELD_LABEL_OVERRIDES as Record<string, Record<string, string> | undefined>)[\n surface\n ]\n : undefined;\n return (\n overrides?.[field] ?? (CLEARABLE_TEXT_FIELD_LABELS as Record<string, string>)[field] ?? field\n );\n}\n\n/** Human labels for the dead-letter replay ledgers (Ops Repairs dead-letter table). */\nexport const DEAD_LETTER_COLLECTION_LABELS: Record<DeadLetterCollection, string> = {\n chatSyncEvents: 'Chat sync event',\n chatAdminActionCommands: 'Chat moderation command',\n notificationDeliveries: 'Notification delivery',\n chatMessageOutbox: 'Chat message publish',\n squareAnnouncementJobs: 'Square announcement',\n chatSyncFanoutJobs: 'Chat access fanout',\n mediaAssets: 'Media authority sync',\n quarantineSagaJobs: 'Quarantine saga',\n nciiRemovalJobs: 'NCII removal',\n safetyEvidenceJobs: 'Safety evidence job',\n accountActionCommands: 'Account safety action',\n activeReportGroups: 'Report edge sync',\n hallSubItemEdgeSync: 'Hall sub-item edge sync',\n};\n\n/** Operator-settable report dispositions with their console copy. 'undetermined' is the\n * initial state, never a settable target, so it carries no option entry. */\nexport const REPORT_DISPOSITION_OPTIONS: readonly {\n value: Exclude<ReportDisposition, 'undetermined'>;\n label: string;\n description: string;\n}[] = [\n {\n value: 'reportRequired',\n label: 'Report required (NCMEC)',\n description:\n 'Apparent CSAM — a report is legally required. Establishes actual knowledge + arms the clock.',\n },\n {\n value: 'notRequired',\n label: 'No report required',\n description: 'No reporting obligation ever arose. Disallowed once there is a validated match.',\n },\n {\n value: 'correctedNoApparentViolation',\n label: 'False positive — correct it',\n description: 'There was a triggering signal but on review it is a false positive.',\n },\n];\n\n/** One user-facing reason option (shown to the affected user for any user-affecting action). */\nexport interface UserFacingReasonOption {\n code: string;\n label: string;\n description: string;\n}\n\n/** User-facing reason picklist for the guided case-resolution flow — the affected user sees the\n * label for any user-affecting action. Canonical home (ARCH-102): the codes ARE this list's own\n * enumeration, so every client (web, phone, TV, admin app) renders the same options + labels by\n * importing from here. Final user-/legal-facing wording is subject to lawyer review; these are\n * functional defaults. */\nexport const USER_FACING_REASON_OPTIONS: readonly UserFacingReasonOption[] = [\n { code: 'harassment', label: 'Harassment or bullying', description: 'Targeted abuse, threats, or sustained harassment of a person.' },\n { code: 'hate', label: 'Hate speech', description: 'Attacks on people based on a protected characteristic.' },\n { code: 'adult-content', label: 'Explicit / adult content', description: 'Sexual or graphic content not allowed on the platform.' },\n { code: 'violence', label: 'Violence or threats', description: 'Threats of violence, or content glorifying or inciting it.' },\n { code: 'spam', label: 'Spam or scam', description: 'Unsolicited bulk content, deceptive links, or fraud.' },\n { code: 'impersonation', label: 'Impersonation', description: 'Pretending to be another person, brand, or entity.' },\n { code: 'ip', label: 'Intellectual property', description: 'Use of someone else’s work without the right to do so.' },\n { code: 'nonconsensual', label: 'Nonconsensual intimate imagery', description: 'Intimate or sexual imagery shared without the subject’s consent.' },\n { code: 'safety', label: 'Safety violation', description: 'A serious safety violation handled under our safety policies.' },\n { code: 'other', label: 'Other (explain)', description: 'A policy violation not covered above — describe it in the detail box.' },\n] as const;\n\n/** The user-facing label for a reason code (undefined when the code is unknown/absent). */\nexport function userFacingReasonLabel(code: string | undefined): string | undefined {\n return USER_FACING_REASON_OPTIONS.find((o) => o.code === code)?.label;\n}\n\n// --- Rules-surface group titles ---\n// The two rule-GROUP headings for the platform rules content (`Rule.group`\n// 'workProjectType' / 'hallWingType' — see schemas/admin.ts). BOTH the admin rules editor\n// and the public rules page render these, so they are declared once here instead of being\n// restated as literals on each surface (ENG-002). Copy uses the short settled terms Work /\n// Hall / Wing (ARCH-107).\n\nexport const WORK_PROJECT_TYPE_RULE_GROUP_TITLE = 'Work Type Rules';\nexport const HALL_WING_TYPE_RULE_GROUP_TITLE = 'Hall Wing Rules';\n\n// --- Stored-enum display labels ---\n// What a screen shows for a stored enum value, keyed by the canonical union so a new member fails\n// the build until it has its text. A screen renders the label, never the raw value.\n\n/** Guild invite statuses (a Work's invited-users list and an invite conversation's status line). */\nexport const GUILD_INVITE_STATUS_LABELS: Record<GuildInviteConversationStatus, string> = {\n pending: 'Pending',\n accepted: 'Accepted',\n declined: 'Declined',\n cancelled: 'Cancelled',\n finalized: 'Finalized',\n};\n\n/** Commission proposal statuses (a Work's proposals table). */\nexport const COMMISSION_PROPOSAL_STATUS_LABELS: Record<CommissionProposalStatus, string> = {\n open: 'Open',\n invited: 'Invited',\n accepted: 'Accepted',\n rejected: 'Rejected',\n};\n\n/** Chapter, track, and episode review statuses (the Tale, Tune, and Television section tables). */\nexport const HALL_SUB_ITEM_STATUS_LABELS: Record<HallSubItemStatus, string> = {\n unpublished: 'unpublished',\n pending_approval: 'Pending approval',\n published: 'published',\n};\n\n/** Audition statuses (the audition page). */\nexport const AUDITION_STATUS_LABELS: Record<Audition['status'], string> = {\n open: 'Open',\n closed: 'Closed',\n pendingReview: 'PendingReview',\n};\n\n/** Work types (Work lists, the Work overview, the Works popover). */\nexport const WORK_PROJECT_TYPE_LABELS: Record<WorkProjectType, string> = {\n Tales: 'Tales',\n Tunes: 'Tunes',\n Television: 'Television',\n};\n\n/** Invite source types, as the invite dialog names the context an invite was sent from. */\nexport const INVITE_SOURCE_TYPE_LABELS: Record<InviteSourceType, string> = {\n standalone: 'standalone',\n craftSkill: 'craftSkill',\n commission: 'commission',\n audition: 'audition',\n};\n\n/** Short-link target types (the admin Short Links list), in the target-type enum's order. */\nexport const SHORT_LINK_TARGET_TYPE_LABELS: Record<ShortLinkTargetType, string> = {\n audition: 'Audition',\n 'audition-entry': 'Audition entry',\n commission: 'Commission',\n 'hall-library-item': 'Hall entry',\n};\n\n/** Support-thread statuses (a member's Messages, a Work's Correspondence, the admin browse list). */\nexport const ADMIN_DISPATCH_STATUS_LABELS: Record<AdminDispatch['status'], string> = {\n open: 'Open',\n user_reply: 'User replied',\n admin_reply: 'Admin replied',\n closed_resolved: 'Resolved',\n closed_unresolved: 'Closed',\n};\n\n/** Child-safety case work statuses (the safety case console's case rows and closed-case lookup). */\nexport const CHILD_SAFETY_CASE_WORK_STATUS_LABELS: Record<ChildSafetyWorkStatus, string> = {\n new: 'new',\n triaged: 'triaged',\n reporting: 'reporting',\n actioning: 'actioning',\n processing: 'processing',\n failed: 'failed',\n operationallyResolved: 'operationallyResolved',\n};\n\n/** NCII case statuses (the safety case console's case rows and closed-case lookup). */\nexport const NCII_CASE_STATUS_LABELS: Record<NciiInternalStatus, string> = {\n open: 'open',\n removalInProgress: 'removalInProgress',\n processing: 'processing',\n failed: 'failed',\n removed: 'removed',\n rejected: 'rejected',\n closed: 'closed',\n};\n"]}
|
|
1
|
+
{"version":3,"file":"admin-labels.js","sourceRoot":"","sources":["../../src/constants/admin-labels.ts"],"names":[],"mappings":"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","sourcesContent":["// ============================================================================\n// ADMIN-SURFACE DISPLAY LABELS — the ONE home for business display copy keyed\n// by canonical ttt-core enums (ARCH-102, extended 2026-07-13). Consolidated from\n// the former component-local maps in ttt-prod (admin-user-management-view,\n// admin-announcements-view, guided-resolution-flow). Any client (web, phone,\n// TV, admin app) renders the same labels by importing these.\n//\n// A few entries here are copy for ADMIN-MANAGED content that a PUBLIC surface also\n// renders (the rules-page group titles at the bottom of this file). The organizing\n// principle is one declaration, not one consumer.\n// ============================================================================\n\nimport type { UserAccountStatus } from '../doc-schemas/user.js';\nimport type { FeedbackType } from './business-admin.js';\nimport type { ClearableTextFieldName } from './business-content.js';\n// Value import: the per-surface override type below indexes this map to restrict each surface's\n// override keys to the fields that surface actually exposes.\nimport { HALL_CONTENT_TEXT_FIELDS } from './business-content.js';\nimport type { HallContentTextSurface } from '../doc-schemas/content.js';\nimport type { ReportDisposition, NciiInternalStatus } from '../doc-schemas/safety/foundation.js';\nimport type { ChildSafetyWorkStatus } from '../doc-schemas/safety/case.js';\nimport type { BroadcastAudienceSelector } from '../schemas/notification.js';\nimport type { DeadLetterCollection } from '../schemas/admin.js';\nimport type { GuildInviteConversationStatus, ShortLinkTargetType } from '../schemas/atoms.js';\nimport type { AdminDispatch, AdminDispatchSenderRole } from '../doc-schemas/messaging.js';\nimport type { CommissionProposalStatus } from '../schemas/commissions.js';\nimport type { InviteSourceType } from '../schemas/work-project-management.js';\nimport type { Audition } from '../doc-schemas/commissions.js';\nimport type { WorkProjectType } from '../types/content.js';\nimport type { HallSubItemStatus } from '../utils/hall-content.js';\n\n/** Moderation status labels (user-management view, status badges). */\nexport const USER_ACCOUNT_STATUS_LABELS: Record<UserAccountStatus, string> = {\n active: 'Active',\n suspended: 'Suspended',\n banned: 'Banned',\n};\n\n/** Broadcast audience selector labels (announcement composer). */\nexport const BROADCAST_AUDIENCE_KIND_LABELS: Record<BroadcastAudienceSelector['kind'], string> = {\n allActiveUsers: 'All active users',\n allArtisans: 'All artisan creators',\n explicitUids: 'Specific users (paste uids)',\n workMembers: \"A Work's guild members\",\n realmMembers: \"A Realm's members\",\n};\n\n/** Human labels for the canonical feedback types — the admin feedback-suggestions views and\n * the user-facing feedback-submission surface render these instead of restating copy. Keyed\n * by FeedbackType, so a new FEEDBACK_TYPES member fails the build until its label exists.\n * UI copy uses the SHORT settled terms (Trade → \"Trades\", Craft → \"Craft Tags\", Genre →\n * \"<Kind> Genres\"), never the compound code identifiers (ARCH-107). */\nexport const FEEDBACK_TYPE_LABELS: Record<FeedbackType, string> = {\n tradeProfessionSuggestions: 'Trades',\n craftSkillTagSuggestions: 'Craft Tags',\n talesWorkGenreSuggestions: 'Tales Genres',\n tunesWorkGenreSuggestions: 'Tunes Genres',\n televisionWorkGenreSuggestions: 'Television Genres',\n};\n\n/**\n * Human labels for the raw clearable/changeable TEXT-FIELD names the moderation text-clear\n * remedy and the published \"Update details\" change-request flow work in. The backend stores and\n * validates the raw doc field names (`workingTitle`, `description`, `content`); these are the\n * only display strings for them — rendered by the member-facing \"text removed by moderation\"\n * banners, every admin clear-text field picker, the change-request dialog, and the admin\n * change-request work view. Keyed by the derived ClearableTextFieldName union, so a new\n * clearable field fails the build here until it has a label (ARCH-102).\n *\n * The `working*` pair belongs to the Work shell and the Realm doc; the labels stay the plain\n * short terms (ARCH-107 — the code identifier carries `working`, the UI never shows it).\n */\nexport const CLEARABLE_TEXT_FIELD_LABELS: Record<ClearableTextFieldName, string> = {\n workingTitle: 'Title',\n workingDescription: 'Description',\n title: 'Title',\n description: 'Description',\n content: 'Content',\n};\n\n/**\n * Per-surface label overrides for the field labels above: `[surface][field] → label`. Only a\n * surface that genuinely names a field differently appears here; everything else resolves to the\n * base map. Each surface's override keys are restricted to the fields THAT surface exposes\n * (indexed off `HALL_CONTENT_TEXT_FIELDS`), so an override for a field the surface does not have\n * is a compile error — as is an override for a surface outside `HallContentTextSurface`.\n */\nexport type ClearableTextFieldLabelOverrides = {\n [S in HallContentTextSurface]?: {\n [F in (typeof HALL_CONTENT_TEXT_FIELDS)[S][number]]?: string;\n };\n};\n\n/**\n * A Realm's identity field is called **Name** on every Realm surface (DJ ruling 2026-07-29,\n * settling a four-surface Name/Title conflict: the creation flow said \"Realm Name\", the inline\n * edit form \"Working Title\", the moderation-cleared banner \"Title\", and the request-update\n * dialog \"Name\"). The `workingTitle` doc field is shared with the Work shell, where it IS a\n * Title — so the difference is per-surface, not per-field, and lives here rather than flattening\n * one of the two settled terms.\n */\nexport const CLEARABLE_TEXT_FIELD_LABEL_OVERRIDES = {\n workRealm: { workingTitle: 'Name' },\n} as const satisfies ClearableTextFieldLabelOverrides;\n\n/**\n * The display label for one raw clearable text-field name: the surface's override when it has\n * one, otherwise the base label, otherwise the raw name. This is the ONE accessor every surface\n * calls — pass the surface whenever the caller knows it (a Realm surface must, or it renders\n * \"Title\" for a Name); omit it only for a genuinely surface-agnostic caller.\n *\n * Both parameters tolerate a plain `string` because callers read field names off stored documents\n * (`moderationClearedFields`) and callable payloads, and the surface may be the `workProject`\n * shell — which is a clearable surface but not a `HallContentTextSurface`, so it simply has no\n * overrides and falls through to the base map.\n */\nexport function clearableTextFieldLabel(field: string, surface?: string): string {\n const overrides = surface\n ? (CLEARABLE_TEXT_FIELD_LABEL_OVERRIDES as Record<string, Record<string, string> | undefined>)[\n surface\n ]\n : undefined;\n return (\n overrides?.[field] ?? (CLEARABLE_TEXT_FIELD_LABELS as Record<string, string>)[field] ?? field\n );\n}\n\n/** What the admin screens show for a thread whose `awaitingAdminReply` is set. */\nexport const ADMIN_DISPATCH_AWAITING_REPLY_LABEL = 'Awaiting reply';\n\n/** Human labels for the dead-letter replay ledgers (Ops Repairs dead-letter table). */\nexport const DEAD_LETTER_COLLECTION_LABELS: Record<DeadLetterCollection, string> = {\n chatSyncEvents: 'Chat sync event',\n chatAdminActionCommands: 'Chat moderation command',\n notificationDeliveries: 'Notification delivery',\n chatMessageOutbox: 'Chat message publish',\n squareAnnouncementJobs: 'Square announcement',\n chatSyncFanoutJobs: 'Chat access fanout',\n mediaAssets: 'Media authority sync',\n quarantineSagaJobs: 'Quarantine saga',\n nciiRemovalJobs: 'NCII removal',\n safetyEvidenceJobs: 'Safety evidence job',\n accountActionCommands: 'Account safety action',\n activeReportGroups: 'Report edge sync',\n hallSubItemEdgeSync: 'Hall sub-item edge sync',\n chatParkedDeliveries: 'Chat room delivery',\n};\n\n/** Operator-settable report dispositions with their console copy. 'undetermined' is the\n * initial state, never a settable target, so it carries no option entry. */\nexport const REPORT_DISPOSITION_OPTIONS: readonly {\n value: Exclude<ReportDisposition, 'undetermined'>;\n label: string;\n description: string;\n}[] = [\n {\n value: 'reportRequired',\n label: 'Report required (NCMEC)',\n description:\n 'Apparent CSAM — a report is legally required. Establishes actual knowledge + arms the clock.',\n },\n {\n value: 'notRequired',\n label: 'No report required',\n description: 'No reporting obligation ever arose. Disallowed once there is a validated match.',\n },\n {\n value: 'correctedNoApparentViolation',\n label: 'False positive — correct it',\n description: 'There was a triggering signal but on review it is a false positive.',\n },\n];\n\n/** One user-facing reason option (shown to the affected user for any user-affecting action). */\nexport interface UserFacingReasonOption {\n code: string;\n label: string;\n description: string;\n}\n\n/** User-facing reason picklist for the guided case-resolution flow — the affected user sees the\n * label for any user-affecting action. Canonical home (ARCH-102): the codes ARE this list's own\n * enumeration, so every client (web, phone, TV, admin app) renders the same options + labels by\n * importing from here. Final user-/legal-facing wording is subject to lawyer review; these are\n * functional defaults. */\nexport const USER_FACING_REASON_OPTIONS: readonly UserFacingReasonOption[] = [\n { code: 'harassment', label: 'Harassment or bullying', description: 'Targeted abuse, threats, or sustained harassment of a person.' },\n { code: 'hate', label: 'Hate speech', description: 'Attacks on people based on a protected characteristic.' },\n { code: 'adult-content', label: 'Explicit / adult content', description: 'Sexual or graphic content not allowed on the platform.' },\n { code: 'violence', label: 'Violence or threats', description: 'Threats of violence, or content glorifying or inciting it.' },\n { code: 'spam', label: 'Spam or scam', description: 'Unsolicited bulk content, deceptive links, or fraud.' },\n { code: 'impersonation', label: 'Impersonation', description: 'Pretending to be another person, brand, or entity.' },\n { code: 'ip', label: 'Intellectual property', description: 'Use of someone else’s work without the right to do so.' },\n { code: 'nonconsensual', label: 'Nonconsensual intimate imagery', description: 'Intimate or sexual imagery shared without the subject’s consent.' },\n { code: 'safety', label: 'Safety violation', description: 'A serious safety violation handled under our safety policies.' },\n { code: 'other', label: 'Other (explain)', description: 'A policy violation not covered above — describe it in the detail box.' },\n] as const;\n\n/** The user-facing label for a reason code (undefined when the code is unknown/absent). */\nexport function userFacingReasonLabel(code: string | undefined): string | undefined {\n return USER_FACING_REASON_OPTIONS.find((o) => o.code === code)?.label;\n}\n\n// --- Rules-surface group titles ---\n// The two rule-GROUP headings for the platform rules content (`Rule.group`\n// 'workProjectType' / 'hallWingType' — see schemas/admin.ts). BOTH the admin rules editor\n// and the public rules page render these, so they are declared once here instead of being\n// restated as literals on each surface (ENG-002). Copy uses the short settled terms Work /\n// Hall / Wing (ARCH-107).\n\nexport const WORK_PROJECT_TYPE_RULE_GROUP_TITLE = 'Work Type Rules';\nexport const HALL_WING_TYPE_RULE_GROUP_TITLE = 'Hall Wing Rules';\n\n// --- Stored-enum display labels ---\n// What a screen shows for a stored enum value, keyed by the canonical union so a new member fails\n// the build until it has its text. A screen renders the label, never the raw value.\n\n/** Guild invite statuses (a Work's invited-users list and an invite conversation's status line). */\nexport const GUILD_INVITE_STATUS_LABELS: Record<GuildInviteConversationStatus, string> = {\n pending: 'Pending',\n accepted: 'Accepted',\n declined: 'Declined',\n cancelled: 'Cancelled',\n finalized: 'Finalized',\n};\n\n/** Commission proposal statuses (a Work's proposals table). */\nexport const COMMISSION_PROPOSAL_STATUS_LABELS: Record<CommissionProposalStatus, string> = {\n open: 'Open',\n invited: 'Invited',\n accepted: 'Accepted',\n rejected: 'Rejected',\n};\n\n/** Chapter, track, and episode review statuses (the Tale, Tune, and Television section tables). */\nexport const HALL_SUB_ITEM_STATUS_LABELS: Record<HallSubItemStatus, string> = {\n unpublished: 'unpublished',\n pending_approval: 'Pending approval',\n published: 'published',\n};\n\n/** Audition statuses (the audition page). */\nexport const AUDITION_STATUS_LABELS: Record<Audition['status'], string> = {\n open: 'Open',\n closed: 'Closed',\n pendingReview: 'PendingReview',\n};\n\n/** Work types (Work lists, the Work overview, the Works popover). */\nexport const WORK_PROJECT_TYPE_LABELS: Record<WorkProjectType, string> = {\n Tales: 'Tales',\n Tunes: 'Tunes',\n Television: 'Television',\n};\n\n/** Invite source types, as the invite dialog names the context an invite was sent from. */\nexport const INVITE_SOURCE_TYPE_LABELS: Record<InviteSourceType, string> = {\n standalone: 'standalone',\n craftSkill: 'craftSkill',\n commission: 'commission',\n audition: 'audition',\n};\n\n/** Short-link target types (the admin Short Links list), in the target-type enum's order. */\nexport const SHORT_LINK_TARGET_TYPE_LABELS: Record<ShortLinkTargetType, string> = {\n audition: 'Audition',\n 'audition-entry': 'Audition entry',\n commission: 'Commission',\n 'hall-library-item': 'Hall entry',\n};\n\n/** Support-thread statuses (a member's Messages, a Work's Correspondence, the admin browse list). */\nexport const ADMIN_DISPATCH_STATUS_LABELS: Record<AdminDispatch['status'], string> = {\n open: 'Open',\n user_reply: 'User replied',\n admin_reply: 'Admin replied',\n closed_resolved: 'Resolved',\n closed_unresolved: 'Closed',\n};\n\n/** Who a support-thread message is from, as the admin thread preview labels it. */\nexport const ADMIN_DISPATCH_SENDER_ROLE_LABELS: Record<AdminDispatchSenderRole, string> = {\n user: 'User',\n admin: 'Admin',\n system: 'System',\n};\n\n/** Child-safety case work statuses (the safety case console's case rows and closed-case lookup). */\nexport const CHILD_SAFETY_CASE_WORK_STATUS_LABELS: Record<ChildSafetyWorkStatus, string> = {\n new: 'new',\n triaged: 'triaged',\n reporting: 'reporting',\n actioning: 'actioning',\n processing: 'processing',\n failed: 'failed',\n operationallyResolved: 'operationallyResolved',\n};\n\n/** NCII case statuses (the safety case console's case rows and closed-case lookup). */\nexport const NCII_CASE_STATUS_LABELS: Record<NciiInternalStatus, string> = {\n open: 'open',\n removalInProgress: 'removalInProgress',\n processing: 'processing',\n failed: 'failed',\n removed: 'removed',\n rejected: 'rejected',\n closed: 'closed',\n};\n"]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { Audition } from '../doc-schemas/commissions.js';
|
|
3
|
+
/** Entries close at least this long after the audition is posted. */
|
|
4
|
+
export declare const AUDITION_MIN_ENTRY_WINDOW_MS: number;
|
|
5
|
+
/** The audition closes at least this long after entries close (voting continues meanwhile). */
|
|
6
|
+
export declare const AUDITION_MIN_VOTING_AFTER_ENTRIES_MS: number;
|
|
7
|
+
/** The entries-close picker opens this many weeks after today, at the end of that day. */
|
|
8
|
+
export declare const AUDITION_DEFAULT_ENTRY_WINDOW_WEEKS = 3;
|
|
9
|
+
/** The audition-close picker opens this many days after entries close, at the end of that day. */
|
|
10
|
+
export declare const AUDITION_DEFAULT_CLOSE_AFTER_ENTRIES_DAYS = 1;
|
|
11
|
+
/** End of a day, as the date-and-time picker expresses it: 11:59 PM local time. */
|
|
12
|
+
export declare const AUDITION_END_OF_DAY: {
|
|
13
|
+
readonly hours: 23;
|
|
14
|
+
readonly minutes: 59;
|
|
15
|
+
};
|
|
16
|
+
/** One deadline: epoch milliseconds. */
|
|
17
|
+
export declare const AuditionDeadlineSchema: z.ZodNumber;
|
|
18
|
+
export interface AuditionDeadlines {
|
|
19
|
+
entriesCloseAt: number;
|
|
20
|
+
auditionCloseAt: number;
|
|
21
|
+
}
|
|
22
|
+
/** Which minimum gap a pair of deadlines breaks. */
|
|
23
|
+
export type AuditionDeadlineProblem = 'entriesCloseTooSoon' | 'auditionCloseTooSoon';
|
|
24
|
+
/** The refusal each broken minimum gap answers with — the server's refusal and the form's alike. */
|
|
25
|
+
export declare const AUDITION_DEADLINE_PROBLEM_MESSAGES: Record<AuditionDeadlineProblem, string>;
|
|
26
|
+
/**
|
|
27
|
+
* The deadline-pair rule every wire schema carrying both deadlines refines with: the audition
|
|
28
|
+
* closes at least `AUDITION_MIN_VOTING_AFTER_ENTRIES_MS` after entries close. (The gap from the
|
|
29
|
+
* posting time depends on WHEN the audition is posted, so it is checked by
|
|
30
|
+
* `auditionDeadlineProblem` at the moment of posting, never inside a schema a later step
|
|
31
|
+
* re-parses.)
|
|
32
|
+
*/
|
|
33
|
+
export declare function refineAuditionDeadlineOrder(value: AuditionDeadlines, ctx: z.RefinementCtx): void;
|
|
34
|
+
/** The earliest allowed entries-close time for an audition posted at `postedAt`. */
|
|
35
|
+
export declare function earliestAuditionEntriesCloseAt(postedAt: number): number;
|
|
36
|
+
/** The earliest allowed audition-close time for entries closing at `entriesCloseAt`. */
|
|
37
|
+
export declare function earliestAuditionCloseAt(entriesCloseAt: number): number;
|
|
38
|
+
/**
|
|
39
|
+
* Which minimum gap `deadlines` break for an audition posted at `postedAt` — the submit time
|
|
40
|
+
* of its upload — or `null` when both hold.
|
|
41
|
+
*/
|
|
42
|
+
export declare function auditionDeadlineProblem(deadlines: AuditionDeadlines, postedAt: number): AuditionDeadlineProblem | null;
|
|
43
|
+
/**
|
|
44
|
+
* Whether an entry submitted at `submittedAt` is in time: the audition is open and the entry
|
|
45
|
+
* was submitted before entries closed. The server passes the upload's submit time (so a
|
|
46
|
+
* slow-processing entry submitted in time still counts); the UI passes now.
|
|
47
|
+
*/
|
|
48
|
+
export declare function areAuditionEntriesOpen(audition: Pick<Audition, 'status' | 'entriesCloseAt'>, submittedAt: number): boolean;
|
|
49
|
+
/** Whether a vote cast at `now` is in time: the audition is open and has not closed. */
|
|
50
|
+
export declare function isAuditionVotingOpen(audition: Pick<Audition, 'status' | 'auditionCloseAt'>, now: number): boolean;
|
|
51
|
+
/** Where the entries-close picker opens: the end of the day three weeks from `today`. */
|
|
52
|
+
export declare function defaultAuditionEntriesCloseAt(today: Date): Date;
|
|
53
|
+
/**
|
|
54
|
+
* Where the audition-close picker opens: the end of the day after entries close — or of the
|
|
55
|
+
* next day that keeps the 24-hour minimum, should a clock change shorten that day.
|
|
56
|
+
*/
|
|
57
|
+
export declare function defaultAuditionCloseAt(entriesCloseAt: Date): Date;
|
|
58
|
+
//# sourceMappingURL=audition-deadlines.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audition-deadlines.d.ts","sourceRoot":"","sources":["../../src/constants/audition-deadlines.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAM9D,qEAAqE;AACrE,eAAO,MAAM,4BAA4B,QAAa,CAAC;AAEvD,+FAA+F;AAC/F,eAAO,MAAM,oCAAoC,QAAe,CAAC;AAEjE,0FAA0F;AAC1F,eAAO,MAAM,mCAAmC,IAAI,CAAC;AAErD,kGAAkG;AAClG,eAAO,MAAM,yCAAyC,IAAI,CAAC;AAE3D,mFAAmF;AACnF,eAAO,MAAM,mBAAmB;;;CAAsC,CAAC;AAEvE,wCAAwC;AACxC,eAAO,MAAM,sBAAsB,aAA8B,CAAC;AAElE,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,oDAAoD;AACpD,MAAM,MAAM,uBAAuB,GAAG,qBAAqB,GAAG,sBAAsB,CAAC;AAErF,oGAAoG;AACpG,eAAO,MAAM,kCAAkC,EAAE,MAAM,CAAC,uBAAuB,EAAE,MAAM,CAGtF,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,CAAC,CAAC,aAAa,GAAG,IAAI,CAIhG;AAED,oFAAoF;AACpF,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED,wFAAwF;AACxF,wBAAgB,uBAAuB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,iBAAiB,EAC5B,QAAQ,EAAE,MAAM,GACf,uBAAuB,GAAG,IAAI,CAIhC;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,gBAAgB,CAAC,EACrD,WAAW,EAAE,MAAM,GAClB,OAAO,CAET;AAED,wFAAwF;AACxF,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,iBAAiB,CAAC,EACtD,GAAG,EAAE,MAAM,GACV,OAAO,CAET;AAMD,yFAAyF;AACzF,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,CAM/D;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,cAAc,EAAE,IAAI,GAAG,IAAI,CAQjE"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// An audition's two deadlines, both picked by its poster:
|
|
2
|
+
// - entries close (`entriesCloseAt`) — an entry counts by the moment it was SUBMITTED, so one
|
|
3
|
+
// uploaded before the cut-off still publishes if its processing finishes after it;
|
|
4
|
+
// - the audition closes (`auditionCloseAt`) — voting runs until then.
|
|
5
|
+
// Entries and voting both open when the audition is posted. The server enforces both cut-offs
|
|
6
|
+
// exactly through the predicates below; the daily job only tidies `status`. The UI offers an
|
|
7
|
+
// action from the same predicates (FRONTEND-110).
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
const MINUTE_MS = 60 * 1000;
|
|
10
|
+
const HOUR_MS = 60 * MINUTE_MS;
|
|
11
|
+
const DAY_MS = 24 * HOUR_MS;
|
|
12
|
+
/** Entries close at least this long after the audition is posted. */
|
|
13
|
+
export const AUDITION_MIN_ENTRY_WINDOW_MS = 7 * DAY_MS;
|
|
14
|
+
/** The audition closes at least this long after entries close (voting continues meanwhile). */
|
|
15
|
+
export const AUDITION_MIN_VOTING_AFTER_ENTRIES_MS = 24 * HOUR_MS;
|
|
16
|
+
/** The entries-close picker opens this many weeks after today, at the end of that day. */
|
|
17
|
+
export const AUDITION_DEFAULT_ENTRY_WINDOW_WEEKS = 3;
|
|
18
|
+
/** The audition-close picker opens this many days after entries close, at the end of that day. */
|
|
19
|
+
export const AUDITION_DEFAULT_CLOSE_AFTER_ENTRIES_DAYS = 1;
|
|
20
|
+
/** End of a day, as the date-and-time picker expresses it: 11:59 PM local time. */
|
|
21
|
+
export const AUDITION_END_OF_DAY = { hours: 23, minutes: 59 };
|
|
22
|
+
/** One deadline: epoch milliseconds. */
|
|
23
|
+
export const AuditionDeadlineSchema = z.number().int().positive();
|
|
24
|
+
/** The refusal each broken minimum gap answers with — the server's refusal and the form's alike. */
|
|
25
|
+
export const AUDITION_DEADLINE_PROBLEM_MESSAGES = {
|
|
26
|
+
entriesCloseTooSoon: `Entries must stay open for at least ${AUDITION_MIN_ENTRY_WINDOW_MS / DAY_MS} days after posting.`,
|
|
27
|
+
auditionCloseTooSoon: `The audition must close at least ${AUDITION_MIN_VOTING_AFTER_ENTRIES_MS / HOUR_MS} hours after entries close.`,
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* The deadline-pair rule every wire schema carrying both deadlines refines with: the audition
|
|
31
|
+
* closes at least `AUDITION_MIN_VOTING_AFTER_ENTRIES_MS` after entries close. (The gap from the
|
|
32
|
+
* posting time depends on WHEN the audition is posted, so it is checked by
|
|
33
|
+
* `auditionDeadlineProblem` at the moment of posting, never inside a schema a later step
|
|
34
|
+
* re-parses.)
|
|
35
|
+
*/
|
|
36
|
+
export function refineAuditionDeadlineOrder(value, ctx) {
|
|
37
|
+
if (value.auditionCloseAt < value.entriesCloseAt + AUDITION_MIN_VOTING_AFTER_ENTRIES_MS) {
|
|
38
|
+
ctx.addIssue({ code: 'custom', path: ['auditionCloseAt'] });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** The earliest allowed entries-close time for an audition posted at `postedAt`. */
|
|
42
|
+
export function earliestAuditionEntriesCloseAt(postedAt) {
|
|
43
|
+
return postedAt + AUDITION_MIN_ENTRY_WINDOW_MS;
|
|
44
|
+
}
|
|
45
|
+
/** The earliest allowed audition-close time for entries closing at `entriesCloseAt`. */
|
|
46
|
+
export function earliestAuditionCloseAt(entriesCloseAt) {
|
|
47
|
+
return entriesCloseAt + AUDITION_MIN_VOTING_AFTER_ENTRIES_MS;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Which minimum gap `deadlines` break for an audition posted at `postedAt` — the submit time
|
|
51
|
+
* of its upload — or `null` when both hold.
|
|
52
|
+
*/
|
|
53
|
+
export function auditionDeadlineProblem(deadlines, postedAt) {
|
|
54
|
+
if (deadlines.entriesCloseAt < earliestAuditionEntriesCloseAt(postedAt))
|
|
55
|
+
return 'entriesCloseTooSoon';
|
|
56
|
+
if (deadlines.auditionCloseAt < earliestAuditionCloseAt(deadlines.entriesCloseAt))
|
|
57
|
+
return 'auditionCloseTooSoon';
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Whether an entry submitted at `submittedAt` is in time: the audition is open and the entry
|
|
62
|
+
* was submitted before entries closed. The server passes the upload's submit time (so a
|
|
63
|
+
* slow-processing entry submitted in time still counts); the UI passes now.
|
|
64
|
+
*/
|
|
65
|
+
export function areAuditionEntriesOpen(audition, submittedAt) {
|
|
66
|
+
return audition.status === 'open' && submittedAt < audition.entriesCloseAt;
|
|
67
|
+
}
|
|
68
|
+
/** Whether a vote cast at `now` is in time: the audition is open and has not closed. */
|
|
69
|
+
export function isAuditionVotingOpen(audition, now) {
|
|
70
|
+
return audition.status === 'open' && now < audition.auditionCloseAt;
|
|
71
|
+
}
|
|
72
|
+
function endOfLocalDay(year, monthIndex, day) {
|
|
73
|
+
return new Date(year, monthIndex, day, AUDITION_END_OF_DAY.hours, AUDITION_END_OF_DAY.minutes, 0, 0);
|
|
74
|
+
}
|
|
75
|
+
/** Where the entries-close picker opens: the end of the day three weeks from `today`. */
|
|
76
|
+
export function defaultAuditionEntriesCloseAt(today) {
|
|
77
|
+
return endOfLocalDay(today.getFullYear(), today.getMonth(), today.getDate() + AUDITION_DEFAULT_ENTRY_WINDOW_WEEKS * 7);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Where the audition-close picker opens: the end of the day after entries close — or of the
|
|
81
|
+
* next day that keeps the 24-hour minimum, should a clock change shorten that day.
|
|
82
|
+
*/
|
|
83
|
+
export function defaultAuditionCloseAt(entriesCloseAt) {
|
|
84
|
+
let offset = AUDITION_DEFAULT_CLOSE_AFTER_ENTRIES_DAYS;
|
|
85
|
+
let candidate = endOfLocalDay(entriesCloseAt.getFullYear(), entriesCloseAt.getMonth(), entriesCloseAt.getDate() + offset);
|
|
86
|
+
while (candidate.getTime() < earliestAuditionCloseAt(entriesCloseAt.getTime())) {
|
|
87
|
+
offset += 1;
|
|
88
|
+
candidate = endOfLocalDay(entriesCloseAt.getFullYear(), entriesCloseAt.getMonth(), entriesCloseAt.getDate() + offset);
|
|
89
|
+
}
|
|
90
|
+
return candidate;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=audition-deadlines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audition-deadlines.js","sourceRoot":"","sources":["../../src/constants/audition-deadlines.ts"],"names":[],"mappings":"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","sourcesContent":["// An audition's two deadlines, both picked by its poster:\n// - entries close (`entriesCloseAt`) — an entry counts by the moment it was SUBMITTED, so one\n// uploaded before the cut-off still publishes if its processing finishes after it;\n// - the audition closes (`auditionCloseAt`) — voting runs until then.\n// Entries and voting both open when the audition is posted. The server enforces both cut-offs\n// exactly through the predicates below; the daily job only tidies `status`. The UI offers an\n// action from the same predicates (FRONTEND-110).\n\nimport { z } from 'zod';\nimport type { Audition } from '../doc-schemas/commissions.js';\n\nconst MINUTE_MS = 60 * 1000;\nconst HOUR_MS = 60 * MINUTE_MS;\nconst DAY_MS = 24 * HOUR_MS;\n\n/** Entries close at least this long after the audition is posted. */\nexport const AUDITION_MIN_ENTRY_WINDOW_MS = 7 * DAY_MS;\n\n/** The audition closes at least this long after entries close (voting continues meanwhile). */\nexport const AUDITION_MIN_VOTING_AFTER_ENTRIES_MS = 24 * HOUR_MS;\n\n/** The entries-close picker opens this many weeks after today, at the end of that day. */\nexport const AUDITION_DEFAULT_ENTRY_WINDOW_WEEKS = 3;\n\n/** The audition-close picker opens this many days after entries close, at the end of that day. */\nexport const AUDITION_DEFAULT_CLOSE_AFTER_ENTRIES_DAYS = 1;\n\n/** End of a day, as the date-and-time picker expresses it: 11:59 PM local time. */\nexport const AUDITION_END_OF_DAY = { hours: 23, minutes: 59 } as const;\n\n/** One deadline: epoch milliseconds. */\nexport const AuditionDeadlineSchema = z.number().int().positive();\n\nexport interface AuditionDeadlines {\n entriesCloseAt: number;\n auditionCloseAt: number;\n}\n\n/** Which minimum gap a pair of deadlines breaks. */\nexport type AuditionDeadlineProblem = 'entriesCloseTooSoon' | 'auditionCloseTooSoon';\n\n/** The refusal each broken minimum gap answers with — the server's refusal and the form's alike. */\nexport const AUDITION_DEADLINE_PROBLEM_MESSAGES: Record<AuditionDeadlineProblem, string> = {\n entriesCloseTooSoon: `Entries must stay open for at least ${AUDITION_MIN_ENTRY_WINDOW_MS / DAY_MS} days after posting.`,\n auditionCloseTooSoon: `The audition must close at least ${AUDITION_MIN_VOTING_AFTER_ENTRIES_MS / HOUR_MS} hours after entries close.`,\n};\n\n/**\n * The deadline-pair rule every wire schema carrying both deadlines refines with: the audition\n * closes at least `AUDITION_MIN_VOTING_AFTER_ENTRIES_MS` after entries close. (The gap from the\n * posting time depends on WHEN the audition is posted, so it is checked by\n * `auditionDeadlineProblem` at the moment of posting, never inside a schema a later step\n * re-parses.)\n */\nexport function refineAuditionDeadlineOrder(value: AuditionDeadlines, ctx: z.RefinementCtx): void {\n if (value.auditionCloseAt < value.entriesCloseAt + AUDITION_MIN_VOTING_AFTER_ENTRIES_MS) {\n ctx.addIssue({ code: 'custom', path: ['auditionCloseAt'] });\n }\n}\n\n/** The earliest allowed entries-close time for an audition posted at `postedAt`. */\nexport function earliestAuditionEntriesCloseAt(postedAt: number): number {\n return postedAt + AUDITION_MIN_ENTRY_WINDOW_MS;\n}\n\n/** The earliest allowed audition-close time for entries closing at `entriesCloseAt`. */\nexport function earliestAuditionCloseAt(entriesCloseAt: number): number {\n return entriesCloseAt + AUDITION_MIN_VOTING_AFTER_ENTRIES_MS;\n}\n\n/**\n * Which minimum gap `deadlines` break for an audition posted at `postedAt` — the submit time\n * of its upload — or `null` when both hold.\n */\nexport function auditionDeadlineProblem(\n deadlines: AuditionDeadlines,\n postedAt: number,\n): AuditionDeadlineProblem | null {\n if (deadlines.entriesCloseAt < earliestAuditionEntriesCloseAt(postedAt)) return 'entriesCloseTooSoon';\n if (deadlines.auditionCloseAt < earliestAuditionCloseAt(deadlines.entriesCloseAt)) return 'auditionCloseTooSoon';\n return null;\n}\n\n/**\n * Whether an entry submitted at `submittedAt` is in time: the audition is open and the entry\n * was submitted before entries closed. The server passes the upload's submit time (so a\n * slow-processing entry submitted in time still counts); the UI passes now.\n */\nexport function areAuditionEntriesOpen(\n audition: Pick<Audition, 'status' | 'entriesCloseAt'>,\n submittedAt: number,\n): boolean {\n return audition.status === 'open' && submittedAt < audition.entriesCloseAt;\n}\n\n/** Whether a vote cast at `now` is in time: the audition is open and has not closed. */\nexport function isAuditionVotingOpen(\n audition: Pick<Audition, 'status' | 'auditionCloseAt'>,\n now: number,\n): boolean {\n return audition.status === 'open' && now < audition.auditionCloseAt;\n}\n\nfunction endOfLocalDay(year: number, monthIndex: number, day: number): Date {\n return new Date(year, monthIndex, day, AUDITION_END_OF_DAY.hours, AUDITION_END_OF_DAY.minutes, 0, 0);\n}\n\n/** Where the entries-close picker opens: the end of the day three weeks from `today`. */\nexport function defaultAuditionEntriesCloseAt(today: Date): Date {\n return endOfLocalDay(\n today.getFullYear(),\n today.getMonth(),\n today.getDate() + AUDITION_DEFAULT_ENTRY_WINDOW_WEEKS * 7,\n );\n}\n\n/**\n * Where the audition-close picker opens: the end of the day after entries close — or of the\n * next day that keeps the 24-hour minimum, should a clock change shorten that day.\n */\nexport function defaultAuditionCloseAt(entriesCloseAt: Date): Date {\n let offset = AUDITION_DEFAULT_CLOSE_AFTER_ENTRIES_DAYS;\n let candidate = endOfLocalDay(entriesCloseAt.getFullYear(), entriesCloseAt.getMonth(), entriesCloseAt.getDate() + offset);\n while (candidate.getTime() < earliestAuditionCloseAt(entriesCloseAt.getTime())) {\n offset += 1;\n candidate = endOfLocalDay(entriesCloseAt.getFullYear(), entriesCloseAt.getMonth(), entriesCloseAt.getDate() + offset);\n }\n return candidate;\n}\n"]}
|
package/dist/constants/chat.d.ts
CHANGED
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Maximum chat message length (characters) used by ttt-core's chat callable
|
|
3
|
-
* and system-message-action schemas for backend validation.
|
|
4
|
-
*
|
|
5
|
-
* Split ownership by design: chat-core owns its own UI/runtime default
|
|
6
|
-
* (`MAX_CHAT_MESSAGE_LENGTH` in `chat-core/src/constants.ts`); ttt-core owns
|
|
7
|
-
* the value used by callable wire validation. The values are intentionally
|
|
8
|
-
* aligned at 4000; consumers wanting a different limit should override at
|
|
9
|
-
* their own call site rather than expecting cross-package coordination.
|
|
10
|
-
*/
|
|
11
|
-
export declare const MAX_CHAT_MESSAGE_LENGTH = 4000;
|
|
12
1
|
/** Guild chat channel name — one owner for the create/update callable schemas AND the
|
|
13
2
|
* channel form (whose zod previously carried its own 50 while the backend allowed 100). */
|
|
14
3
|
export declare const MAX_GUILD_CHAT_CHANNEL_NAME_LENGTH = 50;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/constants/chat.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/constants/chat.ts"],"names":[],"mappings":"AAAA;4FAC4F;AAC5F,eAAO,MAAM,kCAAkC,KAAK,CAAC;AAErD,2EAA2E;AAC3E,eAAO,MAAM,yCAAyC,MAAM,CAAC;AAE7D;;;;;;;GAOG;AACH,eAAO,MAAM,oCAAoC,mEACiB,CAAC"}
|
package/dist/constants/chat.js
CHANGED
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Maximum chat message length (characters) used by ttt-core's chat callable
|
|
3
|
-
* and system-message-action schemas for backend validation.
|
|
4
|
-
*
|
|
5
|
-
* Split ownership by design: chat-core owns its own UI/runtime default
|
|
6
|
-
* (`MAX_CHAT_MESSAGE_LENGTH` in `chat-core/src/constants.ts`); ttt-core owns
|
|
7
|
-
* the value used by callable wire validation. The values are intentionally
|
|
8
|
-
* aligned at 4000; consumers wanting a different limit should override at
|
|
9
|
-
* their own call site rather than expecting cross-package coordination.
|
|
10
|
-
*/
|
|
11
|
-
export const MAX_CHAT_MESSAGE_LENGTH = 4000;
|
|
12
1
|
/** Guild chat channel name — one owner for the create/update callable schemas AND the
|
|
13
2
|
* channel form (whose zod previously carried its own 50 while the backend allowed 100). */
|
|
14
3
|
export const MAX_GUILD_CHAT_CHANNEL_NAME_LENGTH = 50;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/constants/chat.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/constants/chat.ts"],"names":[],"mappings":"AAAA;4FAC4F;AAC5F,MAAM,CAAC,MAAM,kCAAkC,GAAG,EAAE,CAAC;AAErD,2EAA2E;AAC3E,MAAM,CAAC,MAAM,yCAAyC,GAAG,GAAG,CAAC;AAE7D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,oCAAoC,GAC/C,gEAAgE,CAAC","sourcesContent":["/** Guild chat channel name — one owner for the create/update callable schemas AND the\n * channel form (whose zod previously carried its own 50 while the backend allowed 100). */\nexport const MAX_GUILD_CHAT_CHANNEL_NAME_LENGTH = 50;\n\n/** Guild chat channel description — same single-owner rule as the name. */\nexport const MAX_GUILD_CHAT_CHANNEL_DESCRIPTION_LENGTH = 150;\n\n/**\n * The ONE user-facing sentence for \"the chat service itself is down right now\"\n * (DJ ruling 2026-07-30). A chat callable that cannot reach the Cloudflare chat Worker\n * answers `unavailable` with this message, and every chat call site renders this copy\n * instead of the generic error toast — so an outage reads as an outage, on both sides of\n * the wire. Shared by the backend answer text (functions chat-internal-call) and the\n * client surface (src/lib/chat-realtime), which previously carried two hand-synced copies.\n */\nexport const CHAT_TEMPORARILY_UNAVAILABLE_MESSAGE =\n 'Chat is temporarily unavailable. Please try again in a moment.';\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC;AACzC,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC;AACzC,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC"}
|
package/dist/constants/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC;AACzC,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC","sourcesContent":["export * from './analytics.js';\nexport * from './app-mode.js';\nexport * from './business.js';\nexport * from './chat.js';\nexport * from './conversation-files.js';\nexport * from './moderation.js';\nexport * from './options.js';\nexport * from './admin-labels.js';\nexport * from './craft-skill-statements.js';\nexport * from './publish-attestations.js';\nexport * from './pledge-and-bouquet-copy.js';\nexport * from './public-documents.js';\nexport * from './legal-review-notice-state.js';\nexport * from './legal-review-notice.js';\nexport * from './safety-confirmation-phrases.js';\nexport * from './safety-telemetry-patterns.js';\nexport * from './safety-active-statuses.js';\nexport * from './telemetry-content-policy.js';\nexport * from './pagination.js';\nexport * from './release-flags.js';\nexport * from './retention.js';\nexport * from './scheduled-jobs.js';\nexport * from './media-download.js';\nexport * from './media-processing.js';\nexport * from './storage-keys.js';\nexport * from './company-mascots.js';\nexport * from './center-stage-rooms.js';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC;AACzC,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC","sourcesContent":["export * from './analytics.js';\nexport * from './app-mode.js';\nexport * from './business.js';\nexport * from './chat.js';\nexport * from './conversation-files.js';\nexport * from './moderation.js';\nexport * from './options.js';\nexport * from './admin-labels.js';\nexport * from './craft-skill-statements.js';\nexport * from './publish-attestations.js';\nexport * from './pledge-and-bouquet-copy.js';\nexport * from './public-documents.js';\nexport * from './legal-review-notice-state.js';\nexport * from './legal-review-notice.js';\nexport * from './safety-confirmation-phrases.js';\nexport * from './safety-telemetry-patterns.js';\nexport * from './safety-active-statuses.js';\nexport * from './telemetry-content-policy.js';\nexport * from './pagination.js';\nexport * from './release-flags.js';\nexport * from './retention.js';\nexport * from './scheduled-jobs.js';\nexport * from './media-download.js';\nexport * from './media-processing.js';\nexport * from './storage-keys.js';\nexport * from './company-mascots.js';\nexport * from './center-stage-rooms.js';\nexport * from './audition-deadlines.js';\n"]}
|
|
@@ -73,7 +73,7 @@ export declare const AUDITION_SORT_OPTIONS: {
|
|
|
73
73
|
};
|
|
74
74
|
readonly endingSoon: {
|
|
75
75
|
readonly label: "Ending Soon";
|
|
76
|
-
readonly field: "
|
|
76
|
+
readonly field: "auditionCloseAt";
|
|
77
77
|
readonly direction: "asc";
|
|
78
78
|
};
|
|
79
79
|
};
|
|
@@ -85,7 +85,7 @@ export declare const AUDITION_SORT_OPTIONS: {
|
|
|
85
85
|
};
|
|
86
86
|
readonly endingSoon: {
|
|
87
87
|
readonly label: "Ending Soon";
|
|
88
|
-
readonly field: "
|
|
88
|
+
readonly field: "auditionCloseAt";
|
|
89
89
|
readonly direction: "asc";
|
|
90
90
|
};
|
|
91
91
|
};
|
|
@@ -107,7 +107,7 @@ export declare const AUDITION_SORT_OPTIONS: {
|
|
|
107
107
|
};
|
|
108
108
|
readonly endingSoon: {
|
|
109
109
|
readonly label: "Ending Soon";
|
|
110
|
-
readonly field: "
|
|
110
|
+
readonly field: "auditionCloseAt";
|
|
111
111
|
readonly direction: "asc";
|
|
112
112
|
};
|
|
113
113
|
};
|
|
@@ -129,7 +129,7 @@ export declare const AUDITION_SORT_OPTIONS: {
|
|
|
129
129
|
};
|
|
130
130
|
readonly endingSoon: {
|
|
131
131
|
readonly label: "Ending Soon";
|
|
132
|
-
readonly field: "
|
|
132
|
+
readonly field: "auditionCloseAt";
|
|
133
133
|
readonly direction: "asc";
|
|
134
134
|
};
|
|
135
135
|
};
|
|
@@ -223,7 +223,7 @@ export const AUDITION_TYPE_FILTER_ALL = 'All';
|
|
|
223
223
|
*/
|
|
224
224
|
const AUDITION_SORT_OPTIONS_BASE = {
|
|
225
225
|
newest: { label: 'Newest First', field: 'createdOn', direction: 'desc' },
|
|
226
|
-
endingSoon: { label: 'Ending Soon', field: '
|
|
226
|
+
endingSoon: { label: 'Ending Soon', field: 'auditionCloseAt', direction: 'asc' },
|
|
227
227
|
};
|
|
228
228
|
/** Sort options shown on the audition feeds, keyed by feed type. `default` serves the board's
|
|
229
229
|
* ALL filter; `platformAudition` is the base pair on purpose — the by-type lookup must be total
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/constants/options.ts"],"names":[],"mappings":"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","sourcesContent":["// UI option lists shared between frontend and backend admin tooling.\n\nimport type { HallWingType, WorkProjectType } from '../types/content.js';\nimport type { AuditionType } from '../types/commissions.js';\n\n// --- WorkProject Guild Standings ---\n// WorkProject guild-standing IDs, labels, and assignment policy live in ../permissions/.\n// Keep guild-standing picker UIs backed by GUILD_STANDINGS instead of a duplicated option map.\n\n// --- Trade & Craft Options ---\n\n/**\n * Trade professions (20) — role-shaped labels used for guild roles, commission\n * requests, and file-folder permission keys. Display strings are stored/validated\n * directly (they double as the enum values in the callable input schemas that derive\n * from this constant). Kept in curated order; not alphabetized.\n */\nexport const TRADE_PROFESSION_OPTIONS = [\n // Performance\n 'Actor',\n 'Voice Actor',\n 'Singer',\n 'Musician',\n 'Dancer & Choreographer',\n // Story\n 'Writer',\n 'Editor',\n 'Director',\n 'Producer',\n // Camera & visual\n 'Cinematographer',\n 'Photographer',\n 'Animator',\n 'Artist',\n 'Graphic Designer',\n 'VFX Artist',\n 'Costume & Makeup Artist',\n 'Set & Prop Designer',\n // Audio\n 'Composer',\n 'Music Producer',\n 'Sound Designer',\n] as const;\n\n/**\n * Craft-skill discipline tags (23). Tags are Firestore doc IDs in the\n * `craftSkillsByTag/{tag}` index, so the STORED value is a machine-safe kebab-case ID\n * (`CRAFT_SKILL_TAG_OPTIONS`) — this is what the wire schema validates and what path\n * builders write. Human-readable labels (with spaces / ampersands) are mapped over the\n * IDs via `CRAFT_SKILL_TAG_LABELS`; render pickers/badges through that map. Kept in\n * curated discipline order (Performance → Writing → Visual → Film → Audio); not sorted.\n */\nexport const CRAFT_SKILL_TAG_OPTIONS = [\n // Performance\n 'acting',\n 'voice-over',\n 'singing',\n 'rapping',\n 'instrumental-performance',\n 'dance-choreography',\n 'stand-up-sketch-comedy',\n // Writing\n 'writing-storytelling',\n 'songwriting',\n 'poetry-spoken-word',\n // Visual arts\n 'drawing-illustration',\n 'painting',\n 'animation',\n 'graphic-design',\n 'photography',\n // Film & video\n 'cinematography-camera',\n 'video-editing',\n 'visual-effects',\n 'directing',\n 'costume-makeup',\n 'set-prop-design',\n // Audio\n 'music-production',\n 'composing-scoring',\n 'sound-design',\n] as const;\n\n/** The canonical tag-ID type — every tags field/param derives from this, never `string`. */\nexport type CraftSkillTagId = (typeof CRAFT_SKILL_TAG_OPTIONS)[number];\n\n/** The canonical trade-profession ID type. */\nexport type TradeProfessionId = (typeof TRADE_PROFESSION_OPTIONS)[number];\n\n/** TRADE_PROFESSION_OPTIONS as a non-empty tuple for `z.enum(...)` consumers — the ONE\n * cast, here beside the declaration (never re-cast locally in schema files). */\nexport const TRADE_PROFESSION_VALUES = TRADE_PROFESSION_OPTIONS as unknown as [\n TradeProfessionId,\n ...TradeProfessionId[],\n];\n\n/** The same allowlist as a non-empty tuple for `z.enum(...)` consumers — the ONE cast,\n * here beside the declaration (schema files import this, never re-cast locally). */\nexport const CRAFT_SKILL_TAG_VALUES = CRAFT_SKILL_TAG_OPTIONS as unknown as [\n CraftSkillTagId,\n ...CraftSkillTagId[],\n];\n\n/** Human display labels for each craft-skill tag ID. Keyed by the machine-safe ID. */\nexport const CRAFT_SKILL_TAG_LABELS: Record<(typeof CRAFT_SKILL_TAG_OPTIONS)[number], string> = {\n 'acting': 'Acting',\n 'voice-over': 'Voice Over',\n 'singing': 'Singing',\n 'rapping': 'Rapping',\n 'instrumental-performance': 'Instrumental Performance',\n 'dance-choreography': 'Dance & Choreography',\n 'stand-up-sketch-comedy': 'Stand-Up & Sketch Comedy',\n 'writing-storytelling': 'Writing & Storytelling',\n 'songwriting': 'Songwriting',\n 'poetry-spoken-word': 'Poetry & Spoken Word',\n 'drawing-illustration': 'Drawing & Illustration',\n 'painting': 'Painting',\n 'animation': 'Animation',\n 'graphic-design': 'Graphic Design',\n 'photography': 'Photography',\n 'cinematography-camera': 'Cinematography & Camera',\n 'video-editing': 'Video Editing',\n 'visual-effects': 'Visual Effects',\n 'directing': 'Directing',\n 'costume-makeup': 'Costume & Makeup',\n 'set-prop-design': 'Set & Prop Design',\n 'music-production': 'Music Production',\n 'composing-scoring': 'Composing & Scoring',\n 'sound-design': 'Sound Design',\n};\n\n// --- WorkProject-Specific Genres ---\n\n/**\n * Genres shown for each workProject type. Curated final lists (kept in the doc's order,\n * not alphabetized). \"Spooky\" (not \"Horror\") is deliberate for V1: the name carries the\n * all-ages ceiling; \"Horror\" is the natural mature sibling if mature content ever ships.\n */\nexport const WORK_PROJECT_SPECIFIC_GENRES = {\n Tales: [\n 'Adventure',\n 'Comedy',\n 'Drama',\n 'Fantasy',\n 'Fairy Tale & Fable',\n 'Historical',\n 'Mystery',\n 'Romance',\n 'Sci-Fi',\n 'Slice of Life',\n 'Spooky',\n 'Thriller',\n ],\n Tunes: [\n 'Audiobook & Spoken Word',\n 'Blues',\n 'Classical',\n 'Country',\n 'Electronic',\n 'Folk',\n 'Hip Hop & Rap',\n 'Jazz',\n 'Metal',\n 'Podcast',\n 'Pop',\n 'R&B & Soul',\n 'Reggae',\n 'Rock',\n 'Soundtrack & Score',\n ],\n Television: [\n 'Action',\n 'Animation',\n 'Comedy',\n 'Documentary',\n 'Drama',\n 'Fantasy',\n 'Kids & Family',\n 'Music Video',\n 'Mystery',\n 'Reality',\n 'Sci-Fi',\n 'Sketch & Variety',\n 'Spooky',\n 'Talk Show',\n 'Thriller',\n ],\n} as const;\n\n// --- HallLibrary / WorkProject Type Display Maps ---\n\n/** HallLibrary type display info. Used in dropdowns and badges. */\nexport const HALL_WING_TYPES: Record<HallWingType, { label: string; description: string }> = {\n entertainment: {\n label: 'Entertainment',\n description: 'Fun and engaging content',\n },\n educational: {\n label: 'Educational',\n description: 'Learning materials and resources',\n },\n newsPolitical: {\n label: 'News/Political',\n description: 'Current events and political content',\n },\n};\n\n/** WorkProject type display info. Used in dropdowns and headers. */\nexport const WORK_PROJECT_TYPES: Record<WorkProjectType, { label: string; description: string }> = {\n Tales: {\n label: 'Tales',\n description: 'Stories and narratives',\n },\n Tunes: {\n label: 'Tunes',\n description: 'Music and audio content',\n },\n Television: {\n label: 'Television',\n description: 'Video and TV content',\n },\n};\n\n// --- Audition Type Display + Board Filter ---\n\n/** Audition type display info. Used on the audition board's type chips/filters and on\n * audition headers. Record-keyed by the canonical AuditionType union, so adding an\n * audition type fails the build here until its label + description exist. */\nexport const AUDITION_TYPES: Record<AuditionType, { label: string; description: string }> = {\n platformAudition: {\n label: 'Platform',\n description: 'Run by TTT admins to gather community feedback.',\n },\n sponsoredAudition: {\n label: 'Sponsored',\n description: 'Backed by funding — votes decide where the money goes.',\n },\n workAudition: {\n label: 'Work',\n description: \"Created by a Work's Guildmates seeking feedback.\",\n },\n};\n\n/** The audition board's \"every type\" filter sentinel — the ONE declaration (it was\n * previously hand-rolled app-locally). It doubles as the chip's own display label. */\nexport const AUDITION_TYPE_FILTER_ALL = 'All';\n\n/** Audition-board type-filter state: one canonical audition type, or the ALL sentinel.\n * Filter state derives this instead of being typed `string`. */\nexport type AuditionTypeFilter = AuditionType | typeof AUDITION_TYPE_FILTER_ALL;\n\n// --- Sort Options ---\n\n/**\n * The two sort options EVERY audition feed offers — declared ONCE and spread into each feed's\n * option set below (ENG-002). They used to be restated verbatim in all four feed entries, so\n * a label or field change had to be made four times to avoid drift.\n */\nconst AUDITION_SORT_OPTIONS_BASE = {\n newest: { label: 'Newest First', field: 'createdOn', direction: 'desc' },\n endingSoon: { label: 'Ending Soon', field: 'openTill', direction: 'asc' },\n} as const;\n\n/** Sort options shown on the audition feeds, keyed by feed type. `default` serves the board's\n * ALL filter; `platformAudition` is the base pair on purpose — the by-type lookup must be total\n * over AuditionType (see the `AUDITION_SORT_OPTIONS[filter]` call sites). */\nexport const AUDITION_SORT_OPTIONS = {\n default: { ...AUDITION_SORT_OPTIONS_BASE },\n platformAudition: { ...AUDITION_SORT_OPTIONS_BASE },\n sponsoredAudition: {\n ...AUDITION_SORT_OPTIONS_BASE,\n highestPrice: { label: 'Highest Price', field: 'sponsoredAuditionAmountUSD', direction: 'desc' },\n lowestPrice: { label: 'Lowest Price', field: 'sponsoredAuditionAmountUSD', direction: 'asc' },\n },\n workAudition: {\n ...AUDITION_SORT_OPTIONS_BASE,\n highestStakeShares: { label: 'Highest Stakes', field: 'stakeSharesOffered', direction: 'desc' },\n lowestStakeShares: { label: 'Lowest Stakes', field: 'stakeSharesOffered', direction: 'asc' },\n },\n} as const;\n\n/** Every sort key any audition feed offers, DERIVED from AUDITION_SORT_OPTIONS above — a new\n * sort option widens the union automatically, so sort state is never typed `string`. */\nexport type AuditionSortKey = {\n [F in keyof typeof AUDITION_SORT_OPTIONS]: keyof (typeof AUDITION_SORT_OPTIONS)[F];\n}[keyof typeof AUDITION_SORT_OPTIONS];\n\n/** The audition board's initial sort selection. Every feed type offers this key. */\nexport const DEFAULT_AUDITION_SORT: AuditionSortKey = 'newest';\n\n/** Sort options shown on the hallLibrary feed. */\nexport const HALL_LIBRARY_SORT_OPTIONS: Record<\n string,\n { label: string; field: string; direction: 'asc' | 'desc' }\n> = {\n newest: { label: 'Newest First', field: 'createdOn', direction: 'desc' },\n oldest: { label: 'Oldest First', field: 'createdOn', direction: 'asc' },\n most_followed: { label: 'Most Followed', field: 'followerCount', direction: 'desc' },\n};\n\n\n\n"]}
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/constants/options.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAKrE,sCAAsC;AACtC,yFAAyF;AACzF,+FAA+F;AAE/F,gCAAgC;AAEhC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,cAAc;IACd,OAAO;IACP,aAAa;IACb,QAAQ;IACR,UAAU;IACV,wBAAwB;IACxB,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,UAAU;IACV,kBAAkB;IAClB,iBAAiB;IACjB,cAAc;IACd,UAAU;IACV,QAAQ;IACR,kBAAkB;IAClB,YAAY;IACZ,yBAAyB;IACzB,qBAAqB;IACrB,QAAQ;IACR,UAAU;IACV,gBAAgB;IAChB,gBAAgB;CACR,CAAC;AAEX;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,cAAc;IACd,QAAQ;IACR,YAAY;IACZ,SAAS;IACT,SAAS;IACT,0BAA0B;IAC1B,oBAAoB;IACpB,wBAAwB;IACxB,UAAU;IACV,sBAAsB;IACtB,aAAa;IACb,oBAAoB;IACpB,cAAc;IACd,sBAAsB;IACtB,UAAU;IACV,WAAW;IACX,gBAAgB;IAChB,aAAa;IACb,eAAe;IACf,uBAAuB;IACvB,eAAe;IACf,gBAAgB;IAChB,WAAW;IACX,gBAAgB;IAChB,iBAAiB;IACjB,QAAQ;IACR,kBAAkB;IAClB,mBAAmB;IACnB,cAAc;CACN,CAAC;AAQX;gFACgF;AAChF,MAAM,CAAC,MAAM,uBAAuB,GAAG,wBAGtC,CAAC;AAEF;oFACoF;AACpF,MAAM,CAAC,MAAM,sBAAsB,GAAG,uBAGrC,CAAC;AAEF,sFAAsF;AACtF,MAAM,CAAC,MAAM,sBAAsB,GAA6D;IAC9F,QAAQ,EAAE,QAAQ;IAClB,YAAY,EAAE,YAAY;IAC1B,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,SAAS;IACpB,0BAA0B,EAAE,0BAA0B;IACtD,oBAAoB,EAAE,sBAAsB;IAC5C,wBAAwB,EAAE,0BAA0B;IACpD,sBAAsB,EAAE,wBAAwB;IAChD,aAAa,EAAE,aAAa;IAC5B,oBAAoB,EAAE,sBAAsB;IAC5C,sBAAsB,EAAE,wBAAwB;IAChD,UAAU,EAAE,UAAU;IACtB,WAAW,EAAE,WAAW;IACxB,gBAAgB,EAAE,gBAAgB;IAClC,aAAa,EAAE,aAAa;IAC5B,uBAAuB,EAAE,yBAAyB;IAClD,eAAe,EAAE,eAAe;IAChC,gBAAgB,EAAE,gBAAgB;IAClC,WAAW,EAAE,WAAW;IACxB,gBAAgB,EAAE,kBAAkB;IACpC,iBAAiB,EAAE,mBAAmB;IACtC,kBAAkB,EAAE,kBAAkB;IACtC,mBAAmB,EAAE,qBAAqB;IAC1C,cAAc,EAAE,cAAc;CAC/B,CAAC;AAEF,sCAAsC;AAEtC;;;;GAIG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG;IAC1C,KAAK,EAAE;QACL,WAAW;QACX,QAAQ;QACR,OAAO;QACP,SAAS;QACT,oBAAoB;QACpB,YAAY;QACZ,SAAS;QACT,SAAS;QACT,QAAQ;QACR,eAAe;QACf,QAAQ;QACR,UAAU;KACX;IACD,KAAK,EAAE;QACL,yBAAyB;QACzB,OAAO;QACP,WAAW;QACX,SAAS;QACT,YAAY;QACZ,MAAM;QACN,eAAe;QACf,MAAM;QACN,OAAO;QACP,SAAS;QACT,KAAK;QACL,YAAY;QACZ,QAAQ;QACR,MAAM;QACN,oBAAoB;KACrB;IACD,UAAU,EAAE;QACV,QAAQ;QACR,WAAW;QACX,QAAQ;QACR,aAAa;QACb,OAAO;QACP,SAAS;QACT,eAAe;QACf,aAAa;QACb,SAAS;QACT,SAAS;QACT,QAAQ;QACR,kBAAkB;QAClB,QAAQ;QACR,WAAW;QACX,UAAU;KACX;CACO,CAAC;AAEX,sDAAsD;AAEtD,mEAAmE;AACnE,MAAM,CAAC,MAAM,eAAe,GAAiE;IAC3F,aAAa,EAAE;QACb,KAAK,EAAE,eAAe;QACtB,WAAW,EAAE,0BAA0B;KACxC;IACD,WAAW,EAAE;QACX,KAAK,EAAE,aAAa;QACpB,WAAW,EAAE,kCAAkC;KAChD;IACD,aAAa,EAAE;QACb,KAAK,EAAE,gBAAgB;QACvB,WAAW,EAAE,sCAAsC;KACpD;CACF,CAAC;AAEF,oEAAoE;AACpE,MAAM,CAAC,MAAM,kBAAkB,GAAoE;IACjG,KAAK,EAAE;QACL,KAAK,EAAE,OAAO;QACd,WAAW,EAAE,wBAAwB;KACtC;IACD,KAAK,EAAE;QACL,KAAK,EAAE,OAAO;QACd,WAAW,EAAE,yBAAyB;KACvC;IACD,UAAU,EAAE;QACV,KAAK,EAAE,YAAY;QACnB,WAAW,EAAE,sBAAsB;KACpC;CACF,CAAC;AAEF,+CAA+C;AAE/C;;6EAE6E;AAC7E,MAAM,CAAC,MAAM,cAAc,GAAiE;IAC1F,gBAAgB,EAAE;QAChB,KAAK,EAAE,UAAU;QACjB,WAAW,EAAE,iDAAiD;KAC/D;IACD,iBAAiB,EAAE;QACjB,KAAK,EAAE,WAAW;QAClB,WAAW,EAAE,wDAAwD;KACtE;IACD,YAAY,EAAE;QACZ,KAAK,EAAE,MAAM;QACb,WAAW,EAAE,kDAAkD;KAChE;CACF,CAAC;AAEF;sFACsF;AACtF,MAAM,CAAC,MAAM,wBAAwB,GAAG,KAAK,CAAC;AAM9C,uBAAuB;AAEvB;;;;GAIG;AACH,MAAM,0BAA0B,GAAG;IACjC,MAAM,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE;IACxE,UAAU,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,KAAK,EAAE;CACxE,CAAC;AAEX;;6EAE6E;AAC7E,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,OAAO,EAAE,EAAE,GAAG,0BAA0B,EAAE;IAC1C,gBAAgB,EAAE,EAAE,GAAG,0BAA0B,EAAE;IACnD,iBAAiB,EAAE;QACjB,GAAG,0BAA0B;QAC7B,YAAY,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,4BAA4B,EAAE,SAAS,EAAE,MAAM,EAAE;QAChG,WAAW,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,4BAA4B,EAAE,SAAS,EAAE,KAAK,EAAE;KAC9F;IACD,YAAY,EAAE;QACZ,GAAG,0BAA0B;QAC7B,kBAAkB,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,EAAE;QAC/F,iBAAiB,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,KAAK,EAAE;KAC7F;CACO,CAAC;AAQX,oFAAoF;AACpF,MAAM,CAAC,MAAM,qBAAqB,GAAoB,QAAQ,CAAC;AAE/D,kDAAkD;AAClD,MAAM,CAAC,MAAM,yBAAyB,GAGlC;IACF,MAAM,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE;IACxE,MAAM,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,EAAE;IACvE,aAAa,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,EAAE;CACrF,CAAC","sourcesContent":["// UI option lists shared between frontend and backend admin tooling.\n\nimport type { HallWingType, WorkProjectType } from '../types/content.js';\nimport type { AuditionType } from '../types/commissions.js';\n\n// --- WorkProject Guild Standings ---\n// WorkProject guild-standing IDs, labels, and assignment policy live in ../permissions/.\n// Keep guild-standing picker UIs backed by GUILD_STANDINGS instead of a duplicated option map.\n\n// --- Trade & Craft Options ---\n\n/**\n * Trade professions (20) — role-shaped labels used for guild roles, commission\n * requests, and file-folder permission keys. Display strings are stored/validated\n * directly (they double as the enum values in the callable input schemas that derive\n * from this constant). Kept in curated order; not alphabetized.\n */\nexport const TRADE_PROFESSION_OPTIONS = [\n // Performance\n 'Actor',\n 'Voice Actor',\n 'Singer',\n 'Musician',\n 'Dancer & Choreographer',\n // Story\n 'Writer',\n 'Editor',\n 'Director',\n 'Producer',\n // Camera & visual\n 'Cinematographer',\n 'Photographer',\n 'Animator',\n 'Artist',\n 'Graphic Designer',\n 'VFX Artist',\n 'Costume & Makeup Artist',\n 'Set & Prop Designer',\n // Audio\n 'Composer',\n 'Music Producer',\n 'Sound Designer',\n] as const;\n\n/**\n * Craft-skill discipline tags (23). Tags are Firestore doc IDs in the\n * `craftSkillsByTag/{tag}` index, so the STORED value is a machine-safe kebab-case ID\n * (`CRAFT_SKILL_TAG_OPTIONS`) — this is what the wire schema validates and what path\n * builders write. Human-readable labels (with spaces / ampersands) are mapped over the\n * IDs via `CRAFT_SKILL_TAG_LABELS`; render pickers/badges through that map. Kept in\n * curated discipline order (Performance → Writing → Visual → Film → Audio); not sorted.\n */\nexport const CRAFT_SKILL_TAG_OPTIONS = [\n // Performance\n 'acting',\n 'voice-over',\n 'singing',\n 'rapping',\n 'instrumental-performance',\n 'dance-choreography',\n 'stand-up-sketch-comedy',\n // Writing\n 'writing-storytelling',\n 'songwriting',\n 'poetry-spoken-word',\n // Visual arts\n 'drawing-illustration',\n 'painting',\n 'animation',\n 'graphic-design',\n 'photography',\n // Film & video\n 'cinematography-camera',\n 'video-editing',\n 'visual-effects',\n 'directing',\n 'costume-makeup',\n 'set-prop-design',\n // Audio\n 'music-production',\n 'composing-scoring',\n 'sound-design',\n] as const;\n\n/** The canonical tag-ID type — every tags field/param derives from this, never `string`. */\nexport type CraftSkillTagId = (typeof CRAFT_SKILL_TAG_OPTIONS)[number];\n\n/** The canonical trade-profession ID type. */\nexport type TradeProfessionId = (typeof TRADE_PROFESSION_OPTIONS)[number];\n\n/** TRADE_PROFESSION_OPTIONS as a non-empty tuple for `z.enum(...)` consumers — the ONE\n * cast, here beside the declaration (never re-cast locally in schema files). */\nexport const TRADE_PROFESSION_VALUES = TRADE_PROFESSION_OPTIONS as unknown as [\n TradeProfessionId,\n ...TradeProfessionId[],\n];\n\n/** The same allowlist as a non-empty tuple for `z.enum(...)` consumers — the ONE cast,\n * here beside the declaration (schema files import this, never re-cast locally). */\nexport const CRAFT_SKILL_TAG_VALUES = CRAFT_SKILL_TAG_OPTIONS as unknown as [\n CraftSkillTagId,\n ...CraftSkillTagId[],\n];\n\n/** Human display labels for each craft-skill tag ID. Keyed by the machine-safe ID. */\nexport const CRAFT_SKILL_TAG_LABELS: Record<(typeof CRAFT_SKILL_TAG_OPTIONS)[number], string> = {\n 'acting': 'Acting',\n 'voice-over': 'Voice Over',\n 'singing': 'Singing',\n 'rapping': 'Rapping',\n 'instrumental-performance': 'Instrumental Performance',\n 'dance-choreography': 'Dance & Choreography',\n 'stand-up-sketch-comedy': 'Stand-Up & Sketch Comedy',\n 'writing-storytelling': 'Writing & Storytelling',\n 'songwriting': 'Songwriting',\n 'poetry-spoken-word': 'Poetry & Spoken Word',\n 'drawing-illustration': 'Drawing & Illustration',\n 'painting': 'Painting',\n 'animation': 'Animation',\n 'graphic-design': 'Graphic Design',\n 'photography': 'Photography',\n 'cinematography-camera': 'Cinematography & Camera',\n 'video-editing': 'Video Editing',\n 'visual-effects': 'Visual Effects',\n 'directing': 'Directing',\n 'costume-makeup': 'Costume & Makeup',\n 'set-prop-design': 'Set & Prop Design',\n 'music-production': 'Music Production',\n 'composing-scoring': 'Composing & Scoring',\n 'sound-design': 'Sound Design',\n};\n\n// --- WorkProject-Specific Genres ---\n\n/**\n * Genres shown for each workProject type. Curated final lists (kept in the doc's order,\n * not alphabetized). \"Spooky\" (not \"Horror\") is deliberate for V1: the name carries the\n * all-ages ceiling; \"Horror\" is the natural mature sibling if mature content ever ships.\n */\nexport const WORK_PROJECT_SPECIFIC_GENRES = {\n Tales: [\n 'Adventure',\n 'Comedy',\n 'Drama',\n 'Fantasy',\n 'Fairy Tale & Fable',\n 'Historical',\n 'Mystery',\n 'Romance',\n 'Sci-Fi',\n 'Slice of Life',\n 'Spooky',\n 'Thriller',\n ],\n Tunes: [\n 'Audiobook & Spoken Word',\n 'Blues',\n 'Classical',\n 'Country',\n 'Electronic',\n 'Folk',\n 'Hip Hop & Rap',\n 'Jazz',\n 'Metal',\n 'Podcast',\n 'Pop',\n 'R&B & Soul',\n 'Reggae',\n 'Rock',\n 'Soundtrack & Score',\n ],\n Television: [\n 'Action',\n 'Animation',\n 'Comedy',\n 'Documentary',\n 'Drama',\n 'Fantasy',\n 'Kids & Family',\n 'Music Video',\n 'Mystery',\n 'Reality',\n 'Sci-Fi',\n 'Sketch & Variety',\n 'Spooky',\n 'Talk Show',\n 'Thriller',\n ],\n} as const;\n\n// --- HallLibrary / WorkProject Type Display Maps ---\n\n/** HallLibrary type display info. Used in dropdowns and badges. */\nexport const HALL_WING_TYPES: Record<HallWingType, { label: string; description: string }> = {\n entertainment: {\n label: 'Entertainment',\n description: 'Fun and engaging content',\n },\n educational: {\n label: 'Educational',\n description: 'Learning materials and resources',\n },\n newsPolitical: {\n label: 'News/Political',\n description: 'Current events and political content',\n },\n};\n\n/** WorkProject type display info. Used in dropdowns and headers. */\nexport const WORK_PROJECT_TYPES: Record<WorkProjectType, { label: string; description: string }> = {\n Tales: {\n label: 'Tales',\n description: 'Stories and narratives',\n },\n Tunes: {\n label: 'Tunes',\n description: 'Music and audio content',\n },\n Television: {\n label: 'Television',\n description: 'Video and TV content',\n },\n};\n\n// --- Audition Type Display + Board Filter ---\n\n/** Audition type display info. Used on the audition board's type chips/filters and on\n * audition headers. Record-keyed by the canonical AuditionType union, so adding an\n * audition type fails the build here until its label + description exist. */\nexport const AUDITION_TYPES: Record<AuditionType, { label: string; description: string }> = {\n platformAudition: {\n label: 'Platform',\n description: 'Run by TTT admins to gather community feedback.',\n },\n sponsoredAudition: {\n label: 'Sponsored',\n description: 'Backed by funding — votes decide where the money goes.',\n },\n workAudition: {\n label: 'Work',\n description: \"Created by a Work's Guildmates seeking feedback.\",\n },\n};\n\n/** The audition board's \"every type\" filter sentinel — the ONE declaration (it was\n * previously hand-rolled app-locally). It doubles as the chip's own display label. */\nexport const AUDITION_TYPE_FILTER_ALL = 'All';\n\n/** Audition-board type-filter state: one canonical audition type, or the ALL sentinel.\n * Filter state derives this instead of being typed `string`. */\nexport type AuditionTypeFilter = AuditionType | typeof AUDITION_TYPE_FILTER_ALL;\n\n// --- Sort Options ---\n\n/**\n * The two sort options EVERY audition feed offers — declared ONCE and spread into each feed's\n * option set below (ENG-002). They used to be restated verbatim in all four feed entries, so\n * a label or field change had to be made four times to avoid drift.\n */\nconst AUDITION_SORT_OPTIONS_BASE = {\n newest: { label: 'Newest First', field: 'createdOn', direction: 'desc' },\n endingSoon: { label: 'Ending Soon', field: 'auditionCloseAt', direction: 'asc' },\n} as const;\n\n/** Sort options shown on the audition feeds, keyed by feed type. `default` serves the board's\n * ALL filter; `platformAudition` is the base pair on purpose — the by-type lookup must be total\n * over AuditionType (see the `AUDITION_SORT_OPTIONS[filter]` call sites). */\nexport const AUDITION_SORT_OPTIONS = {\n default: { ...AUDITION_SORT_OPTIONS_BASE },\n platformAudition: { ...AUDITION_SORT_OPTIONS_BASE },\n sponsoredAudition: {\n ...AUDITION_SORT_OPTIONS_BASE,\n highestPrice: { label: 'Highest Price', field: 'sponsoredAuditionAmountUSD', direction: 'desc' },\n lowestPrice: { label: 'Lowest Price', field: 'sponsoredAuditionAmountUSD', direction: 'asc' },\n },\n workAudition: {\n ...AUDITION_SORT_OPTIONS_BASE,\n highestStakeShares: { label: 'Highest Stakes', field: 'stakeSharesOffered', direction: 'desc' },\n lowestStakeShares: { label: 'Lowest Stakes', field: 'stakeSharesOffered', direction: 'asc' },\n },\n} as const;\n\n/** Every sort key any audition feed offers, DERIVED from AUDITION_SORT_OPTIONS above — a new\n * sort option widens the union automatically, so sort state is never typed `string`. */\nexport type AuditionSortKey = {\n [F in keyof typeof AUDITION_SORT_OPTIONS]: keyof (typeof AUDITION_SORT_OPTIONS)[F];\n}[keyof typeof AUDITION_SORT_OPTIONS];\n\n/** The audition board's initial sort selection. Every feed type offers this key. */\nexport const DEFAULT_AUDITION_SORT: AuditionSortKey = 'newest';\n\n/** Sort options shown on the hallLibrary feed. */\nexport const HALL_LIBRARY_SORT_OPTIONS: Record<\n string,\n { label: string; field: string; direction: 'asc' | 'desc' }\n> = {\n newest: { label: 'Newest First', field: 'createdOn', direction: 'desc' },\n oldest: { label: 'Oldest First', field: 'createdOn', direction: 'asc' },\n most_followed: { label: 'Most Followed', field: 'followerCount', direction: 'desc' },\n};\n\n\n\n"]}
|
|
@@ -15,6 +15,8 @@ export declare const ITEMS_PER_PAGE_FOLLOWED_USERS = 10;
|
|
|
15
15
|
export declare const ITEMS_PER_PAGE_ADMIN_DISPATCH_THREADS = 10;
|
|
16
16
|
/** The admin Dispatches browse list (every support thread, admin-only) — not a member's own thread list above. */
|
|
17
17
|
export declare const ITEMS_PER_PAGE_ADMIN_DISPATCH_BROWSE = 12;
|
|
18
|
+
/** The admin task browse list (every queue task of one type, admin-only). */
|
|
19
|
+
export declare const ITEMS_PER_PAGE_ADMIN_TASK_BROWSE = 12;
|
|
18
20
|
/** Page size for the pledge-payments list hook. */
|
|
19
21
|
export declare const PLEDGE_PAYMENTS_PER_PAGE = 20;
|
|
20
22
|
/** Page size for the pending-media archive list hook. */
|
|
@@ -51,4 +53,14 @@ export declare const HALL_LIBRARY_PAGE_CONSTANTS: {
|
|
|
51
53
|
readonly MAX_TAGS_PER_ITEM: 10;
|
|
52
54
|
readonly SEARCH_DEBOUNCE_MS: 300;
|
|
53
55
|
};
|
|
56
|
+
/**
|
|
57
|
+
* The notification tray's Safety Cases view shows how many safety cases are open, up to this
|
|
58
|
+
* many; above it the view says `${SAFETY_CASE_TRAY_COUNT_CAP}+`. The view only signals that there
|
|
59
|
+
* is work — the Safety Case Console holds the details — so it never counts past the cap.
|
|
60
|
+
*/
|
|
61
|
+
export declare const SAFETY_CASE_TRAY_COUNT_CAP = 100;
|
|
62
|
+
/** The tray's open-case read limit: one row past the cap, so a full cap is told apart from more. */
|
|
63
|
+
export declare const SAFETY_CASE_TRAY_READ_LIMIT: number;
|
|
64
|
+
/** The tray's open safety-case count as shown: exact up to the cap, `"100+"` above it. */
|
|
65
|
+
export declare function formatSafetyCaseTrayCount(loadedRows: number): string;
|
|
54
66
|
//# sourceMappingURL=pagination.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/constants/pagination.ts"],"names":[],"mappings":"AAGA,0DAA0D;AAC1D,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,sCAAsC,IAAI,CAAC;AACxD,eAAO,MAAM,+BAA+B,IAAI,CAAC;AACjD,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAChD,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAC/C,eAAO,MAAM,kCAAkC,IAAI,CAAC;AACpD,eAAO,MAAM,uCAAuC,IAAI,CAAC;AACzD,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAC5C,eAAO,MAAM,kCAAkC,IAAI,CAAC;AACpD,eAAO,MAAM,gCAAgC,IAAI,CAAC;AAClD,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAChD,eAAO,MAAM,qCAAqC,KAAK,CAAC;AACxD,kHAAkH;AAClH,eAAO,MAAM,oCAAoC,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/constants/pagination.ts"],"names":[],"mappings":"AAGA,0DAA0D;AAC1D,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,sCAAsC,IAAI,CAAC;AACxD,eAAO,MAAM,+BAA+B,IAAI,CAAC;AACjD,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAChD,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAC/C,eAAO,MAAM,kCAAkC,IAAI,CAAC;AACpD,eAAO,MAAM,uCAAuC,IAAI,CAAC;AACzD,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAC5C,eAAO,MAAM,kCAAkC,IAAI,CAAC;AACpD,eAAO,MAAM,gCAAgC,IAAI,CAAC;AAClD,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAChD,eAAO,MAAM,qCAAqC,KAAK,CAAC;AACxD,kHAAkH;AAClH,eAAO,MAAM,oCAAoC,KAAK,CAAC;AACvD,6EAA6E;AAC7E,eAAO,MAAM,gCAAgC,KAAK,CAAC;AAInD,mDAAmD;AACnD,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C,yDAAyD;AACzD,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC,wDAAwD;AACxD,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,0CAA0C;AAC1C,eAAO,MAAM,cAAc,KAAK,CAAC;AAEjC,qDAAqD;AACrD,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,gDAAgD;AAChD,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C,8GAA8G;AAC9G,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAEhD;;;;GAIG;AACH,eAAO,MAAM,qCAAqC,KAAK,CAAC;AAExD,4GAA4G;AAC5G,eAAO,MAAM,2BAA2B,QAAiD,CAAC;AAI1F,uGAAuG;AACvG,eAAO,MAAM,2BAA2B;;;;;CAK9B,CAAC;AAGX;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAE9C,oGAAoG;AACpG,eAAO,MAAM,2BAA2B,QAAiC,CAAC;AAE1E,0FAA0F;AAC1F,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEpE"}
|