@chuzi/shared 1.3.42 → 1.3.43

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.
@@ -511,6 +511,43 @@ interface StoryStyleResponse {
511
511
  has_style: boolean;
512
512
  style_context: AiGeneration["style_context"] | null;
513
513
  }
514
+ interface AiStoryScenePayload {
515
+ title: string;
516
+ text: string;
517
+ font_family: string;
518
+ text_color: string;
519
+ background_color: string;
520
+ scene_color: string | null;
521
+ }
522
+ interface AiStoryEstimateRequest {
523
+ answers: Record<string, string>;
524
+ }
525
+ interface AiStoryTokenEstimate {
526
+ input_tokens: number;
527
+ output_tokens: number;
528
+ credits_needed: number;
529
+ }
530
+ interface AiStoryEstimateResponse {
531
+ estimate: AiStoryTokenEstimate;
532
+ balance: CreditBalance;
533
+ can_afford: boolean;
534
+ }
535
+ interface AiStoryGenerateRequest {
536
+ answers: Record<string, string>;
537
+ }
538
+ interface AiStoryGenerationResult {
539
+ id: string;
540
+ title: string;
541
+ scenes: AiStoryScenePayload[];
542
+ input_tokens: number;
543
+ output_tokens: number;
544
+ credits_charged: number;
545
+ model_id: string;
546
+ }
547
+ interface AiStoryGenerateResponse {
548
+ generation: AiStoryGenerationResult;
549
+ balance: CreditBalance;
550
+ }
514
551
  interface MediaItem {
515
552
  id: string;
516
553
  user_id: string;
@@ -644,4 +681,4 @@ declare function computeSceneVisibility(sceneList: Pick<SceneListItem, "is_title
644
681
  endingSeen: boolean;
645
682
  }): SceneVisibility[];
646
683
 
647
- export { type AcceptGenerationRequest, type AcceptGenerationResponse, type AiGeneration, type AiGenerationShowResponse, type AiGenerationStatus, type BookmarkListItem, type BookmarkListResponse, type BookmarkResponse, type CatalogResponse, type ContentRating, type ContentRatingDefinition, type CreateSceneActionRequest, type CreateSceneRequest, type CreateStoryRequest, type CreditBalance, type CreditBalanceResponse, type CreditPack, type CreditPool, type EngagementResponse, type GenerateImageRequest, type GenerateImageResponse, type GrantCreditsRequest, type GrantCreditsResponse, type HistoryEntry, type LineType, type LocaleId, type MagicLinkRequest, type MagicLinkRequestResponse, type MagicLinkVerifyRequest, type MagicLinkVerifyResponse, type MediaItem, type MineResponse, type OidcExchangeRequest, type OidcExchangeResponse, type PaginatedLink, type PaginatedResponse, type PasswordLoginRequest, type PasswordLoginResponse, type PaymentMethod, type PlayUrlResponse, type PopularChoice, type PublicDirectorProfile, type PurchaseAmountRequest, type PurchaseCreditsRequest, type PurchaseCreditsResponse, type RealmConfigResponse, type RealmDefinition, type RealmId, type RegisterMediaRequest, type RegisterMediaResponse, type RejectGenerationRequest, type RejectGenerationResponse, type SaveBookmarkRequest, type SceneActionItem, type SceneActionPayload, type SceneChoice, type SceneListItem, type SceneMapEntry, type SceneMapResponse, type SceneNode, type SceneTextContent, type SceneVisibility, type SourceUrlResponse, type StateUpdate, type StorePaymentMethodRequest, type StoryListItem, type StoryPreview, type StoryProgress, type StoryStyleResponse, type TagListResponse, type TextLine, type TrackEngagementRequest, type TranscodeRequest, type TranscodeResponse, type TreeGraph, type TreeGraphEdge, type TreeGraphNode, type UpdateLocaleRequest, type UpdateLocaleResponse, type UpdateProfileRequest, type UpdateProfileResponse, type UpdateRealmRequest, type UpdateRealmResponse, type UpdateSceneActionRequest, type UpdateSceneRequest, type UpdateStoryRequest, type UploadCostResponse, type UploadUrlRequest, type UploadUrlResponse, type UserProfile, type UsernameAvailabilityResponse, type VisibilityCondition, type VisibilityRules, type WatchSnapshot, computeSceneVisibility };
684
+ export { type AcceptGenerationRequest, type AcceptGenerationResponse, type AiGeneration, type AiGenerationShowResponse, type AiGenerationStatus, type AiStoryEstimateRequest, type AiStoryEstimateResponse, type AiStoryGenerateRequest, type AiStoryGenerateResponse, type AiStoryGenerationResult, type AiStoryScenePayload, type AiStoryTokenEstimate, type BookmarkListItem, type BookmarkListResponse, type BookmarkResponse, type CatalogResponse, type ContentRating, type ContentRatingDefinition, type CreateSceneActionRequest, type CreateSceneRequest, type CreateStoryRequest, type CreditBalance, type CreditBalanceResponse, type CreditPack, type CreditPool, type EngagementResponse, type GenerateImageRequest, type GenerateImageResponse, type GrantCreditsRequest, type GrantCreditsResponse, type HistoryEntry, type LineType, type LocaleId, type MagicLinkRequest, type MagicLinkRequestResponse, type MagicLinkVerifyRequest, type MagicLinkVerifyResponse, type MediaItem, type MineResponse, type OidcExchangeRequest, type OidcExchangeResponse, type PaginatedLink, type PaginatedResponse, type PasswordLoginRequest, type PasswordLoginResponse, type PaymentMethod, type PlayUrlResponse, type PopularChoice, type PublicDirectorProfile, type PurchaseAmountRequest, type PurchaseCreditsRequest, type PurchaseCreditsResponse, type RealmConfigResponse, type RealmDefinition, type RealmId, type RegisterMediaRequest, type RegisterMediaResponse, type RejectGenerationRequest, type RejectGenerationResponse, type SaveBookmarkRequest, type SceneActionItem, type SceneActionPayload, type SceneChoice, type SceneListItem, type SceneMapEntry, type SceneMapResponse, type SceneNode, type SceneTextContent, type SceneVisibility, type SourceUrlResponse, type StateUpdate, type StorePaymentMethodRequest, type StoryListItem, type StoryPreview, type StoryProgress, type StoryStyleResponse, type TagListResponse, type TextLine, type TrackEngagementRequest, type TranscodeRequest, type TranscodeResponse, type TreeGraph, type TreeGraphEdge, type TreeGraphNode, type UpdateLocaleRequest, type UpdateLocaleResponse, type UpdateProfileRequest, type UpdateProfileResponse, type UpdateRealmRequest, type UpdateRealmResponse, type UpdateSceneActionRequest, type UpdateSceneRequest, type UpdateStoryRequest, type UploadCostResponse, type UploadUrlRequest, type UploadUrlResponse, type UserProfile, type UsernameAvailabilityResponse, type VisibilityCondition, type VisibilityRules, type WatchSnapshot, computeSceneVisibility };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/index.ts"],"names":[],"mappings":";AAyvBO,SAAS,sBAAA,CACd,WACA,IAAA,EACmB;AACnB,EAAA,IAAI,IAAA,CAAK,SAAA,IAAa,IAAA,CAAK,UAAA,EAAY;AACrC,IAAA,OAAO,SAAA,CAAU,IAAI,OAAO,EAAE,WAAW,IAAA,EAAM,MAAA,EAAQ,OAAM,CAAE,CAAA;AAAA,EACjE;AACA,EAAA,OAAO,SAAA,CAAU,GAAA,CAAI,CAAC,KAAA,MAAW;AAAA,IAC/B,WAAW,KAAA,CAAM,QAAA;AAAA,IACjB,MAAA,EAAQ,CAAC,KAAA,CAAM;AAAA,GACjB,CAAE,CAAA;AACJ","file":"index.js","sourcesContent":["// ── Auth ──\n\nexport interface MagicLinkRequest {\n email: string;\n username?: string;\n device_name?: string;\n}\n\nexport interface MagicLinkRequestResponse {\n message: string;\n}\n\nexport interface MagicLinkVerifyRequest {\n email: string;\n token: string;\n device_name?: string;\n}\n\nexport interface MagicLinkVerifyResponse {\n token?: string;\n user: UserProfile;\n}\n\nexport interface OidcExchangeRequest {\n code: string;\n code_verifier: string;\n redirect_uri: string;\n device_name?: string;\n}\n\nexport interface OidcExchangeResponse {\n token?: string;\n user: UserProfile;\n}\n\nexport interface PasswordLoginRequest {\n email: string;\n password: string;\n device_name?: string;\n}\n\nexport interface PasswordLoginResponse {\n token?: string;\n user: UserProfile;\n}\n\n// ── User ──\n\nexport interface UserProfile {\n id: string;\n name: string;\n username: string;\n email: string;\n realm: RealmId | null;\n needs_realm_choice: boolean;\n locale: LocaleId | null;\n avatar_url: string | null;\n is_admin: boolean;\n created_at: string;\n}\n\nexport interface UpdateRealmRequest {\n realm: RealmId;\n}\n\nexport interface UpdateRealmResponse {\n realm: RealmId;\n user: UserProfile;\n}\n\nexport interface UpdateProfileRequest {\n name?: string;\n username?: string;\n}\n\nexport interface UpdateProfileResponse {\n user: UserProfile;\n}\n\nexport interface UsernameAvailabilityResponse {\n username: string;\n available: boolean;\n suggestion?: string;\n}\n\nexport interface PublicDirectorProfile {\n id: string;\n name: string;\n avatar_url: string | null;\n realm: RealmId | null;\n stories_count: number;\n}\n\n// ── Credits & payments ──\n\nexport type CreditPool = \"watch\" | \"create\";\n\nexport interface CreditBalance {\n watch: number;\n create: number;\n}\n\nexport interface CreditPack {\n id: string;\n pool: CreditPool;\n name: string;\n credits: number;\n price_cents: number;\n price: string;\n}\n\nexport interface PaymentMethod {\n id: string;\n type: string;\n last_four: string;\n label: string | null;\n is_default: boolean;\n created_at: string;\n}\n\nexport interface CreditBalanceResponse {\n balance: CreditBalance;\n}\n\nexport interface UploadCostResponse {\n file_size_bytes: number;\n file_size_mb: number;\n base_size_mb: number;\n credits_needed: number;\n balance: CreditBalance;\n can_afford: boolean;\n}\n\nexport interface PurchaseCreditsRequest {\n pack_id: string;\n payment_method_id?: string;\n}\n\nexport interface PurchaseAmountRequest {\n pool: CreditPool;\n credits: number;\n payment_method_id?: string;\n}\n\nexport interface PurchaseCreditsResponse {\n message: string;\n transaction_id?: string;\n balance: CreditBalance;\n}\n\nexport interface StorePaymentMethodRequest {\n type?: string;\n last_four: string;\n label?: string;\n}\n\nexport interface GrantCreditsRequest {\n user_id: string;\n pool: CreditPool;\n amount: number;\n note?: string;\n}\n\nexport interface GrantCreditsResponse {\n message: string;\n balance: CreditBalance;\n}\n\n// ── Catalog ──\n\nexport interface StoryListItem {\n id: string;\n title: string;\n description: string | null;\n genre: string | null;\n content_rating: ContentRating | null;\n published: boolean;\n published_version: number;\n watch_starts_count: number;\n choice_clicks_count: number;\n scenes_count: number;\n choices_count: number;\n tags: string[];\n creator: {\n id: string;\n name: string;\n } | null;\n created_at: string;\n updated_at: string;\n}\n\nexport interface StoryPreview {\n source: \"trailer\" | \"title_scene\" | \"none\";\n title: string;\n preview_url: string | null;\n media_type: string | null;\n is_ready: boolean;\n}\n\nexport interface PopularChoice {\n label: string;\n click_count: number;\n}\n\nexport interface StoryProgress {\n last_scene_id: string | null;\n bookmark_code: string | null;\n playback_seconds: number;\n watched_version: number;\n last_watched_at: string | null;\n}\n\nexport interface CatalogResponse {\n data: StoryListItem[];\n meta: {\n previews: Record<string, StoryPreview>;\n popular_choices: Record<string, PopularChoice[]>;\n creator_avatars: Record<string, string>;\n coverboxes: Record<string, string | null>;\n progress: Record<string, StoryProgress>;\n };\n}\n\nexport interface MineResponse {\n stories: StoryListItem[];\n data?: StoryListItem[];\n progress?: Record<string, StoryProgress>;\n meta: {\n coverboxes: Record<string, string | null>;\n };\n}\n\n// ── Watch / Scene Map ──\n\nexport interface SceneChoice {\n id: string;\n label: string;\n choice_type: string;\n choice_icon: string | null;\n choice_icon_media_id: string | null;\n choice_icon_url: string | null;\n reveal_mode: string;\n start_time_seconds: number | null;\n pause_for_choice: boolean;\n end_time_seconds: number | null;\n target_scene_id: string;\n x: number;\n y: number;\n w: number;\n h: number;\n arrow_rotation: number;\n arrow_scale: number;\n fade_in_ms?: number | null;\n fade_out_ms?: number | null;\n duration_ms?: number | null;\n visibility_rules: VisibilityRules | null;\n state_updates: StateUpdate[];\n}\n\nexport interface VisibilityRules {\n mode: \"all\" | \"any\";\n conditions: VisibilityCondition[];\n}\n\nexport interface VisibilityCondition {\n variable?: string;\n key?: string;\n operator?: string;\n value?: string;\n}\n\nexport interface StateUpdate {\n variable?: string;\n key?: string;\n action?: string;\n value?: string;\n}\n\nexport interface SceneNode {\n type: string;\n properties?: Record<string, unknown>;\n children?: SceneNode[];\n}\n\nexport type SceneActionPayload = Record<string, unknown> | unknown[];\n\nexport interface SceneMapEntry {\n scene_id: string;\n scene_title: string;\n color: string | null;\n is_title: boolean;\n media_title: string | null;\n media_type: string | null;\n media_url: string | null;\n stream_status: string | null;\n choice_style: string;\n choice_overlay_mode: string;\n goto_scene_id: string | null;\n choices: SceneChoice[];\n nodes: SceneNode[];\n}\n\nexport interface TreeGraphNode {\n id: string;\n title: string;\n is_title: boolean;\n is_end: boolean;\n level: number;\n index: number;\n x: number;\n y: number;\n color: string | null;\n}\n\nexport interface TreeGraphEdge {\n id: string;\n source: string;\n target: string;\n type: \"choice\" | \"go_to_scene\";\n}\n\nexport interface TreeGraph {\n nodes: TreeGraphNode[];\n edges: TreeGraphEdge[];\n meta: {\n root_id: string | null;\n level_count: number;\n };\n}\n\nexport interface WatchSnapshot {\n scene_id: string | null;\n state: Record<string, string>;\n history: HistoryEntry[];\n path: string[];\n visited_scene_ids?: string[];\n playback_seconds: number;\n}\n\nexport interface HistoryEntry {\n choice_id: string;\n scene_id: string;\n target_scene_id: string | null;\n at: string | null;\n path_index: number | null;\n}\n\nexport interface SceneMapResponse {\n story: {\n id: string;\n title: string;\n description: string | null;\n genre: string | null;\n content_rating: ContentRating | null;\n published_version: number;\n watch_starts_count: number;\n choice_clicks_count: number;\n };\n start_scene_id: string;\n scene_map: Record<string, SceneMapEntry>;\n tree_graph: TreeGraph;\n initial_snapshot: WatchSnapshot;\n initial_bookmark_code: string | null;\n}\n\n// ── Engagement ──\n\nexport interface TrackEngagementRequest {\n event: \"play_start\" | \"choice_click\";\n choice_id?: string;\n}\n\nexport interface EngagementResponse {\n watch_starts_count: number;\n choice_clicks_count: number;\n}\n\n// ── Bookmarks ──\n\nexport interface SaveBookmarkRequest {\n snapshot: WatchSnapshot;\n}\n\nexport interface BookmarkResponse {\n code: string;\n snapshot: WatchSnapshot;\n}\n\nexport interface BookmarkListItem {\n code: string;\n snapshot: WatchSnapshot;\n updated_at: string;\n}\n\nexport interface BookmarkListResponse {\n bookmarks: BookmarkListItem[];\n}\n\n// ── Pagination ──\n\nexport interface PaginatedLink {\n url: string | null;\n label: string;\n active: boolean;\n}\n\nexport interface PaginatedResponse<T> {\n data: T[];\n current_page: number;\n first_page_url: string;\n from: number | null;\n last_page: number;\n last_page_url: string;\n links: PaginatedLink[];\n next_page_url: string | null;\n path: string;\n per_page: number;\n prev_page_url: string | null;\n to: number | null;\n total: number;\n}\n\n// ── Scenes ──\n\nexport type LineType = \"text\" | \"sound\" | \"image\";\n\nexport interface TextLine {\n id: string;\n type?: LineType;\n media_id?: string;\n html: string;\n appear_at_ms: number;\n fade_in_ms: number;\n fade_out_ms: number;\n duration_ms: number;\n position_x?: number;\n position_y?: number;\n width_pct?: number;\n height_pct?: number;\n persist?: boolean;\n}\n\nexport interface SceneTextContent {\n html: string;\n lines?: TextLine[];\n}\n\nexport interface SceneListItem {\n id: string;\n story_id: string;\n title: string;\n order: number;\n is_title: boolean;\n is_end: boolean;\n color: string | null;\n media_id: string | null;\n alt_media_id: string | null;\n media_mode: \"text\" | \"imagery\" | \"film\" | null;\n text_content: SceneTextContent | null;\n text_style: {\n font_family?: string | null;\n text_color?: string | null;\n background_color?: string | null;\n } | null;\n goto_scene_id?: string | null;\n choice_end_time_seconds?: number | null;\n created_at: string;\n updated_at: string;\n}\n\nexport interface UpdateSceneRequest {\n title?: string;\n order?: number;\n media_id?: string | null;\n alt_media_id?: string | null;\n media_mode?: \"text\" | \"imagery\" | \"film\" | null;\n text_content?: SceneTextContent | null;\n text_style?: {\n font_family?: string | null;\n text_color?: string | null;\n background_color?: string | null;\n } | null;\n color?: string | null;\n is_title?: boolean;\n is_end?: boolean;\n goto_scene_id?: string | null;\n choice_style?: string | null;\n choice_overlay_mode?: string | null;\n choice_reveal_mode?: string | null;\n choice_start_time_seconds?: number | null;\n choice_pause_for_choice?: boolean;\n choice_end_time_seconds?: number | null;\n}\n\nexport interface CreateSceneRequest {\n story_id: string;\n title: string;\n order?: number;\n is_title?: boolean;\n is_end?: boolean;\n}\n\nexport interface SceneActionItem {\n id: string;\n scene_id: string;\n name: string;\n type: string | null;\n scene_choice_id: string | null;\n order: number;\n duration: number;\n properties: SceneActionPayload | null;\n subproperties: SceneActionPayload | null;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface CreateSceneActionRequest {\n scene_id: string;\n name: string;\n type?: string | null;\n order?: number;\n duration?: number;\n properties?: SceneActionPayload | null;\n subproperties?: SceneActionPayload | null;\n}\n\nexport interface UpdateSceneActionRequest {\n name?: string;\n type?: string | null;\n order?: number;\n duration?: number;\n properties?: SceneActionPayload;\n subproperties?: SceneActionPayload;\n}\n\n// ── AI Generation ──\n\nexport type AiGenerationStatus =\n | \"pending\"\n | \"generating\"\n | \"ready\"\n | \"failed\"\n | \"accepted\"\n | \"rejected\";\n\nexport interface GenerateImageRequest {\n story_id: string;\n scene_id?: string;\n prompt: string;\n mood?: string;\n visual_style?: string;\n rejection_feedback?: string;\n previous_generation_id?: string;\n}\n\nexport interface AiGeneration {\n id: string;\n story_id: string;\n scene_id: string | null;\n status: AiGenerationStatus;\n user_prompt: string;\n style_context: {\n mood?: string;\n visual_style?: string;\n subject_prompt: string;\n full_prompt: string;\n negative_prompt?: string;\n };\n preview_url?: string;\n rejection_feedback: string | null;\n media_id: string | null;\n attempt_number: number;\n credits_charged: number;\n created_at: string;\n updated_at: string;\n}\n\nexport interface GenerateImageResponse {\n generation: AiGeneration;\n balance: { watch: number; create: number };\n}\n\nexport interface AiGenerationShowResponse {\n generation: AiGeneration;\n}\n\nexport interface AcceptGenerationRequest {\n scene_id: string;\n}\n\nexport interface AcceptGenerationResponse {\n generation: AiGeneration;\n scene: SceneListItem;\n media: MediaItem;\n}\n\nexport interface RejectGenerationRequest {\n feedback: string;\n}\n\nexport interface RejectGenerationResponse {\n generation: AiGeneration;\n}\n\nexport interface StoryStyleResponse {\n has_style: boolean;\n style_context: AiGeneration[\"style_context\"] | null;\n}\n\n// ── Media ──\n\nexport interface MediaItem {\n id: string;\n user_id: string;\n s3_key: string;\n source_path: string;\n output_prefix: string | null;\n status: \"uploaded\" | \"processing\" | \"ready\" | \"error\";\n meta: Record<string, unknown>;\n order: number;\n created_at: string;\n updated_at: string;\n}\n\nexport interface UploadUrlRequest {\n filename: string;\n contentType: string;\n}\n\nexport interface UploadUrlResponse {\n key: string;\n uploadUrl: string;\n}\n\nexport interface RegisterMediaRequest {\n key: string;\n s3_key: string;\n filename: string;\n content_type?: string;\n title?: string;\n file_size?: number;\n}\n\nexport interface RegisterMediaResponse extends MediaItem {\n credits_charged: number;\n balance: number;\n}\n\nexport interface TranscodeRequest {\n media_id: string;\n}\n\nexport interface TranscodeResponse {\n message: string;\n job_id: string | null;\n manifest_path?: string;\n}\n\nexport interface PlayUrlResponse {\n play_url: string;\n status: string;\n}\n\nexport interface SourceUrlResponse {\n url: string;\n}\n\n// ── Story authoring ──\n\nexport interface CreateStoryRequest {\n title: string;\n description?: string | null;\n genre?: string | null;\n content_rating?: ContentRating | null;\n}\n\nexport interface UpdateStoryRequest {\n title?: string;\n description?: string | null;\n genre?: string | null;\n content_rating?: ContentRating | null;\n published?: boolean;\n tags?: string[];\n}\n\nexport interface TagListResponse {\n data: string[];\n}\n\n// ── Content Ratings ──\n\nexport type ContentRating = \"G\" | \"PG\" | \"PG-13\" | \"R\" | \"NC-17\";\n\nexport interface ContentRatingDefinition {\n id: ContentRating;\n label: string;\n description: string;\n}\n\n// ── Realm Config ──\n\nexport type RealmId = \"cosmos\" | \"wilds\";\n\n/** Supported UI locales — matches PHP `chuzi_realms.supported_locales`. */\nexport type LocaleId = \"en\" | \"es\" | \"fr\" | \"de\" | \"pt\";\n\nexport interface RealmDefinition {\n label: string;\n short_label: string;\n /** Canonical English lexicon (always present). */\n lexicon: Record<string, string>;\n /** Optional per-locale overrides; missing keys fall through to `lexicon`. */\n locales?: Partial<Record<LocaleId, Record<string, string>>>;\n}\n\nexport interface RealmConfigResponse {\n realms: Record<RealmId, RealmDefinition>;\n fallback_lexicon: Record<string, string>;\n fallback_locales?: Partial<Record<LocaleId, Record<string, string>>>;\n intro: {\n line1: string;\n line2: string;\n };\n intro_locales?: Partial<Record<LocaleId, { line1: string; line2: string }>>;\n profile: {\n title: string;\n current_prefix: string;\n switch_prompt: string;\n };\n profile_locales?: Partial<Record<LocaleId, { title: string; current_prefix: string; switch_prompt: string }>>;\n allowed_realm_ids: RealmId[];\n supported_locales: LocaleId[];\n locale_labels?: Partial<Record<LocaleId, string>>;\n}\n\nexport interface UpdateLocaleRequest {\n locale: LocaleId;\n}\n\nexport interface UpdateLocaleResponse {\n locale: LocaleId;\n}\n\n// ── Scene Visibility ──\n\nexport interface SceneVisibility {\n /** Whether the user can navigate to this scene-star. */\n navigable: boolean;\n /** Whether the star/edge should render at reduced opacity. */\n dimmed: boolean;\n}\n\n/**\n * Compute per-scene navigable/dimmed flags for a constellation.\n *\n * Rules:\n * - If `isCreator` is true, everything is navigable and bright.\n * - Title scenes are always navigable and bright.\n * - If the user has watched the ending (`endingSeen`), all scenes unlock.\n * - Otherwise non-title scenes are locked and dimmed.\n */\nexport function computeSceneVisibility(\n sceneList: Pick<SceneListItem, \"is_title\" | \"is_end\">[],\n opts: { isCreator: boolean; endingSeen: boolean },\n): SceneVisibility[] {\n if (opts.isCreator || opts.endingSeen) {\n return sceneList.map(() => ({ navigable: true, dimmed: false }));\n }\n return sceneList.map((scene) => ({\n navigable: scene.is_title,\n dimmed: !scene.is_title,\n }));\n}\n"]}
1
+ {"version":3,"sources":["../../src/types/index.ts"],"names":[],"mappings":";AAuyBO,SAAS,sBAAA,CACd,WACA,IAAA,EACmB;AACnB,EAAA,IAAI,IAAA,CAAK,SAAA,IAAa,IAAA,CAAK,UAAA,EAAY;AACrC,IAAA,OAAO,SAAA,CAAU,IAAI,OAAO,EAAE,WAAW,IAAA,EAAM,MAAA,EAAQ,OAAM,CAAE,CAAA;AAAA,EACjE;AACA,EAAA,OAAO,SAAA,CAAU,GAAA,CAAI,CAAC,KAAA,MAAW;AAAA,IAC/B,WAAW,KAAA,CAAM,QAAA;AAAA,IACjB,MAAA,EAAQ,CAAC,KAAA,CAAM;AAAA,GACjB,CAAE,CAAA;AACJ","file":"index.js","sourcesContent":["// ── Auth ──\n\nexport interface MagicLinkRequest {\n email: string;\n username?: string;\n device_name?: string;\n}\n\nexport interface MagicLinkRequestResponse {\n message: string;\n}\n\nexport interface MagicLinkVerifyRequest {\n email: string;\n token: string;\n device_name?: string;\n}\n\nexport interface MagicLinkVerifyResponse {\n token?: string;\n user: UserProfile;\n}\n\nexport interface OidcExchangeRequest {\n code: string;\n code_verifier: string;\n redirect_uri: string;\n device_name?: string;\n}\n\nexport interface OidcExchangeResponse {\n token?: string;\n user: UserProfile;\n}\n\nexport interface PasswordLoginRequest {\n email: string;\n password: string;\n device_name?: string;\n}\n\nexport interface PasswordLoginResponse {\n token?: string;\n user: UserProfile;\n}\n\n// ── User ──\n\nexport interface UserProfile {\n id: string;\n name: string;\n username: string;\n email: string;\n realm: RealmId | null;\n needs_realm_choice: boolean;\n locale: LocaleId | null;\n avatar_url: string | null;\n is_admin: boolean;\n created_at: string;\n}\n\nexport interface UpdateRealmRequest {\n realm: RealmId;\n}\n\nexport interface UpdateRealmResponse {\n realm: RealmId;\n user: UserProfile;\n}\n\nexport interface UpdateProfileRequest {\n name?: string;\n username?: string;\n}\n\nexport interface UpdateProfileResponse {\n user: UserProfile;\n}\n\nexport interface UsernameAvailabilityResponse {\n username: string;\n available: boolean;\n suggestion?: string;\n}\n\nexport interface PublicDirectorProfile {\n id: string;\n name: string;\n avatar_url: string | null;\n realm: RealmId | null;\n stories_count: number;\n}\n\n// ── Credits & payments ──\n\nexport type CreditPool = \"watch\" | \"create\";\n\nexport interface CreditBalance {\n watch: number;\n create: number;\n}\n\nexport interface CreditPack {\n id: string;\n pool: CreditPool;\n name: string;\n credits: number;\n price_cents: number;\n price: string;\n}\n\nexport interface PaymentMethod {\n id: string;\n type: string;\n last_four: string;\n label: string | null;\n is_default: boolean;\n created_at: string;\n}\n\nexport interface CreditBalanceResponse {\n balance: CreditBalance;\n}\n\nexport interface UploadCostResponse {\n file_size_bytes: number;\n file_size_mb: number;\n base_size_mb: number;\n credits_needed: number;\n balance: CreditBalance;\n can_afford: boolean;\n}\n\nexport interface PurchaseCreditsRequest {\n pack_id: string;\n payment_method_id?: string;\n}\n\nexport interface PurchaseAmountRequest {\n pool: CreditPool;\n credits: number;\n payment_method_id?: string;\n}\n\nexport interface PurchaseCreditsResponse {\n message: string;\n transaction_id?: string;\n balance: CreditBalance;\n}\n\nexport interface StorePaymentMethodRequest {\n type?: string;\n last_four: string;\n label?: string;\n}\n\nexport interface GrantCreditsRequest {\n user_id: string;\n pool: CreditPool;\n amount: number;\n note?: string;\n}\n\nexport interface GrantCreditsResponse {\n message: string;\n balance: CreditBalance;\n}\n\n// ── Catalog ──\n\nexport interface StoryListItem {\n id: string;\n title: string;\n description: string | null;\n genre: string | null;\n content_rating: ContentRating | null;\n published: boolean;\n published_version: number;\n watch_starts_count: number;\n choice_clicks_count: number;\n scenes_count: number;\n choices_count: number;\n tags: string[];\n creator: {\n id: string;\n name: string;\n } | null;\n created_at: string;\n updated_at: string;\n}\n\nexport interface StoryPreview {\n source: \"trailer\" | \"title_scene\" | \"none\";\n title: string;\n preview_url: string | null;\n media_type: string | null;\n is_ready: boolean;\n}\n\nexport interface PopularChoice {\n label: string;\n click_count: number;\n}\n\nexport interface StoryProgress {\n last_scene_id: string | null;\n bookmark_code: string | null;\n playback_seconds: number;\n watched_version: number;\n last_watched_at: string | null;\n}\n\nexport interface CatalogResponse {\n data: StoryListItem[];\n meta: {\n previews: Record<string, StoryPreview>;\n popular_choices: Record<string, PopularChoice[]>;\n creator_avatars: Record<string, string>;\n coverboxes: Record<string, string | null>;\n progress: Record<string, StoryProgress>;\n };\n}\n\nexport interface MineResponse {\n stories: StoryListItem[];\n data?: StoryListItem[];\n progress?: Record<string, StoryProgress>;\n meta: {\n coverboxes: Record<string, string | null>;\n };\n}\n\n// ── Watch / Scene Map ──\n\nexport interface SceneChoice {\n id: string;\n label: string;\n choice_type: string;\n choice_icon: string | null;\n choice_icon_media_id: string | null;\n choice_icon_url: string | null;\n reveal_mode: string;\n start_time_seconds: number | null;\n pause_for_choice: boolean;\n end_time_seconds: number | null;\n target_scene_id: string;\n x: number;\n y: number;\n w: number;\n h: number;\n arrow_rotation: number;\n arrow_scale: number;\n fade_in_ms?: number | null;\n fade_out_ms?: number | null;\n duration_ms?: number | null;\n visibility_rules: VisibilityRules | null;\n state_updates: StateUpdate[];\n}\n\nexport interface VisibilityRules {\n mode: \"all\" | \"any\";\n conditions: VisibilityCondition[];\n}\n\nexport interface VisibilityCondition {\n variable?: string;\n key?: string;\n operator?: string;\n value?: string;\n}\n\nexport interface StateUpdate {\n variable?: string;\n key?: string;\n action?: string;\n value?: string;\n}\n\nexport interface SceneNode {\n type: string;\n properties?: Record<string, unknown>;\n children?: SceneNode[];\n}\n\nexport type SceneActionPayload = Record<string, unknown> | unknown[];\n\nexport interface SceneMapEntry {\n scene_id: string;\n scene_title: string;\n color: string | null;\n is_title: boolean;\n media_title: string | null;\n media_type: string | null;\n media_url: string | null;\n stream_status: string | null;\n choice_style: string;\n choice_overlay_mode: string;\n goto_scene_id: string | null;\n choices: SceneChoice[];\n nodes: SceneNode[];\n}\n\nexport interface TreeGraphNode {\n id: string;\n title: string;\n is_title: boolean;\n is_end: boolean;\n level: number;\n index: number;\n x: number;\n y: number;\n color: string | null;\n}\n\nexport interface TreeGraphEdge {\n id: string;\n source: string;\n target: string;\n type: \"choice\" | \"go_to_scene\";\n}\n\nexport interface TreeGraph {\n nodes: TreeGraphNode[];\n edges: TreeGraphEdge[];\n meta: {\n root_id: string | null;\n level_count: number;\n };\n}\n\nexport interface WatchSnapshot {\n scene_id: string | null;\n state: Record<string, string>;\n history: HistoryEntry[];\n path: string[];\n visited_scene_ids?: string[];\n playback_seconds: number;\n}\n\nexport interface HistoryEntry {\n choice_id: string;\n scene_id: string;\n target_scene_id: string | null;\n at: string | null;\n path_index: number | null;\n}\n\nexport interface SceneMapResponse {\n story: {\n id: string;\n title: string;\n description: string | null;\n genre: string | null;\n content_rating: ContentRating | null;\n published_version: number;\n watch_starts_count: number;\n choice_clicks_count: number;\n };\n start_scene_id: string;\n scene_map: Record<string, SceneMapEntry>;\n tree_graph: TreeGraph;\n initial_snapshot: WatchSnapshot;\n initial_bookmark_code: string | null;\n}\n\n// ── Engagement ──\n\nexport interface TrackEngagementRequest {\n event: \"play_start\" | \"choice_click\";\n choice_id?: string;\n}\n\nexport interface EngagementResponse {\n watch_starts_count: number;\n choice_clicks_count: number;\n}\n\n// ── Bookmarks ──\n\nexport interface SaveBookmarkRequest {\n snapshot: WatchSnapshot;\n}\n\nexport interface BookmarkResponse {\n code: string;\n snapshot: WatchSnapshot;\n}\n\nexport interface BookmarkListItem {\n code: string;\n snapshot: WatchSnapshot;\n updated_at: string;\n}\n\nexport interface BookmarkListResponse {\n bookmarks: BookmarkListItem[];\n}\n\n// ── Pagination ──\n\nexport interface PaginatedLink {\n url: string | null;\n label: string;\n active: boolean;\n}\n\nexport interface PaginatedResponse<T> {\n data: T[];\n current_page: number;\n first_page_url: string;\n from: number | null;\n last_page: number;\n last_page_url: string;\n links: PaginatedLink[];\n next_page_url: string | null;\n path: string;\n per_page: number;\n prev_page_url: string | null;\n to: number | null;\n total: number;\n}\n\n// ── Scenes ──\n\nexport type LineType = \"text\" | \"sound\" | \"image\";\n\nexport interface TextLine {\n id: string;\n type?: LineType;\n media_id?: string;\n html: string;\n appear_at_ms: number;\n fade_in_ms: number;\n fade_out_ms: number;\n duration_ms: number;\n position_x?: number;\n position_y?: number;\n width_pct?: number;\n height_pct?: number;\n persist?: boolean;\n}\n\nexport interface SceneTextContent {\n html: string;\n lines?: TextLine[];\n}\n\nexport interface SceneListItem {\n id: string;\n story_id: string;\n title: string;\n order: number;\n is_title: boolean;\n is_end: boolean;\n color: string | null;\n media_id: string | null;\n alt_media_id: string | null;\n media_mode: \"text\" | \"imagery\" | \"film\" | null;\n text_content: SceneTextContent | null;\n text_style: {\n font_family?: string | null;\n text_color?: string | null;\n background_color?: string | null;\n } | null;\n goto_scene_id?: string | null;\n choice_end_time_seconds?: number | null;\n created_at: string;\n updated_at: string;\n}\n\nexport interface UpdateSceneRequest {\n title?: string;\n order?: number;\n media_id?: string | null;\n alt_media_id?: string | null;\n media_mode?: \"text\" | \"imagery\" | \"film\" | null;\n text_content?: SceneTextContent | null;\n text_style?: {\n font_family?: string | null;\n text_color?: string | null;\n background_color?: string | null;\n } | null;\n color?: string | null;\n is_title?: boolean;\n is_end?: boolean;\n goto_scene_id?: string | null;\n choice_style?: string | null;\n choice_overlay_mode?: string | null;\n choice_reveal_mode?: string | null;\n choice_start_time_seconds?: number | null;\n choice_pause_for_choice?: boolean;\n choice_end_time_seconds?: number | null;\n}\n\nexport interface CreateSceneRequest {\n story_id: string;\n title: string;\n order?: number;\n is_title?: boolean;\n is_end?: boolean;\n}\n\nexport interface SceneActionItem {\n id: string;\n scene_id: string;\n name: string;\n type: string | null;\n scene_choice_id: string | null;\n order: number;\n duration: number;\n properties: SceneActionPayload | null;\n subproperties: SceneActionPayload | null;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface CreateSceneActionRequest {\n scene_id: string;\n name: string;\n type?: string | null;\n order?: number;\n duration?: number;\n properties?: SceneActionPayload | null;\n subproperties?: SceneActionPayload | null;\n}\n\nexport interface UpdateSceneActionRequest {\n name?: string;\n type?: string | null;\n order?: number;\n duration?: number;\n properties?: SceneActionPayload;\n subproperties?: SceneActionPayload;\n}\n\n// ── AI Generation ──\n\nexport type AiGenerationStatus =\n | \"pending\"\n | \"generating\"\n | \"ready\"\n | \"failed\"\n | \"accepted\"\n | \"rejected\";\n\nexport interface GenerateImageRequest {\n story_id: string;\n scene_id?: string;\n prompt: string;\n mood?: string;\n visual_style?: string;\n rejection_feedback?: string;\n previous_generation_id?: string;\n}\n\nexport interface AiGeneration {\n id: string;\n story_id: string;\n scene_id: string | null;\n status: AiGenerationStatus;\n user_prompt: string;\n style_context: {\n mood?: string;\n visual_style?: string;\n subject_prompt: string;\n full_prompt: string;\n negative_prompt?: string;\n };\n preview_url?: string;\n rejection_feedback: string | null;\n media_id: string | null;\n attempt_number: number;\n credits_charged: number;\n created_at: string;\n updated_at: string;\n}\n\nexport interface GenerateImageResponse {\n generation: AiGeneration;\n balance: { watch: number; create: number };\n}\n\nexport interface AiGenerationShowResponse {\n generation: AiGeneration;\n}\n\nexport interface AcceptGenerationRequest {\n scene_id: string;\n}\n\nexport interface AcceptGenerationResponse {\n generation: AiGeneration;\n scene: SceneListItem;\n media: MediaItem;\n}\n\nexport interface RejectGenerationRequest {\n feedback: string;\n}\n\nexport interface RejectGenerationResponse {\n generation: AiGeneration;\n}\n\nexport interface StoryStyleResponse {\n has_style: boolean;\n style_context: AiGeneration[\"style_context\"] | null;\n}\n\n// ── Chuzi AI (Bedrock short-story generation) ──\n\nexport interface AiStoryScenePayload {\n title: string;\n text: string;\n font_family: string;\n text_color: string;\n background_color: string;\n scene_color: string | null;\n}\n\nexport interface AiStoryEstimateRequest {\n answers: Record<string, string>;\n}\n\nexport interface AiStoryTokenEstimate {\n input_tokens: number;\n output_tokens: number;\n credits_needed: number;\n}\n\nexport interface AiStoryEstimateResponse {\n estimate: AiStoryTokenEstimate;\n balance: CreditBalance;\n can_afford: boolean;\n}\n\nexport interface AiStoryGenerateRequest {\n answers: Record<string, string>;\n}\n\nexport interface AiStoryGenerationResult {\n id: string;\n title: string;\n scenes: AiStoryScenePayload[];\n input_tokens: number;\n output_tokens: number;\n credits_charged: number;\n model_id: string;\n}\n\nexport interface AiStoryGenerateResponse {\n generation: AiStoryGenerationResult;\n balance: CreditBalance;\n}\n\n// ── Media ──\n\nexport interface MediaItem {\n id: string;\n user_id: string;\n s3_key: string;\n source_path: string;\n output_prefix: string | null;\n status: \"uploaded\" | \"processing\" | \"ready\" | \"error\";\n meta: Record<string, unknown>;\n order: number;\n created_at: string;\n updated_at: string;\n}\n\nexport interface UploadUrlRequest {\n filename: string;\n contentType: string;\n}\n\nexport interface UploadUrlResponse {\n key: string;\n uploadUrl: string;\n}\n\nexport interface RegisterMediaRequest {\n key: string;\n s3_key: string;\n filename: string;\n content_type?: string;\n title?: string;\n file_size?: number;\n}\n\nexport interface RegisterMediaResponse extends MediaItem {\n credits_charged: number;\n balance: number;\n}\n\nexport interface TranscodeRequest {\n media_id: string;\n}\n\nexport interface TranscodeResponse {\n message: string;\n job_id: string | null;\n manifest_path?: string;\n}\n\nexport interface PlayUrlResponse {\n play_url: string;\n status: string;\n}\n\nexport interface SourceUrlResponse {\n url: string;\n}\n\n// ── Story authoring ──\n\nexport interface CreateStoryRequest {\n title: string;\n description?: string | null;\n genre?: string | null;\n content_rating?: ContentRating | null;\n}\n\nexport interface UpdateStoryRequest {\n title?: string;\n description?: string | null;\n genre?: string | null;\n content_rating?: ContentRating | null;\n published?: boolean;\n tags?: string[];\n}\n\nexport interface TagListResponse {\n data: string[];\n}\n\n// ── Content Ratings ──\n\nexport type ContentRating = \"G\" | \"PG\" | \"PG-13\" | \"R\" | \"NC-17\";\n\nexport interface ContentRatingDefinition {\n id: ContentRating;\n label: string;\n description: string;\n}\n\n// ── Realm Config ──\n\nexport type RealmId = \"cosmos\" | \"wilds\";\n\n/** Supported UI locales — matches PHP `chuzi_realms.supported_locales`. */\nexport type LocaleId = \"en\" | \"es\" | \"fr\" | \"de\" | \"pt\";\n\nexport interface RealmDefinition {\n label: string;\n short_label: string;\n /** Canonical English lexicon (always present). */\n lexicon: Record<string, string>;\n /** Optional per-locale overrides; missing keys fall through to `lexicon`. */\n locales?: Partial<Record<LocaleId, Record<string, string>>>;\n}\n\nexport interface RealmConfigResponse {\n realms: Record<RealmId, RealmDefinition>;\n fallback_lexicon: Record<string, string>;\n fallback_locales?: Partial<Record<LocaleId, Record<string, string>>>;\n intro: {\n line1: string;\n line2: string;\n };\n intro_locales?: Partial<Record<LocaleId, { line1: string; line2: string }>>;\n profile: {\n title: string;\n current_prefix: string;\n switch_prompt: string;\n };\n profile_locales?: Partial<Record<LocaleId, { title: string; current_prefix: string; switch_prompt: string }>>;\n allowed_realm_ids: RealmId[];\n supported_locales: LocaleId[];\n locale_labels?: Partial<Record<LocaleId, string>>;\n}\n\nexport interface UpdateLocaleRequest {\n locale: LocaleId;\n}\n\nexport interface UpdateLocaleResponse {\n locale: LocaleId;\n}\n\n// ── Scene Visibility ──\n\nexport interface SceneVisibility {\n /** Whether the user can navigate to this scene-star. */\n navigable: boolean;\n /** Whether the star/edge should render at reduced opacity. */\n dimmed: boolean;\n}\n\n/**\n * Compute per-scene navigable/dimmed flags for a constellation.\n *\n * Rules:\n * - If `isCreator` is true, everything is navigable and bright.\n * - Title scenes are always navigable and bright.\n * - If the user has watched the ending (`endingSeen`), all scenes unlock.\n * - Otherwise non-title scenes are locked and dimmed.\n */\nexport function computeSceneVisibility(\n sceneList: Pick<SceneListItem, \"is_title\" | \"is_end\">[],\n opts: { isCreator: boolean; endingSeen: boolean },\n): SceneVisibility[] {\n if (opts.isCreator || opts.endingSeen) {\n return sceneList.map(() => ({ navigable: true, dimmed: false }));\n }\n return sceneList.map((scene) => ({\n navigable: scene.is_title,\n dimmed: !scene.is_title,\n }));\n}\n"]}
package/dist/ui/index.js CHANGED
@@ -48,7 +48,7 @@ var REALMS = {
48
48
  select_genre: "Select galaxy",
49
49
  genre_field_aria: "Galaxy",
50
50
  delete_story_verb: "Delete star system",
51
- title_scene_default: "Title planet",
51
+ title_scene_default: "Launch",
52
52
  choices_made_stat: "trajectories taken",
53
53
  content_rating: "Audience Class",
54
54
  content_rating_field_aria: "Audience class",
@@ -61,10 +61,10 @@ var REALMS = {
61
61
  editor_alt_media: "Effects",
62
62
  editor_choices: "Choices",
63
63
  editor_scene_settings: "Star Settings",
64
- editor_title_scene: "Title Star",
64
+ editor_title_scene: "Start",
65
65
  editor_film_title: "Star System Title",
66
66
  editor_film_title_hint: "Click to rename this star system",
67
- editor_ending_scene: "Final Star",
67
+ editor_ending_scene: "End",
68
68
  editor_play: "Engage",
69
69
  editor_pause: "Hold",
70
70
  editor_prev_frame: "Previous Frame",
@@ -81,8 +81,61 @@ var REALMS = {
81
81
  editor_create_scene_cost: "1 Stardust",
82
82
  editor_delete_scene_cta: "Delete Scene",
83
83
  editor_delete_scene_confirm: "Click again to confirm",
84
- editor_scene_locked_delete: "Title and end scenes cannot be deleted.",
84
+ editor_scene_locked_delete: "Start and end scenes cannot be deleted.",
85
85
  editor_scene_color: "Star Hue",
86
+ chuzi_ai_name: "Chuzi AI",
87
+ chuzi_ai_create_with: "Create with Chuzi AI",
88
+ chuzi_ai_create_manual: "Enter title manually",
89
+ chuzi_ai_intro: "Answer story-circle prompts and Chuzi AI will chart your short story.",
90
+ chuzi_ai_step_of: "Step",
91
+ chuzi_ai_back: "Back",
92
+ chuzi_ai_next: "Next",
93
+ chuzi_ai_scenes_label: "scenes",
94
+ chuzi_ai_creating: "Creating\u2026",
95
+ chuzi_ai_generate_failed: "Story generation failed.",
96
+ chuzi_ai_build_failed: "Failed to build story.",
97
+ chuzi_ai_generate: "Generate story",
98
+ chuzi_ai_generating: "Generating\u2026",
99
+ chuzi_ai_token_in: "Tokens in",
100
+ chuzi_ai_token_out: "Tokens out",
101
+ chuzi_ai_credits_cost: "AI credits",
102
+ chuzi_ai_scene_credits: "Scene credits",
103
+ chuzi_ai_total_cost: "Total create credits",
104
+ chuzi_ai_insufficient: "Not enough create credits for this generation.",
105
+ chuzi_ai_apply: "Build story",
106
+ chuzi_ai_applying: "Building scenes\u2026",
107
+ chuzi_ai_step_hero: "Hero",
108
+ chuzi_ai_step_hero_hint: "Who is your protagonist? Name, age, personality, and what makes them relatable.",
109
+ chuzi_ai_step_world: "Ordinary world",
110
+ chuzi_ai_step_world_hint: "Where does the story begin? Describe the setting and daily life before adventure calls.",
111
+ chuzi_ai_step_you: "You",
112
+ chuzi_ai_step_you_hint: "The character in a zone of comfort. What is their normal life like right now?",
113
+ chuzi_ai_step_need: "Need",
114
+ chuzi_ai_step_need_hint: "Something isn\u2019t right. What problem, longing, or imbalance disrupts their comfort?",
115
+ chuzi_ai_step_go: "Go",
116
+ chuzi_ai_step_go_hint: "Crossing the threshold. What event pushes them into the unknown?",
117
+ chuzi_ai_step_search: "Search",
118
+ chuzi_ai_step_search_hint: "Trials, growth, and exploration. What challenges and discoveries shape them?",
119
+ chuzi_ai_step_find: "Find",
120
+ chuzi_ai_step_find_hint: "The thing is found or revealed. What truth, object, or insight do they uncover?",
121
+ chuzi_ai_step_take: "Take",
122
+ chuzi_ai_step_take_hint: "Pay the price. What must they sacrifice or confront to claim their goal?",
123
+ chuzi_ai_step_return: "Return",
124
+ chuzi_ai_step_return_hint: "Back to the known world. How do they bring what they learned home?",
125
+ chuzi_ai_step_change: "Change",
126
+ chuzi_ai_step_change_hint: "Transformation achieved. How is the hero different from who they were at the start?",
127
+ chuzi_ai_step_tone: "Tone & mood",
128
+ chuzi_ai_step_tone_hint: "Genre, mood, and atmosphere (e.g. bittersweet sci-fi, cozy mystery, epic fantasy).",
129
+ chuzi_ai_monomyth_hero: "Hero\u2019s Journey: the protagonist",
130
+ chuzi_ai_monomyth_world: "Monomyth: ordinary world",
131
+ chuzi_ai_monomyth_you: "Story Circle: zone of comfort",
132
+ chuzi_ai_monomyth_need: "Story Circle: something isn\u2019t right",
133
+ chuzi_ai_monomyth_go: "Monomyth: crossing the first threshold",
134
+ chuzi_ai_monomyth_search: "Monomyth: road of trials",
135
+ chuzi_ai_monomyth_find: "Monomyth: the ultimate boon",
136
+ chuzi_ai_monomyth_take: "Monomyth: atonement with the father",
137
+ chuzi_ai_monomyth_return: "Monomyth: crossing the return threshold",
138
+ chuzi_ai_monomyth_change: "Monomyth: freedom to live",
86
139
  editor_ai_generate: "Generate Transmission",
87
140
  editor_ai_generating: "Transmitting Signal\u2026",
88
141
  editor_ai_mood_question: "What energy should this planet radiate?",
@@ -380,7 +433,7 @@ var REALMS = {
380
433
  select_genre: "Select biome",
381
434
  genre_field_aria: "Biome",
382
435
  delete_story_verb: "Delete grove",
383
- title_scene_default: "Title clearing",
436
+ title_scene_default: "Trailhead",
384
437
  choices_made_stat: "trails taken",
385
438
  content_rating: "Field Guide",
386
439
  content_rating_field_aria: "Field guide",
@@ -393,10 +446,10 @@ var REALMS = {
393
446
  editor_alt_media: "Effects",
394
447
  editor_choices: "Choices",
395
448
  editor_scene_settings: "Clearing Settings",
396
- editor_title_scene: "Title Clearing",
449
+ editor_title_scene: "Start",
397
450
  editor_film_title: "Grove Title",
398
451
  editor_film_title_hint: "Click to rename this grove",
399
- editor_ending_scene: "Roots",
452
+ editor_ending_scene: "End",
400
453
  editor_play: "Unfurl",
401
454
  editor_pause: "Rest",
402
455
  editor_prev_frame: "Previous Frame",
@@ -413,8 +466,61 @@ var REALMS = {
413
466
  editor_create_scene_cost: "1 Pollen",
414
467
  editor_delete_scene_cta: "Delete Scene",
415
468
  editor_delete_scene_confirm: "Click again to confirm",
416
- editor_scene_locked_delete: "Title and end scenes cannot be deleted.",
469
+ editor_scene_locked_delete: "Start and end scenes cannot be deleted.",
417
470
  editor_scene_color: "Clearing Tint",
471
+ chuzi_ai_name: "Chuzi AI",
472
+ chuzi_ai_create_with: "Create with Chuzi AI",
473
+ chuzi_ai_create_manual: "Enter title manually",
474
+ chuzi_ai_intro: "Answer story-circle prompts and Chuzi AI will grow your short story.",
475
+ chuzi_ai_step_of: "Step",
476
+ chuzi_ai_back: "Back",
477
+ chuzi_ai_next: "Next",
478
+ chuzi_ai_scenes_label: "scenes",
479
+ chuzi_ai_creating: "Creating\u2026",
480
+ chuzi_ai_generate_failed: "Story generation failed.",
481
+ chuzi_ai_build_failed: "Failed to build story.",
482
+ chuzi_ai_generate: "Generate story",
483
+ chuzi_ai_generating: "Generating\u2026",
484
+ chuzi_ai_token_in: "Tokens in",
485
+ chuzi_ai_token_out: "Tokens out",
486
+ chuzi_ai_credits_cost: "AI credits",
487
+ chuzi_ai_scene_credits: "Scene credits",
488
+ chuzi_ai_total_cost: "Total create credits",
489
+ chuzi_ai_insufficient: "Not enough create credits for this generation.",
490
+ chuzi_ai_apply: "Build story",
491
+ chuzi_ai_applying: "Building scenes\u2026",
492
+ chuzi_ai_step_hero: "Hero",
493
+ chuzi_ai_step_hero_hint: "Who is your protagonist? Name, age, personality, and what makes them relatable.",
494
+ chuzi_ai_step_world: "Ordinary world",
495
+ chuzi_ai_step_world_hint: "Where does the story begin? Describe the setting and daily life before adventure calls.",
496
+ chuzi_ai_step_you: "You",
497
+ chuzi_ai_step_you_hint: "The character in a zone of comfort. What is their normal life like right now?",
498
+ chuzi_ai_step_need: "Need",
499
+ chuzi_ai_step_need_hint: "Something isn\u2019t right. What problem, longing, or imbalance disrupts their comfort?",
500
+ chuzi_ai_step_go: "Go",
501
+ chuzi_ai_step_go_hint: "Crossing the threshold. What event pushes them into the unknown?",
502
+ chuzi_ai_step_search: "Search",
503
+ chuzi_ai_step_search_hint: "Trials, growth, and exploration. What challenges and discoveries shape them?",
504
+ chuzi_ai_step_find: "Find",
505
+ chuzi_ai_step_find_hint: "The thing is found or revealed. What truth, object, or insight do they uncover?",
506
+ chuzi_ai_step_take: "Take",
507
+ chuzi_ai_step_take_hint: "Pay the price. What must they sacrifice or confront to claim their goal?",
508
+ chuzi_ai_step_return: "Return",
509
+ chuzi_ai_step_return_hint: "Back to the known world. How do they bring what they learned home?",
510
+ chuzi_ai_step_change: "Change",
511
+ chuzi_ai_step_change_hint: "Transformation achieved. How is the hero different from who they were at the start?",
512
+ chuzi_ai_step_tone: "Tone & mood",
513
+ chuzi_ai_step_tone_hint: "Genre, mood, and atmosphere (e.g. bittersweet sci-fi, cozy mystery, epic fantasy).",
514
+ chuzi_ai_monomyth_hero: "Hero\u2019s Journey: the protagonist",
515
+ chuzi_ai_monomyth_world: "Monomyth: ordinary world",
516
+ chuzi_ai_monomyth_you: "Story Circle: zone of comfort",
517
+ chuzi_ai_monomyth_need: "Story Circle: something isn\u2019t right",
518
+ chuzi_ai_monomyth_go: "Monomyth: crossing the first threshold",
519
+ chuzi_ai_monomyth_search: "Monomyth: road of trials",
520
+ chuzi_ai_monomyth_find: "Monomyth: the ultimate boon",
521
+ chuzi_ai_monomyth_take: "Monomyth: atonement with the father",
522
+ chuzi_ai_monomyth_return: "Monomyth: crossing the return threshold",
523
+ chuzi_ai_monomyth_change: "Monomyth: freedom to live",
418
524
  editor_ai_generate: "Grow Bloom",
419
525
  editor_ai_generating: "Seed Sprouting\u2026",
420
526
  editor_ai_mood_question: "What feeling should this clearing evoke?",
@@ -710,7 +816,7 @@ var FALLBACK_LEXICON = {
710
816
  select_genre: "Select genre",
711
817
  genre_field_aria: "Film genre",
712
818
  delete_story_verb: "Delete film",
713
- title_scene_default: "Title Scene",
819
+ title_scene_default: "Start",
714
820
  choices_made_stat: "choices made",
715
821
  content_rating: "Rating",
716
822
  content_rating_field_aria: "Content rating",
@@ -723,10 +829,10 @@ var FALLBACK_LEXICON = {
723
829
  editor_alt_media: "Effects",
724
830
  editor_choices: "Choices",
725
831
  editor_scene_settings: "Scene Settings",
726
- editor_title_scene: "Title Scene",
832
+ editor_title_scene: "Start",
727
833
  editor_film_title: "Film Title",
728
834
  editor_film_title_hint: "Click to rename this film",
729
- editor_ending_scene: "Ending Scene",
835
+ editor_ending_scene: "End",
730
836
  editor_play: "Play",
731
837
  editor_pause: "Pause",
732
838
  editor_prev_frame: "Previous Frame",
@@ -743,8 +849,61 @@ var FALLBACK_LEXICON = {
743
849
  editor_create_scene_cost: "1 credit",
744
850
  editor_delete_scene_cta: "Delete Scene",
745
851
  editor_delete_scene_confirm: "Click again to confirm",
746
- editor_scene_locked_delete: "Title and end scenes cannot be deleted.",
852
+ editor_scene_locked_delete: "Start and end scenes cannot be deleted.",
747
853
  editor_scene_color: "Scene Color",
854
+ chuzi_ai_name: "Chuzi AI",
855
+ chuzi_ai_create_with: "Create with Chuzi AI",
856
+ chuzi_ai_create_manual: "Enter title manually",
857
+ chuzi_ai_intro: "Answer a few story-circle prompts and Chuzi AI will draft your short story.",
858
+ chuzi_ai_step_of: "Step",
859
+ chuzi_ai_back: "Back",
860
+ chuzi_ai_next: "Next",
861
+ chuzi_ai_scenes_label: "scenes",
862
+ chuzi_ai_creating: "Creating\u2026",
863
+ chuzi_ai_generate_failed: "Story generation failed.",
864
+ chuzi_ai_build_failed: "Failed to build story.",
865
+ chuzi_ai_generate: "Generate story",
866
+ chuzi_ai_generating: "Generating\u2026",
867
+ chuzi_ai_token_in: "Tokens in",
868
+ chuzi_ai_token_out: "Tokens out",
869
+ chuzi_ai_credits_cost: "AI credits",
870
+ chuzi_ai_scene_credits: "Scene credits",
871
+ chuzi_ai_total_cost: "Total create credits",
872
+ chuzi_ai_insufficient: "Not enough create credits for this generation.",
873
+ chuzi_ai_apply: "Build story",
874
+ chuzi_ai_applying: "Building scenes\u2026",
875
+ chuzi_ai_step_hero: "Hero",
876
+ chuzi_ai_step_hero_hint: "Who is your protagonist? Name, age, personality, and what makes them relatable.",
877
+ chuzi_ai_step_world: "Ordinary world",
878
+ chuzi_ai_step_world_hint: "Where does the story begin? Describe the setting and daily life before adventure calls.",
879
+ chuzi_ai_step_you: "You",
880
+ chuzi_ai_step_you_hint: "The character in a zone of comfort. What is their normal life like right now?",
881
+ chuzi_ai_step_need: "Need",
882
+ chuzi_ai_step_need_hint: "Something isn\u2019t right. What problem, longing, or imbalance disrupts their comfort?",
883
+ chuzi_ai_step_go: "Go",
884
+ chuzi_ai_step_go_hint: "Crossing the threshold. What event pushes them into the unknown?",
885
+ chuzi_ai_step_search: "Search",
886
+ chuzi_ai_step_search_hint: "Trials, growth, and exploration. What challenges and discoveries shape them?",
887
+ chuzi_ai_step_find: "Find",
888
+ chuzi_ai_step_find_hint: "The thing is found or revealed. What truth, object, or insight do they uncover?",
889
+ chuzi_ai_step_take: "Take",
890
+ chuzi_ai_step_take_hint: "Pay the price. What must they sacrifice or confront to claim their goal?",
891
+ chuzi_ai_step_return: "Return",
892
+ chuzi_ai_step_return_hint: "Back to the known world. How do they bring what they learned home?",
893
+ chuzi_ai_step_change: "Change",
894
+ chuzi_ai_step_change_hint: "Transformation achieved. How is the hero different from who they were at the start?",
895
+ chuzi_ai_step_tone: "Tone & mood",
896
+ chuzi_ai_step_tone_hint: "Genre, mood, and atmosphere (e.g. bittersweet sci-fi, cozy mystery, epic fantasy).",
897
+ chuzi_ai_monomyth_hero: "Hero\u2019s Journey: the protagonist",
898
+ chuzi_ai_monomyth_world: "Monomyth: ordinary world",
899
+ chuzi_ai_monomyth_you: "Story Circle: zone of comfort",
900
+ chuzi_ai_monomyth_need: "Story Circle: something isn\u2019t right",
901
+ chuzi_ai_monomyth_go: "Monomyth: crossing the first threshold",
902
+ chuzi_ai_monomyth_search: "Monomyth: road of trials",
903
+ chuzi_ai_monomyth_find: "Monomyth: the ultimate boon",
904
+ chuzi_ai_monomyth_take: "Monomyth: atonement with the father",
905
+ chuzi_ai_monomyth_return: "Monomyth: crossing the return threshold",
906
+ chuzi_ai_monomyth_change: "Monomyth: freedom to live",
748
907
  editor_ai_generate: "Generate with AI",
749
908
  editor_ai_generating: "Generating\u2026",
750
909
  editor_ai_mood_question: "What mood should this scene convey?",