Full Code of CameronFoxly/Ascii-Motion for AI

main 156cc9994c57 cached
653 files
45.2 MB
3.8M tokens
1941 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (15,972K chars total). Download the full file to get everything.
Repository: CameronFoxly/Ascii-Motion
Branch: main
Commit: 156cc9994c57
Files: 653
Total size: 45.2 MB

Directory structure:
gitextract_bzvznlar/

├── .gitignore
├── .gitmodules
├── CONTRIBUTING.md
├── COPILOT_INSTRUCTIONS.md
├── LICENSE-MIT
├── LICENSE-PREMIUM
├── README.md
├── api/
│   └── og.ts
├── components.json
├── dev-tools/
│   ├── README.md
│   ├── bubbletea-test-cli/
│   │   ├── README.md
│   │   ├── animations/
│   │   │   ├── ascii_motion_anim.go
│   │   │   ├── copilotspin/
│   │   │   │   └── copilot_spin.go
│   │   │   ├── effects/
│   │   │   │   └── ascii_motion_anim_effects.go
│   │   │   ├── effects2/
│   │   │   │   └── ascii_motion_anim_effects2.go
│   │   │   ├── effects3/
│   │   │   │   └── ascii_motion_anim_effects3.go
│   │   │   └── newtest/
│   │   │       └── ascii_motion_anim_new.go
│   │   ├── go.mod
│   │   ├── go.sum
│   │   └── main.go
│   ├── clipboard-test.js
│   ├── debug-video-export.js
│   ├── font-test.html
│   ├── gridColorTest.ts
│   ├── ink-test-cli/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── ascii-motion-cli-effects.tsx
│   │   │   ├── ascii-motion-cli_256.tsx
│   │   │   └── cli.tsx
│   │   └── tsconfig.json
│   ├── opentui-test-cli/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── ascii-motion-opentui-hex.tsx
│   │   │   ├── ascii-motion-tui-ansi2.tsx
│   │   │   ├── ascii-motion-tui-effects.tsx
│   │   │   ├── ascii-motion-tui-semantic.tsx
│   │   │   ├── ascii-motion-tui.tsx
│   │   │   ├── ascii-motion-tui2.tsx
│   │   │   ├── cli.tsx
│   │   │   ├── fish-animation-256.tsx
│   │   │   └── fish-animation.tsx
│   │   └── tsconfig.json
│   ├── react-export-test/
│   │   ├── README.md
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── App.tsx
│   │   │   ├── ascii-motion-animation-effects.tsx
│   │   │   ├── ascii-motion-animation-new.tsx
│   │   │   ├── ascii-motion-animation.tsx
│   │   │   ├── main.tsx
│   │   │   ├── shader-test-01.tsx
│   │   │   ├── shader-test-02.tsx
│   │   │   └── vite-env.d.ts
│   │   ├── tsconfig.json
│   │   └── vite.config.ts
│   ├── sample-json-export.json
│   ├── test-frame-timing.js
│   ├── test-ibm-vga-font.html
│   ├── test-json-html-export.js
│   ├── test-palette.json
│   ├── test-sf-mono.html
│   ├── test-video-export.js
│   └── test-video-loops.js
├── docs/
│   ├── ADDING_CUSTOM_FONTS.md
│   ├── ADDING_FEATURES_TO_PROJECT_SYSTEM.md
│   ├── ANIMATION_PLAYBACK_OPTIMIZATION.md
│   ├── ANIMATION_PLAYBACK_OPTIMIZATION_PLAN.md
│   ├── ANIMATION_SYSTEM_GUIDE.md
│   ├── ASCII_BOX_TOOL_IMPLEMENTATION_PLAN.md
│   ├── ASCII_TYPE_TOOL_IMPLEMENTATION_PLAN.md
│   ├── BEZIER_GRANULAR_UNDO_IMPLEMENTATION.md
│   ├── BEZIER_SHAPE_TOOL_IMPLEMENTATION_PLAN.md
│   ├── BRUSH_HOVER_PREVIEW_PLAN.md
│   ├── BRUSH_TOOL_USER_GUIDE.md
│   ├── BUBBLETEA_EXPORT_IMPLEMENTATION_PLAN.md
│   ├── BUILD_FIXES.md
│   ├── CANVAS_RENDERING_IMPROVEMENTS.md
│   ├── CANVAS_TEXT_RENDERING.md
│   ├── COEP_CONFIGURATION_GUIDE.md
│   ├── COEP_TROUBLESHOOTING_GUIDE.md
│   ├── COLOR_PALETTE_OVERHAUL_PLAN.md
│   ├── CROP_CANVAS_TO_SELECTION.md
│   ├── DIALOG_COMPONENT_AUDIT.md
│   ├── DIALOG_CONSISTENCY_UPDATE.md
│   ├── DIGITAL_RAIN_GENERATOR_IMPLEMENTATION.md
│   ├── DITHERING_ANALYSIS_AND_PLAN.md
│   ├── DITHERING_IMPLEMENTATION_SUMMARY.md
│   ├── DITHERING_QUICK_REFERENCE.md
│   ├── DRAGGABLE_PICKERS_IMPLEMENTATION.md
│   ├── DRAWING_GAP_FIX.md
│   ├── EFFECTS_DEVELOPER_GUIDE.md
│   ├── EFFECTS_IMPLEMENTATION_SUMMARY.md
│   ├── EFFECTS_SYSTEM_IMPLEMENTATION.md
│   ├── EFFECTS_SYSTEM_USER_GUIDE.md
│   ├── ELLIPSE_RADIAL_GRADIENTS.md
│   ├── EXPORT_METADATA_AUDIT_COMPLETE.md
│   ├── FIGMA_COMPONENT_RECREATION_GUIDE.md
│   ├── FIGMA_DESIGN_SYSTEM_SETUP.md
│   ├── FIGMA_MCP_WORKFLOW_GUIDE.md
│   ├── FIGMA_REACT_DIALOG_REDESIGN_MASTER_GUIDE.md
│   ├── FIGMA_WORKFLOW_IMPLEMENTATION_SUMMARY.md
│   ├── FIGMA_WORKFLOW_README.md
│   ├── FONT_QUICK_REFERENCE.md
│   ├── FONT_SELECTION_IMPLEMENTATION_PLAN.md
│   ├── FONT_SYSTEM_IMPLEMENTATION_PLAN.md
│   ├── FRAME_SYNCHRONIZATION_DEBUGGING_GUIDE.md
│   ├── GENERATORS_IMPLEMENTATION_PLAN.md
│   ├── GENERATOR_CANVAS_PREVIEW_OPTIMIZATION.md
│   ├── GENERATOR_PREVIEW_RACE_CONDITION_FIX.md
│   ├── GIT_SUBMODULE_SETUP.md
│   ├── GRADIENT_FILL_IMPLEMENTATION.md
│   ├── GRID_OPACITY_IMPROVEMENTS.md
│   ├── INK_COMPONENT_EXPORT_IMPLEMENTATION_PLAN.md
│   ├── LAYER_TIMELINE_OPTIMIZATIONS.md
│   ├── LAYER_TIMELINE_REFACTOR_PLAN.md
│   ├── LOGGING_CLEANUP_SUMMARY.md
│   ├── MCP_GUIDE_RESOURCE_CODE.ts
│   ├── MCP_LLM_USAGE_GUIDE.md
│   ├── MCP_SERVER_IMPLEMENTATION_PLAN.md
│   ├── MEDIA_IMPORT_ANALYSIS.md
│   ├── MEDIA_IMPORT_FIXES_COMPLETE.md
│   ├── MEDIA_IMPORT_HISTORY_INTEGRATION.md
│   ├── MONOREPO_QUICK_REFERENCE.md
│   ├── MONOREPO_SETUP_COMPLETE.md
│   ├── MONOREPO_SETUP_GUIDE.md
│   ├── MULTI_FRAME_SELECTION_IMPLEMENTATION_PLAN.md
│   ├── MULTI_FRAME_SELECTION_MANUAL_TEST_PLAN.md
│   ├── ONION_SKINNING_GUIDE.md
│   ├── OPENTUI_COMPONENT_EXPORT_IMPLEMENTATION_PLAN.md
│   ├── OPEN_SOURCE_SECURITY_STRATEGY.md
│   ├── OS_CLIPBOARD_TESTING.md
│   ├── PALETTE_REMAP_IMPLEMENTATION.md
│   ├── PASTE_FUNCTIONALITY_TEST.md
│   ├── PERFORMANCE_ANALYSIS_REPORT.md
│   ├── PERFORMANCE_OPTIMIZATION.md
│   ├── PERFORMANCE_OPTIMIZATION_ACTION_PLAN.md
│   ├── PERFORMANCE_OPTIMIZATION_PHASE1.md
│   ├── PERMANENT_DELETE_RLS_FIX.md
│   ├── PERSISTENT_SELECTION_IMPLEMENTATION_PLAN.md
│   ├── PHASE_4_ADVANCED_TOOLS_PLAN.md
│   ├── POST_EFFECTS_DEVELOPER_GUIDE.md
│   ├── POST_EFFECTS_USER_GUIDE.md
│   ├── PREMIUM_DOCS_MOVED.md
│   ├── PRIVACY_POLICY.md
│   ├── PROCEDURAL_EFFECTS_HANDOFF.md
│   ├── PROJECT_MANAGEMENT_ENHANCEMENT_PLAN.md
│   ├── REACT_COMPONENT_EXPORT_IMPLEMENTATION_PLAN.md
│   ├── README.md
│   ├── RESPONSIVE_TESTING_CHECKLIST.md
│   ├── SCATTER_BLEND_COLORS_FEATURE.md
│   ├── SCATTER_EFFECT_FINAL_IMPLEMENTATION.md
│   ├── SECURITY_HEADERS_INDEX.md
│   ├── SECURITY_REVIEW.md
│   ├── SHARED_UI_COMPONENTS_PATTERN.md
│   ├── SVG_EXPORT_IMPLEMENTATION_PLAN.md
│   ├── SVG_TEXT_TO_OUTLINES_IMPLEMENTATION_PLAN.md
│   ├── SVG_TEXT_TO_OUTLINES_IMPLEMENTATION_SUMMARY.md
│   ├── TAB_ORDER_STRATEGY.md
│   ├── TERMS_OF_SERVICE.md
│   ├── TIME_EFFECTS_IMPLEMENTATION_PLAN.md
│   ├── TOOL_BEHAVIOR_IMPLEMENTATION.md
│   ├── TYPOGRAPHY_IMPLEMENTATION.md
│   ├── UI_COMPONENTS_DESIGN_SYSTEM.md
│   ├── UNDO_REDO_BUG_FIXES.md
│   ├── VERCEL_JSON_REFERENCE.md
│   ├── WIDTH_HEIGHT_INPUT_FIX.md
│   └── timanthes.txt
├── eslint.config.js
├── index.html
├── package.json
├── packages/
│   └── core/
│       ├── package.json
│       ├── src/
│       │   ├── components/
│       │   │   ├── index.ts
│       │   │   └── ui/
│       │   │       ├── alert.tsx
│       │   │       ├── badge.tsx
│       │   │       ├── button.tsx
│       │   │       ├── card.tsx
│       │   │       ├── checkbox.tsx
│       │   │       ├── collapsible.tsx
│       │   │       ├── dialog.tsx
│       │   │       ├── dropdown-menu.tsx
│       │   │       ├── input.tsx
│       │   │       ├── label.tsx
│       │   │       ├── menubar.tsx
│       │   │       ├── popover.tsx
│       │   │       ├── progress.tsx
│       │   │       ├── scroll-area.tsx
│       │   │       ├── select.tsx
│       │   │       ├── separator.tsx
│       │   │       ├── sheet.tsx
│       │   │       ├── skeleton.tsx
│       │   │       ├── slider.tsx
│       │   │       ├── switch.tsx
│       │   │       ├── tabs.tsx
│       │   │       ├── textarea.tsx
│       │   │       ├── toggle.tsx
│       │   │       └── tooltip.tsx
│       │   ├── index.ts
│       │   └── lib/
│       │       └── utils.ts
│       └── tsconfig.json
├── postcss.config.js
├── public/
│   ├── ffmpeg/
│   │   ├── ffmpeg-core.js
│   │   └── ffmpeg-core.wasm
│   ├── fonts/
│   │   └── jetbrains-mono/
│   │       └── LICENSE.txt
│   └── site.webmanifest
├── scripts/
│   ├── check-licenses.js
│   ├── create_mcp_guide.py
│   ├── download-fonts.sh
│   ├── extract-logo-frames.js
│   ├── migrate-to-monorepo.js
│   ├── setup-premium-submodule.sh
│   ├── update_mcp_resources.py
│   └── version-bump.js
├── src/
│   ├── App.css
│   ├── App.tsx
│   ├── __tests__/
│   │   ├── canvasStoreLayerSync.test.ts
│   │   ├── easing.test.ts
│   │   ├── effectBlocks.test.ts
│   │   ├── effectRegistry.test.ts
│   │   ├── effectsPipeline.test.ts
│   │   ├── layerCompositing.test.ts
│   │   ├── layerLimits.test.ts
│   │   ├── phase5ExportMigration.test.ts
│   │   ├── phase6Integration.test.ts
│   │   ├── sessionMigration.test.ts
│   │   ├── timelineStore.test.ts
│   │   ├── timelineUI.test.ts
│   │   └── useTimelineHistory.test.ts
│   ├── components/
│   │   ├── common/
│   │   │   ├── AppReveal.tsx
│   │   │   ├── AsciiMotionLogo.tsx
│   │   │   ├── CellRenderer.tsx
│   │   │   ├── CollapsibleHeader.tsx
│   │   │   ├── CollapsiblePanel.tsx
│   │   │   ├── ColorSwatch.tsx
│   │   │   ├── DraggableDialogBar.tsx
│   │   │   ├── MouseCoordinates.tsx
│   │   │   ├── PanelSeparator.tsx
│   │   │   ├── PanelToggleButton.tsx
│   │   │   ├── PerformanceMonitor.tsx
│   │   │   ├── PerformanceOverlay.tsx
│   │   │   ├── Spinner.tsx
│   │   │   ├── ThemeToggle.tsx
│   │   │   └── VersionDisplay.tsx
│   │   ├── demos/
│   │   │   └── SimpleAsciiDemo.tsx
│   │   ├── features/
│   │   │   ├── AboutDialog.tsx
│   │   │   ├── AccountButton.tsx
│   │   │   ├── ActiveLayerIndicator.tsx
│   │   │   ├── ActiveStyleSection.tsx
│   │   │   ├── AnchorPointOverlay.tsx
│   │   │   ├── AsciiBoxPanel.tsx
│   │   │   ├── AsciiTypePanel.tsx
│   │   │   ├── AsciiTypePreviewDialog.tsx
│   │   │   ├── AuthButtons.tsx
│   │   │   ├── BackgroundColorMappingSection.tsx
│   │   │   ├── BezierActionButtons.tsx
│   │   │   ├── BrushControls.tsx
│   │   │   ├── BrushPreview.tsx
│   │   │   ├── BrushSizePreviewOverlay.tsx
│   │   │   ├── BubbleteaExportDialog.tsx
│   │   │   ├── CanvasActionButtons.tsx
│   │   │   ├── CanvasGrid.tsx
│   │   │   ├── CanvasOverlay.tsx
│   │   │   ├── CanvasRenderer.tsx
│   │   │   ├── CanvasResizeDialog.tsx
│   │   │   ├── CanvasSettings.tsx
│   │   │   ├── CanvasSizePicker.tsx
│   │   │   ├── CanvasWithShortcuts.tsx
│   │   │   ├── CharacterMappingControls.tsx
│   │   │   ├── CharacterMappingSection.tsx
│   │   │   ├── CharacterPalette.tsx
│   │   │   ├── CharacterPaletteEditor.tsx
│   │   │   ├── ColorPicker.tsx
│   │   │   ├── ColorPickerOverlay.tsx
│   │   │   ├── ColorPicker_new.tsx
│   │   │   ├── ColorReadout.tsx
│   │   │   ├── EffectsSection.tsx
│   │   │   ├── EnhancedCharacterPicker.tsx
│   │   │   ├── ExportCharacterPaletteDialog.tsx
│   │   │   ├── ExportImportButtons.tsx
│   │   │   ├── ExportPaletteDialog.tsx
│   │   │   ├── ForegroundBackgroundSelector.tsx
│   │   │   ├── FullscreenToggle.tsx
│   │   │   ├── GalleryMobileMenu.tsx
│   │   │   ├── GeneratorsPanel.tsx
│   │   │   ├── GeneratorsSection.tsx
│   │   │   ├── GradientPanel.tsx
│   │   │   ├── GradientPropertyPreview.tsx
│   │   │   ├── GradientStopPicker.tsx
│   │   │   ├── HamburgerMenu.tsx
│   │   │   ├── HtmlExportDialog.tsx
│   │   │   ├── ImageExportDialog.tsx
│   │   │   ├── ImportCharacterPaletteDialog.tsx
│   │   │   ├── ImportModal.tsx
│   │   │   ├── ImportPaletteDialog.tsx
│   │   │   ├── InkExportDialog.tsx
│   │   │   ├── InlineProjectNameEditor.tsx
│   │   │   ├── InteractiveBezierOverlay.tsx
│   │   │   ├── InteractiveGradientOverlay.tsx
│   │   │   ├── InteractiveVectorShapeOverlay.tsx
│   │   │   ├── JsonExportDialog.tsx
│   │   │   ├── KeyboardShortcutsDialog.tsx
│   │   │   ├── LayerTransformOverlay.tsx
│   │   │   ├── MCPConnectionDialog.tsx
│   │   │   ├── MainCharacterPaletteSection.tsx
│   │   │   ├── ManageCharacterPalettesDialog.tsx
│   │   │   ├── ManagePalettesDialog.tsx
│   │   │   ├── MediaImportPanel.tsx
│   │   │   ├── MobileDialog.tsx
│   │   │   ├── NewProjectDialog.tsx
│   │   │   ├── OnionSkinControls.tsx
│   │   │   ├── OpenTuiExportDialog.tsx
│   │   │   ├── PastePreviewOverlay.tsx
│   │   │   ├── PlaybackControls.tsx
│   │   │   ├── PlaybackOverlay.tsx
│   │   │   ├── PlaybackStatusBar.tsx
│   │   │   ├── PostEffectsSection.tsx
│   │   │   ├── PreprocessingSection.tsx
│   │   │   ├── ProjectCanvasPreview.tsx
│   │   │   ├── ProjectSettingsDialog.tsx
│   │   │   ├── ProjectsDialog.tsx
│   │   │   ├── PublishToGalleryDialogWrapper.tsx
│   │   │   ├── PublishedProjectSaveWarningDialog.tsx
│   │   │   ├── ReactExportDialog.tsx
│   │   │   ├── SaveToCloudDialog.tsx
│   │   │   ├── SessionExportDialog.tsx
│   │   │   ├── SilentSaveHandler.tsx
│   │   │   ├── TextColorMappingSection.tsx
│   │   │   ├── TextExportDialog.tsx
│   │   │   ├── TimelinePanel.tsx
│   │   │   ├── ToolBehaviorSettings.tsx
│   │   │   ├── ToolManager.tsx
│   │   │   ├── ToolPalette.tsx
│   │   │   ├── ToolPalette_backup.tsx
│   │   │   ├── ToolPalette_new.tsx
│   │   │   ├── ToolStatusManager.tsx
│   │   │   ├── TransparencySection.tsx
│   │   │   ├── UpgradeToProDialog.tsx
│   │   │   ├── VideoExportDialog.tsx
│   │   │   ├── WelcomeAsciiAnimation.tsx
│   │   │   ├── WelcomeAsciiAnimationData.tsx
│   │   │   ├── WelcomeDialog.tsx
│   │   │   ├── ZoomControls.tsx
│   │   │   ├── generators/
│   │   │   │   ├── DigitalRainSettings.tsx
│   │   │   │   ├── GeneratorsMappingTab.tsx
│   │   │   │   ├── ParticlePhysicsSettings.tsx
│   │   │   │   ├── PlaceholderGeneratorSettings.tsx
│   │   │   │   ├── RadioWavesSettings.tsx
│   │   │   │   ├── RainDropsSettings.tsx
│   │   │   │   └── TurbulentNoiseSettings.tsx
│   │   │   ├── preview/
│   │   │   │   └── GeneratorPreviewCanvas.tsx
│   │   │   └── timeline/
│   │   │       ├── ContentFrameBlock.tsx
│   │   │       ├── EasingCurveEditor.tsx
│   │   │       ├── EffectBlock.tsx
│   │   │       ├── EffectPropertiesPanel.tsx
│   │   │       ├── EffectTrackRow.tsx
│   │   │       ├── FrameRateControl.tsx
│   │   │       ├── GlobalEffectsTrackHeader.tsx
│   │   │       ├── GroupHeader.tsx
│   │   │       ├── GroupPropertiesPanel.tsx
│   │   │       ├── KeyframeDiamond.tsx
│   │   │       ├── KeyframeEditorPanel.tsx
│   │   │       ├── LayerContextMenu.tsx
│   │   │       ├── LayerList.tsx
│   │   │       ├── LayerListItem.tsx
│   │   │       ├── LayerMenu.tsx
│   │   │       ├── LayerPropertiesPanel.tsx
│   │   │       ├── PostEffectBlock.tsx
│   │   │       ├── PostEffectPropertiesPanel.tsx
│   │   │       ├── PostEffectsTrackHeader.tsx
│   │   │       ├── TimecodeDisplay.tsx
│   │   │       ├── TimelineContextMenu.tsx
│   │   │       ├── TimelineResizeHandle.tsx
│   │   │       ├── TimelineRuler.tsx
│   │   │       ├── TimelineToolbar.tsx
│   │   │       ├── TimelineTrackArea.tsx
│   │   │       ├── timecodeUtils.ts
│   │   │       └── timelineRulerUtils.ts
│   │   ├── icons/
│   │   │   ├── DiscordIcon.tsx
│   │   │   ├── GitHubIcon.tsx
│   │   │   ├── GradientIcon.tsx
│   │   │   ├── README.md
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   ├── tools/
│   │   │   ├── AsciiBoxTool.tsx
│   │   │   ├── AsciiTypeTool.tsx
│   │   │   ├── BezierShapeTool.tsx
│   │   │   ├── DrawingTool.tsx
│   │   │   ├── EllipseTool.tsx
│   │   │   ├── EyedropperTool.tsx
│   │   │   ├── FlipHorizontalTool.tsx
│   │   │   ├── FlipVerticalTool.tsx
│   │   │   ├── GradientFillTool.tsx
│   │   │   ├── LassoTool.tsx
│   │   │   ├── LayerTransformTool.tsx
│   │   │   ├── MagicWandTool.tsx
│   │   │   ├── PaintBucketTool.tsx
│   │   │   ├── RectangleTool.tsx
│   │   │   ├── SelectionTool.tsx
│   │   │   ├── TextTool.tsx
│   │   │   └── index.ts
│   │   └── ui/
│   │       ├── alert.tsx
│   │       ├── badge.tsx
│   │       ├── button.tsx
│   │       ├── card.tsx
│   │       ├── checkbox.tsx
│   │       ├── collapsible.tsx
│   │       ├── dialog.tsx
│   │       ├── dropdown-menu.tsx
│   │       ├── input.tsx
│   │       ├── label.tsx
│   │       ├── menubar.tsx
│   │       ├── popover.tsx
│   │       ├── progress.tsx
│   │       ├── scroll-area.tsx
│   │       ├── select.tsx
│   │       ├── separator.tsx
│   │       ├── sheet.tsx
│   │       ├── skeleton.tsx
│   │       ├── slider.tsx
│   │       ├── sonner.tsx
│   │       ├── switch.tsx
│   │       ├── tabs.tsx
│   │       ├── textarea.tsx
│   │       ├── toggle.tsx
│   │       └── tooltip.tsx
│   ├── constants/
│   │   ├── bezierAutofill/
│   │   │   ├── ansiCharacters.ts
│   │   │   ├── ansiCharacters_backup.ts
│   │   │   ├── blockCharacters.ts
│   │   │   ├── brailleCharacters.ts
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   ├── boxDrawingStyles.ts
│   │   ├── colors.ts
│   │   ├── defaultCharacterPalettes.ts
│   │   ├── defaultPalettes.ts
│   │   ├── effectsDefaults.ts
│   │   ├── features.ts
│   │   ├── figletFonts.ts
│   │   ├── fonts.d.ts
│   │   ├── fonts.ts
│   │   ├── generators.ts
│   │   ├── hotkeys.ts
│   │   ├── index.ts
│   │   ├── onionSkin.ts
│   │   ├── postEffectDefaults.ts
│   │   ├── shapeVectors.ts
│   │   └── version.ts
│   ├── contexts/
│   │   ├── CanvasContext/
│   │   │   ├── CanvasProvider.tsx
│   │   │   ├── context.ts
│   │   │   ├── index.ts
│   │   │   ├── useCanvasContext.ts
│   │   │   └── useCanvasDimensions.ts
│   │   ├── CanvasContext.ts
│   │   ├── CanvasContext.tsx
│   │   ├── ModalContext/
│   │   │   ├── ModalProvider.tsx
│   │   │   ├── context.ts
│   │   │   ├── index.ts
│   │   │   └── useModalContext.ts
│   │   ├── ModalContext.ts
│   │   ├── ModalContext.tsx
│   │   ├── ThemeContext/
│   │   │   ├── ThemeProvider.tsx
│   │   │   ├── context.ts
│   │   │   ├── index.ts
│   │   │   └── useTheme.ts
│   │   ├── ThemeContext.ts
│   │   └── ThemeContext.tsx
│   ├── hooks/
│   │   ├── useAdminProjectLoader.ts
│   │   ├── useAnimationHistory.ts
│   │   ├── useAsciiBoxTool.ts
│   │   ├── useAsciiTypePlacement.ts
│   │   ├── useAsciiTypeTool.ts
│   │   ├── useCanvasDragAndDrop.ts
│   │   ├── useCanvasLassoSelection.ts
│   │   ├── useCanvasMagicWandSelection.ts
│   │   ├── useCanvasMouseHandlers.ts
│   │   ├── useCanvasRenderer.ts
│   │   ├── useCanvasRenderer.ts.backup
│   │   ├── useCanvasResize.ts
│   │   ├── useCanvasSelection.ts
│   │   ├── useCanvasState.ts
│   │   ├── useCloudDialogState.ts
│   │   ├── useCloudProjectActions.ts
│   │   ├── useCompositedCanvas.ts
│   │   ├── useCropToSelection.ts
│   │   ├── useDrawingTool.ts
│   │   ├── useEffectBlockHistory.ts
│   │   ├── useFlipUtilities.ts
│   │   ├── useFrameNavigation.ts
│   │   ├── useFrameSynchronization.ts
│   │   ├── useGeneratorPreview.ts
│   │   ├── useGradientFillTool.ts
│   │   ├── useHoverPreview.ts
│   │   ├── useKeyboardShortcuts.ts
│   │   ├── useKeyframeableProperty.ts
│   │   ├── useLayerLimit.ts
│   │   ├── useLayerTransformTool.ts
│   │   ├── useLayoutState.ts
│   │   ├── useMemoizedGrid.ts
│   │   ├── useOnionSkinRenderer.ts
│   │   ├── useOptimizedPlayback.ts
│   │   ├── useOptimizedRender.ts
│   │   ├── usePasteMode.ts
│   │   ├── usePerformanceMonitor.ts
│   │   ├── usePlaybackFpsMonitor.ts
│   │   ├── usePlaybackOnlySnapshot.ts
│   │   ├── usePostEffectBlockHistory.ts
│   │   ├── usePostEffectsRenderer.ts
│   │   ├── useProjectDialogState.ts
│   │   ├── useProjectFileActions.ts
│   │   ├── useScrubInput.ts
│   │   ├── useSelectionSync.ts
│   │   ├── useTextTool.ts
│   │   ├── useTimelineHistory.ts
│   │   ├── useToolBehavior.ts
│   │   ├── useWelcomeDialog.ts
│   │   └── useZoomControls.ts
│   ├── index.css
│   ├── index.css.backup
│   ├── lib/
│   │   ├── figletClient.ts
│   │   ├── premium-stub.ts
│   │   └── utils.ts
│   ├── main.tsx
│   ├── mcp/
│   │   ├── client.ts
│   │   ├── index.ts
│   │   ├── store.ts
│   │   ├── types.ts
│   │   └── useMCPConnection.ts
│   ├── pages/
│   │   ├── CommunityPage.tsx
│   │   └── EditorPage.tsx
│   ├── registry/
│   │   ├── effectRegistry.ts
│   │   ├── effects/
│   │   │   ├── hueSaturation.ts
│   │   │   ├── index.ts
│   │   │   ├── levels.ts
│   │   │   ├── motionTrails.ts
│   │   │   ├── remapCharacters.ts
│   │   │   ├── remapColors.ts
│   │   │   ├── scatter.ts
│   │   │   ├── waveWarp.ts
│   │   │   └── wiggle.ts
│   │   ├── postEffectRegistry.ts
│   │   └── postEffects/
│   │       ├── blur.ts
│   │       ├── chromaticAberration.ts
│   │       ├── glow.ts
│   │       ├── index.ts
│   │       ├── pixelate.ts
│   │       └── screenDistortion.ts
│   ├── stores/
│   │   ├── animationStore.ts
│   │   ├── animationStoreAdapter.ts
│   │   ├── asciiBoxStore.ts
│   │   ├── asciiTypeStore.ts
│   │   ├── bezierStore.ts
│   │   ├── canvasStore.ts
│   │   ├── characterPaletteStore.ts
│   │   ├── exportStore.ts
│   │   ├── generatorsStore.ts
│   │   ├── gradientStore.ts
│   │   ├── importStore.ts
│   │   ├── paletteStore.ts
│   │   ├── playbackOnlyStore.ts
│   │   ├── previewStore.ts
│   │   ├── projectMetadataStore.ts
│   │   ├── selectionStore.ts
│   │   ├── timelineStore.ts
│   │   └── toolStore.ts
│   ├── styles/
│   │   └── bundled-fonts.css
│   ├── types/
│   │   ├── easing.ts
│   │   ├── effectBlock.ts
│   │   ├── effects.ts
│   │   ├── export.ts
│   │   ├── generators.ts
│   │   ├── index.ts
│   │   ├── mp4box.d.ts
│   │   ├── palette.ts
│   │   ├── postEffect.ts
│   │   ├── timeEffects.ts
│   │   ├── timeline.ts
│   │   └── welcomeDialog.ts
│   ├── utils/
│   │   ├── asciiConverter.ts
│   │   ├── bezierAutofillUtils.ts
│   │   ├── bezierFillUtils.ts
│   │   ├── bezierPathUtils.ts
│   │   ├── bezierStrokeUtils.ts
│   │   ├── boxDrawingEngine.ts
│   │   ├── brushUtils.ts
│   │   ├── canvasAnalysis.ts
│   │   ├── canvasDPI.ts
│   │   ├── canvasResizeUtils.ts
│   │   ├── canvasSizeConversion.ts
│   │   ├── canvasTextRendering.ts
│   │   ├── characterPaletteValidation.ts
│   │   ├── clipboardUtils.ts
│   │   ├── colorConversion.ts
│   │   ├── cropUtils.ts
│   │   ├── directCanvasRenderer.ts
│   │   ├── dirtyTracker.ts
│   │   ├── effectKeyframeInterpolation.ts
│   │   ├── effectsPipeline.ts
│   │   ├── effectsProcessing.ts
│   │   ├── exportDataCollector.ts
│   │   ├── exportPixelCalculator.ts
│   │   ├── exportRenderer.ts
│   │   ├── fillArea.ts
│   │   ├── flipUtils.ts
│   │   ├── font/
│   │   │   ├── fontLoader.ts
│   │   │   ├── fontRegistry.ts
│   │   │   ├── index.ts
│   │   │   ├── opentypePathConverter.ts
│   │   │   └── types.ts
│   │   ├── fontDetection.ts
│   │   ├── fontLoader.ts
│   │   ├── fontMetrics.ts
│   │   ├── frameUtils.ts
│   │   ├── generators/
│   │   │   ├── digitalRain.ts
│   │   │   ├── generatorEngine.ts
│   │   │   ├── particlePhysics.ts
│   │   │   ├── radioWaves.ts
│   │   │   ├── rainDrops.ts
│   │   │   └── turbulentNoise.ts
│   │   ├── gradientEngine.ts
│   │   ├── gridColor.ts
│   │   ├── kdTree.ts
│   │   ├── layerCompositing.ts
│   │   ├── layerLimits.ts
│   │   ├── layerTransformUtils.ts
│   │   ├── lineArtConverter.ts
│   │   ├── mediaProcessor.ts
│   │   ├── paletteValidation.ts
│   │   ├── performance.ts
│   │   ├── polygon.ts
│   │   ├── postEffectsPipeline.ts
│   │   ├── projectUtils.ts
│   │   ├── renderScheduler.ts
│   │   ├── selectionConstraint.ts
│   │   ├── selectionUtils.ts
│   │   ├── sessionImporter.ts
│   │   ├── sessionMigration.ts
│   │   ├── shapeBasedConverter.ts
│   │   ├── svgExportUtils.ts
│   │   ├── timeEffectsProcessing.ts
│   │   ├── vectorShapeGeometry.ts
│   │   └── webgl/
│   │       ├── WebGLPostProcessor.ts
│   │       ├── commonShaders.ts
│   │       ├── index.ts
│   │       └── shaderCompiler.ts
│   └── vite-env.d.ts
├── supabase/
│   ├── .gitignore
│   └── config.toml
├── tailwind.config.js
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
├── vercel.json
├── vite.config.ts
└── vitest.config.ts

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Next.js (for submodule sites - prevent accidental root pollution)
.next
next-env.d.ts

# Monorepo build outputs
packages/*/dist
packages/*/.tsbuildinfo

# Backup directories
.backup-premium/

# MCP tool caches
.playwright-mcp/

# Premium package protection
# Note: Premium code is in a separate private Git repository (Git submodule).
# No gitignore patterns needed - the entire packages/premium/ directory
# is managed by Git submodules and points to a private repo.
# See: .gitmodules and docs/GIT_SUBMODULE_SETUP.md

# Environment variables (CRITICAL: Never commit these!)
.env
.env.local
.env.production
.env.preview
.env.*.local

# Internal security documentation (CRITICAL: Never commit!)
docs/INTERNAL_SECURITY_MEASURES.md
**/INTERNAL_*.md

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
.vercel


================================================
FILE: .gitmodules
================================================
[submodule "packages/premium"]
	path = packages/premium
	url = https://github.com/cameronfoxly/Ascii-Motion-Premium.git
[submodule "packages/web"]
	path = packages/web
	url = https://github.com/cameronfoxly/Ascii-Motion-Web.git


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to ASCII Motion

Thank you for your interest in contributing to ASCII Motion! We welcome contributions to the **open-source core** of the project.

## 🎯 What Can I Contribute?

### ✅ Accepted Contributions (MIT License)

**Drawing Tools & Features:**
- New drawing tools (spray, line, polygon, etc.)
- Tool improvements (brush smoothing, better fill algorithm)
- Effect additions (blur, sharpen, dithering patterns)

**Animation Features:**
- Timeline improvements
- Onion skinning enhancements
- Frame interpolation

**Export Features:**
- New export formats
- Export quality improvements
- Batch export capabilities

**UI/UX:**
- Component improvements
- Accessibility enhancements
- Keyboard shortcuts
- Color picker improvements

**Performance:**
- Rendering optimizations
- Memory usage improvements
- Large canvas handling

**Documentation:**
- Code documentation
- User guides
- Tutorial content

### ❌ Not Accepted (Proprietary)

These features are closed-source and not accepting external contributions:

- Authentication system
- Cloud storage integration
- Payment processing
- User account management
- Premium feature gating

## 🚀 Getting Started

1. **Fork the repository**

2. **Clone your fork:**
   ```bash
   git clone https://github.com/YOUR_USERNAME/Ascii-Motion.git
   cd Ascii-Motion
   ```

3. **Install dependencies:**
   ```bash
   npm install
   ```

4. **Create a feature branch:**
   ```bash
   git checkout -b feature/my-new-tool
   ```

5. **Make your changes in `src/`** (not `packages/core/` — that's a shared UI library)

6. **Add license header to new files:**
   ```typescript
   /**
    * ASCII Motion - Open Source ASCII Art Editor
    * 
    * @license MIT
    * @copyright 2025 ASCII Motion
    * @see LICENSE-MIT for full license text
    */
   ```

7. **Test your changes:**
   ```bash
   npm run dev          # Manual testing
   npm run test:run     # Run test suite (343 tests)
   npm run lint         # Code quality check
   npm run build        # Production build
   ```

8. **Commit and push:**
   ```bash
   git add .
   git commit -m "feat: Add polygon drawing tool"
   git push origin feature/my-new-tool
   ```

9. **Open a Pull Request**

## 📝 Coding Guidelines

### File Organization

- Place new tools in `src/components/tools/`
- Place new hooks in `src/hooks/`
- Place utilities in `src/utils/`
- Place store additions in `src/stores/`
- Follow the **9-step tool creation pattern** in [COPILOT_INSTRUCTIONS.md](./COPILOT_INSTRUCTIONS.md)

### TypeScript

- Use strict TypeScript (no `any` types)
- Export all public APIs
- Document complex functions with JSDoc comments

### Code Style

- Use functional components with hooks
- Follow existing naming conventions
- Use Zustand for state management
- Use Tailwind CSS for styling

### Example: Adding a New Tool

```typescript
/**
 * ASCII Motion - Open Source ASCII Art Editor
 * 
 * @license MIT
 * @copyright 2025 ASCII Motion
 * @see LICENSE-MIT for full license text
 */

import { useCanvasStore } from '../../stores/canvasStore';
import { useToolStore } from '../../stores/toolStore';
import { screenToLocal } from '../../utils/layerTransformUtils';

export function MyNewTool() {
  const { cells, setCells } = useCanvasStore();
  const { selectedColor } = useToolStore();

  const handleClick = (x: number, y: number) => {
    // Your tool logic here
  };

  return (
    <button onClick={() => handleClick(0, 0)}>
      My Tool
    </button>
  );
}
```

## 🧪 Testing

Before submitting a PR:

- [ ] Run `npm run test:run` - All 343 tests pass
- [ ] Run `npm run lint` - Zero warnings
- [ ] Run `npm run dev` - Verify no console errors
- [ ] Run `npm run build` - Production build succeeds
- [ ] Test your feature manually
- [ ] Test with multiple layers (if animation/drawing related)
- [ ] Add tests for new store actions or utility functions
- [ ] Verify exports still work

## 📋 Pull Request Guidelines

### PR Title Format

Use conventional commits:

- `feat: Add spray tool`
- `fix: Correct fill algorithm overflow`
- `docs: Update tool documentation`
- `refactor: Simplify canvas rendering`
- `perf: Optimize animation playback`

### PR Description

Include:

1. **What** - What does this PR do?
2. **Why** - Why is this change needed?
3. **How** - How does it work?
4. **Testing** - How did you test it?
5. **Screenshots** - For UI changes (optional but helpful)

### Example PR Description

```markdown
## Add Polygon Drawing Tool

### What
Adds a polygon tool that lets users draw multi-point shapes.

### Why
Users requested a polygon tool for creating geometric ASCII art.

### How
- Click to add points
- Double-click or press Enter to close the polygon
- Uses line drawing algorithm between points

### Testing
- [x] Tested with 3-10 point polygons
- [x] Tested closing polygon
- [x] Tested with different colors
- [x] Tested undo/redo
- [x] Verified exports work

### Screenshots
[Include screenshot of polygon tool in action]
```

## 🔍 Code Review Process

1. **Automated Checks** - Must pass:
   - License header check
   - TypeScript compilation
   - Linting

2. **Manual Review** - Maintainers will check:
   - Code quality
   - Consistency with existing code
   - Feature completeness
   - Documentation

3. **Feedback** - We'll provide constructive feedback

4. **Merge** - Once approved, your PR will be merged!

## 🎉 Recognition

Contributors will be:
- Listed in release notes
- Credited in documentation
- Added to contributors list

## ❓ Questions?

- Open an issue for questions
- Check existing documentation
- See [docs/](./docs/) for technical guides

## 📜 License Agreement

By contributing, you agree that your contributions will be licensed under the MIT License (for `packages/core/` code).

---

Thank you for contributing to ASCII Motion! 🎨


================================================
FILE: COPILOT_INSTRUCTIONS.md
================================================
# ASCII Motion - Copilot Development Instructions

## Project Overview

ASCII Motion is a React + TypeScript web application for creating and animating ASCII art with a professional layer-based timeline system. The app uses a compositing architecture where multiple layers are rendered with keyframe-interpolated transforms (position, scale, rotation, anchor point).

**Tech stack:** Vite, React 19, Zustand, Shadcn/ui, Tailwind CSS v3, TypeScript strict mode.

**Version:** 2.1.0 (Shaders — GPU Post-Processing Effects)

**MCP Server:** The companion `ascii-motion-mcp` package (separate repo) provides an MCP server for AI-assisted creation. It mirrors the app's tool/layer/keyframe API via WebSocket. When adding new tools or features, update the MCP server's tools and state model accordingly. See `ascii-motion-mcp/src/tools/` and `ascii-motion-mcp/src/state.ts`.

---

## Critical Rules

### Security & Documentation

**Documentation locations (two directories based on sensitivity):**
```
Does this doc mention...
├─ Database/Supabase? → packages/premium/docs/
├─ Authentication?    → packages/premium/docs/
├─ Cloud storage?     → packages/premium/docs/
├─ Subscriptions?     → packages/premium/docs/
├─ Payments/Stripe?   → packages/premium/docs/
├─ Security policies? → packages/premium/docs/
└─ None of the above? → docs/
When in doubt?        → packages/premium/docs/
```

**NEVER include in any documentation:** Real API keys, database credentials, Supabase project IDs, service role keys, Stripe secret keys, real user data. Always use placeholders:
```bash
VITE_SUPABASE_URL=https://YOUR_SUPABASE_PROJECT_ID.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key-here
```

**Get project IDs dynamically via MCP tools**, never hardcode from memory:
```typescript
const projects = await mcp_supabase_list_projects();
const projectId = projects[0].id;
```

**Edge Function deployment:** Always use Supabase MCP tools, NOT the CLI (CLI requires interactive browser auth). Location: `packages/premium/supabase/functions/`

**If you accidentally commit sensitive IDs:** `npx tsx packages/premium/scripts/sanitize-project-ids.ts`

### Never Modify Subscription Tiers

**Do NOT change any user's subscription tier unless explicitly instructed by the project owner.**
```sql
-- ❌ FORBIDDEN without explicit permission
UPDATE profiles SET subscription_tier_id = 'admin-tier-id' WHERE id = 'some-user-id';

-- ✅ ONLY with explicit permission and confirmed user ID
UPDATE profiles SET subscription_tier_id = 'admin-tier-id' WHERE id = 'user-id-they-explicitly-provided';
```
If testing tier features: ask which account, get explicit user ID, confirm before executing.

### No Automatic Commits or Deployments

Do not commit or deploy automatically. All changes must be manually reviewed before committing. Only commit when explicitly asked. Never run `vercel deploy --prod` from feature branches.

### Tailwind CSS v3 Requirement

**NEVER upgrade to Tailwind CSS v4+** — it breaks Shadcn component styling.
- Required: Tailwind CSS v3.4.x
- PostCSS config must use `tailwindcss: {}`, NOT `@tailwindcss/postcss: {}`

### Security Headers (COEP/COOP)

FFmpeg requires `SharedArrayBuffer`, which mandates:
- `Cross-Origin-Embedder-Policy: credentialless`
- `Cross-Origin-Opener-Policy: same-origin`

Production config is in `vercel.json`. Development does NOT set COEP headers (allows Vimeo/YouTube iframes).

CSP must include `https://unpkg.com` in both `script-src` AND `connect-src` for FFmpeg WASM loading. `media-src blob:` is required for import previews.

Chrome iframes need `credentialless` attribute: `{...({ credentialless: 'true' } as any)}`

### Code Quality

- Run `npm run lint` after every code change — zero warnings required
- Run `npm test:run` after changes to verify all tests pass (343 tests across 10 files)
- Fix `react-hooks/exhaustive-deps` warnings immediately
- Use Radix tooltips, never HTML `title` attributes
- Use shadcn component variants, don't override with custom classes
- Scope custom CSS — avoid universal selectors that affect shadcn components

### Testing

**Infrastructure:** Vitest + jsdom + @testing-library/react

**Commands:**
- `npm test` — watch mode (development)
- `npm run test:run` — single run (CI / verification)
- `npm run test:coverage` — with v8 coverage report

**Existing test files** (in `src/__tests__/`):
- `timelineStore.test.ts` (58 tests) — layer CRUD, content frames, keyframes, config
- `easing.test.ts` (27 tests) — cubic bezier solver, interpolation, presets
- `sessionMigration.test.ts` (29 tests) — v1→v2 migration, validation, repair
- `useTimelineHistory.test.ts` (16 tests) — undo/redo wrappers
- `layerCompositing.test.ts` (40 tests) — visibility, solo, transforms, gaps
- `layerLimits.test.ts` (23 tests) — tier enforcement, limit checks
- `canvasStoreLayerSync.test.ts` (15 tests) — dirty tracking, sync patterns
- `phase5ExportMigration.test.ts` (24 tests) — export round-trip, format validation
- `phase6Integration.test.ts` (19 tests) — adapter wiring, multi-layer behavior
- `timelineUI.test.ts` (92 tests) — timecode, ticks, easing presets, store state

**When writing new tests:**
- Store tests: import store directly, call `createNewProject()` in `beforeEach`, assert with `getState()`
- Hook tests: use `renderHook` from `@testing-library/react`, mock dependencies with `vi.mock()`
- Pure function tests: import directly, test boundary conditions
- Name tests descriptively: `'addLayer inserts above active layer'` not `'test addLayer'`

**When to add tests:**
- New store actions or utility functions — always
- Bug fixes — add a regression test that would have caught the bug
- Complex logic (interpolation, compositing, migration) — comprehensive coverage
- UI components — test interaction logic via hook tests, not DOM rendering

---

## Architecture Overview

### Core Stores (Zustand)

| Store | Purpose |
|-------|---------|
| **`useTimelineStore`** | PRIMARY: Layers, content frames, keyframes, property tracks, groups, timeline config, playback |
| `useCanvasStore` | Working buffer for the active layer's current content frame |
| `useAnimationStore` | **Compatibility adapter** over `timelineStore` — do NOT use for new code |
| `useToolStore` | Active tool, settings, drawing state, undo/redo history |
| `useProjectMetadataStore` | Project name, description |
| `useImportStore` | Media import workflow |
| `useExportStore` | Export dialog state |
| `useGeneratorsStore` | Generator definitions and output |
| `usePaletteStore` | Color palettes |
| `useCharacterPaletteStore` | Character palettes and mapping |
| `useBezierStore` | Bezier pen tool state |
| `usePreviewStore` | Preview overlay for effects/generators |

### Data Flow

```
timelineStore (layers, content frames, keyframes)
    ↓
useFrameSynchronization (syncs active layer ↔ canvasStore)
    ↓
canvasStore (working buffer — drawing tools write here)
    ↓
useCompositedCanvas (composites all layers for rendering)
    ↓
useCanvasRenderer (draws to canvas element)
```

### Key Files

| File | Purpose |
|------|---------|
| `src/stores/timelineStore.ts` | Layer/keyframe/timeline state (~2200 lines) |
| `src/stores/animationStore.ts` | Legacy API adapter (~650 lines) |
| `src/utils/layerCompositing.ts` | Multi-layer compositing with inverse-mapping transforms |
| `src/utils/layerTransformUtils.ts` | `screenToLocal()`, `localToScreen()`, `screenToLocalForLayer()` |
| `src/hooks/useCompositedCanvas.ts` | Composites all visible layers for rendering |
| `src/hooks/useFrameSynchronization.ts` | Canvas ↔ timeline sync, layer switching, auto-save |
| `src/utils/sessionMigration.ts` | v1→v2 session format migration |
| `src/types/timeline.ts` | Layer, ContentFrame, Keyframe, PropertyTrack types |
| `src/types/easing.ts` | Cubic bezier easing with Newton-Raphson solver |

### Coordinate System

```
Mouse events → screen space → drawing tools call screenToLocal() → canvasStore (local space)
    → compositing forward-transforms → rendered output (screen space)
```

- Drawing tools: call `screenToLocal()` before `setCell()` to convert screen coords to layer-local
- Selection masks: stay in screen space
- Compositing: forward-transforms local content to screen space per layer
- Crop: shifts position transforms by canvas origin offset; does NOT re-key content data
- Export: `compositeLayersAtFrame()` produces screen-space output for all formats

### Layer System

**Content Frames** replace the old v1 frame model:
```typescript
interface ContentFrame {
  id: ContentFrameId;
  startFrame: number;      // Position on timeline
  durationFrames: number;  // Duration in frames
  data: Map<string, Cell>; // ASCII cell data in local space
}
```

**Keyframe interpolation** for position, scale, rotation, anchor point using cubic bezier easing. Property tracks store keyframes per-layer. Groups compose transforms additively with child layers.

**Session format v2.0.0** preserves full layer structure. v1 files auto-migrate on import via `migrateV1ToV2()`.

---

## UI Layout

```
┌─────────────────────────────────────────────────────────────┐
│ Header: Tool Options Bar | Canvas Size/Display | Theme      │
├─────────────────────────────────────────────────────────────┤
│ Tool Panel  │ Canvas (composited layers)  │ Right Sidebar   │
│ (84px,      │ + Zoom Controls Footer      │ Layer Properties │
│  2-col)     │                             │ or Keyframe Edit │
├─────────────────────────────────────────────────────────────┤
│ Timeline Panel (resizable)                                  │
│ Layer List (w-52) │ Ruler + Tracks + Keyframes              │
│ Footer: Work Area │ Onion Skin │ Zoom + Frame Timeline      │
└─────────────────────────────────────────────────────────────┘
```

**Z-Index hierarchy:** Canvas z-10–z-40, UI overlays z-50–z-999, Dropdowns/pickers z-[99999], Modals z-[100000]+

---

## Adding New Tools (9-Step Pattern)

Every new tool must follow this pattern for architectural consistency:

1. **Update Tool type** in `src/types/index.ts` — add to `Tool` union
2. **Create tool component** in `src/components/tools/YourTool.tsx` — behavior + status
3. **Export from index** in `src/components/tools/index.ts`
4. **Update `useToolBehavior.ts`** — display name, cursor, component names
5. **Update `ToolManager.tsx`** — render your tool component
6. **Update `ToolStatusManager.tsx`** — render your status component
7. **Implement tool logic** — use existing hooks (`useDrawingTool`, `useCanvasDragAndDrop`) or create a new dedicated hook
8. **Add tool store settings** if needed in `src/stores/toolStore.ts`
9. **Add hotkey** in `src/constants/hotkeys.ts` (MANDATORY) + update `KeyboardShortcutsDialog.tsx`
10. **Add MCP tool** in `ascii-motion-mcp/src/tools/` — expose the new tool's functionality for AI-assisted workflows, update state model if needed

**Hook selection:** Simple click tools → `useDrawingTool`. Drag tools → `useCanvasDragAndDrop`. Complex multi-state tools → create dedicated hook.

**Drawing tools must call `screenToLocal()`** before writing to `canvasStore` to handle layer transforms.

---

## Import System

- **Media import** supports "New Layer" mode (default) — creates a named layer from the source file
- **Video frame rate matching** — option to update project fps to match imported video, or keep project fps
- **Session import** auto-detects v1/v2 format and migrates v1 files
- **Import guard:** `animationStore.setImportingSession(true)` must be set before import to block auto-save race conditions in `useFrameSynchronization`
- **Layer-switch sync bug prevention:** The flush guard in `useFrameSynchronization` checks `!isImportingSession` to prevent writing empty canvas data to a newly-loaded layer whose ID matches the default layer

## Export System

All exports composite layers via `compositeLayersAtFrame()`:
- **React:** Compact array cells `[x,y,"char",colorIdx,bgIdx?]` + color dictionary + frame deduplication (~75% size reduction)
- **CLI (Ink, OpenTUI, BubbleTea):** Human-readable content rows + color dictionary + frame deduplication for identical consecutive frames
- **Video:** "Auto" fps mode uses project frame rate; 1:1 frame mapping (each animation frame = 1 video frame)
- **Session:** v2.0.0 format preserving full layer structure, keyframes, transforms
- **Crop:** Operates across all layers — shifts position transforms by crop offset, preserves keyframes

---

## File Organization

- **Root:** Essential project files only (README, package.json, configs)
- **`docs/`** — Public implementation docs, guides, plans
- **`packages/premium/docs/`** — Secure docs (auth, database, payments, subscriptions)
- **`dev-tools/`** — Test scripts, debugging tools, test projects
- **`src/components/ui/`** — Shadcn components (must sync to `packages/core/src/components/ui/`)

When adding/modifying Shadcn components, copy to `packages/core/` for the premium package.

---

## Key Patterns

### Undo/Redo
All undoable operations push to `toolStore.pushToHistory()` with typed `HistoryAction` objects. The handler in `useKeyboardShortcuts.ts` processes undo/redo for all action types. For drag operations, batch to a single undo (capture start values on mouseDown, push history on mouseUp).

### Layer-Aware Operations
When implementing features that read/write cell data:
- Reading cells for display: use `useCompositedCanvas` (composited view)
- Reading cells for the active layer: use `canvasStore.cells` (local space)
- Writing cells: use `canvasStore.setCell()` after `screenToLocal()` transform
- Multi-layer operations (crop, effects): iterate `timelineStore.layers` and handle each layer's transform separately

### Frame Synchronization
`useFrameSynchronization` handles the bidirectional sync between `canvasStore` and `timelineStore`:
- **Layer switch:** flush canvas to old layer's content frame, load new layer's content frame
- **Frame navigation:** same flush/load cycle
- **Auto-save:** debounced subscription writes canvas changes back to the active content frame
- **Guards:** `isImportingSession`, `isLoadingFrameRef`, `isPlaying`, `isDraggingFrame` prevent corruption

### Selection Tools
All selection tools must integrate with global keyboard handlers:
- Delete/Backspace: clear selected cells
- Cmd/Ctrl+C/V: copy/paste with clipboard priority (magic wand > lasso > rectangular)
- Arrow keys: move selection
- Escape: cancel/clear selection
- Enter: commit move operation


================================================
FILE: LICENSE-MIT
================================================
MIT License

Copyright (c) 2025 ASCII Motion

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: LICENSE-PREMIUM
================================================
PROPRIETARY LICENSE

Copyright (c) 2025 ASCII Motion

All rights reserved.

This software and associated documentation files (the "Premium Features") are
proprietary and confidential.

NOTICE: This license applies ONLY to the following directories and files:
  - packages/premium/
  - packages/web/
  - Any files marked with "@license Proprietary" in the header comments

Unauthorized copying, modification, distribution, or use of these Premium Features
is strictly prohibited without explicit written permission from ASCII Motion.

The Premium Features are provided "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR
A PARTICULAR PURPOSE AND NONINFRINGEMENT.

For licensing inquiries or permission requests, please contact:
  Email: contact@ascii-motion.com
  
Grant of License:
  Subject to the terms and conditions of this License, ASCII Motion grants you a
  limited, non-exclusive, non-transferable, revocable license to use the Premium
  Features solely in connection with the ASCII Motion application as deployed by
  ASCII Motion or its authorized distributors.

Restrictions:
  1. You may NOT copy, modify, or distribute the Premium Features
  2. You may NOT reverse engineer, decompile, or disassemble the Premium Features
  3. You may NOT use the Premium Features to create derivative works
  4. You may NOT remove or alter any proprietary notices or labels
  5. You may NOT use the Premium Features for commercial purposes without written consent

Termination:
  This license is effective until terminated. ASCII Motion may terminate this license
  at any time if you fail to comply with any term or condition. Upon termination, you
  must cease all use and destroy all copies of the Premium Features.

Governing Law:
  This License shall be governed by and construed in accordance with the laws of the
  jurisdiction in which ASCII Motion operates, without regard to its conflict of law
  provisions.


================================================
FILE: README.md
================================================
# [ASCII Motion](https://ascii-motion.app)

![ASCII Motion](https://img.shields.io/badge/version-2.0.4-green)
![License - Dual](https://img.shields.io/badge/license-MIT%20%2B%20Proprietary-blue)

A web app for creating and animating ASCII/ANSI art. 

Current deployed version:
https://ascii-motion.app

See what people are making in the community gallery:
https://ascii-motion.app/community

Learn more on the landing page:
https://ascii-motion.com

Check the usage documentation at:
https://docs.ascii-motion.com

<img width="2584" height="2002" alt="Screenshot 2026-02-17 at 4 26 14 PM" src="https://github.com/user-attachments/assets/ca4923b5-b964-4bd0-923c-c5c4b07ecad2" />


## 🎨 Current Features

- **Grid-based ASCII Art Editor** with full drawing toolset (pencil, eraser, fill, rectangle, ellipse, bezier pen, text, gradient, and more)
- **Convert images or video assets to ASCII art** with fine-tuned rendering control and frame rate matching
- **Custom Color and Character Palettes** including presets and import/export
- **Apply effects** and filters to existing animations
- **Generate animations** using procedural animation tools
- **Layer-Based Timeline** with keyframe interpolation for position, scale, rotation, and anchor point
- **Multi-Layer Compositing** with z-order, visibility, solo, lock, and layer groups
- **Keyframe Animation** with cubic bezier easing editor and presets
- **Export Formats:** Images (PNG, JPEG, SVG), Videos (MP4, WebM), React Components, CLI Components (Ink, OpenTUI, BubbleTea), Text, HTML, and session files
- **Publish to community gallery** and explore what people are making
- **MCP Server** ([ascii-motion-mcp](https://www.npmjs.com/package/ascii-motion-mcp)) for AI-assisted animation creation 
  
## 🚀 Quick Start

### Prerequisites
- Node.js 18+
- npm or yarn

### Installation
```bash
git clone https://github.com/cameronfoxly/Ascii-Motion.git
cd Ascii-Motion
npm install
```

### Development
```bash
npm run dev
```

### Build
```bash
npm run build
```

## 🚀 Deployment

This monorepo contains **three separate deployable apps**, each with its own Vercel project:

| App | Domain | Deploy From | Command |
|-----|--------|-------------|---------|
| **Main App** | `ascii-motion.app` | Root | `npm run deploy` |
| **Marketing** | `ascii-motion.com` | `packages/web/marketing` | `npx vercel --prod` |
| **Docs** | `docs.ascii-motion.com` | `packages/web/docs-site` | `npx vercel --prod` |

### Main App Deployment (Root)

The main ASCII art editor deploys with automated versioning:

<details>
  <summary>Available Deployment Commands</summary>

| Command | Version Increment | Use Case |
|---------|------------------|----------|
| `npm run deploy` | **Patch** (2.0.0 → 2.0.1) | Bug fixes, small updates |
| `npm run deploy:major` | **Minor** (2.0.1 → 2.1.0) | New features, significant improvements |
| `npm run deploy:preview` | **None** | Testing deployments, preview branches |

### Manual Version Commands

For version management without deployment:

```bash
# Increment patch version (2.0.0 → 2.0.1)
npm run version:patch

# Increment minor version (2.0.1 → 2.1.0) 
npm run version:minor

# Increment major version (2.1.0 → 3.0.0)
npm run version:major
```
</details>

### Marketing & Docs Site Deployment

These deploy **separately** from the main app using the Vercel CLI:

```bash
# Marketing site (ascii-motion.com)
cd packages/web/marketing
npx vercel --prod

# Docs site (docs.ascii-motion.com)
cd packages/web/docs-site
npx vercel --prod
```

See the README in each package for detailed deployment instructions.


## 🏗️ Tech Stack

- **React 19** - UI framework
- **TypeScript** - Type safety (strict mode)
- **Vite** - Build tool and dev server
- **Tailwind CSS v3** - Styling
- **Shadcn/ui** - UI components
- **Zustand** - State management
- **Lucide React** - Icons
- **Vitest** - Testing framework

## 📦 Project Structure

**This is a monorepo with dual licensing and separate deployment targets:**

- **`packages/core/`** - Open source core features (MIT License)
  - Canvas editor, drawing tools, animation system
  - Export features (PNG, SVG, GIF, MP4, etc.)
  - All UI components and utilities

- **`packages/premium/`** - Premium features (Proprietary License)
  - User authentication (email-based)
  - Cloud project storage (Supabase)
  - Payment integration (future)
  
- **`packages/web/marketing/`** - Marketing site (Proprietary License)
  - Deploys to `ascii-motion.com`
  - Next.js 16 + React 19
  - Has its own `package.json` and Vercel project
  
- **`packages/web/docs-site/`** - Documentation site (Proprietary License)
  - Deploys to `docs.ascii-motion.com`
  - Next.js 15 + MDX
  - Has its own `package.json` and Vercel project
  
See [docs/MONOREPO_SETUP_GUIDE.md](docs/MONOREPO_SETUP_GUIDE.md) for details.

## 🏛️ Core App Architecture

```
src/
├── components/
│   ├── common/         # Shared/reusable components
│   ├── features/       # Complex functional components (canvas, import/export)
│   │   └── timeline/   # Layer list, track area, keyframe editor, ruler
│   ├── tools/          # Tool-specific components
│   └── ui/             # Shadcn UI components
├── stores/
│   ├── timelineStore.ts   # PRIMARY: layers, content frames, keyframes, groups
│   ├── canvasStore.ts     # Working canvas buffer for active layer
│   ├── animationStore.ts  # Legacy compatibility adapter
│   └── toolStore.ts       # Tools, settings, undo/redo history
├── types/
│   ├── timeline.ts        # Layer, ContentFrame, Keyframe, PropertyTrack types
│   └── easing.ts          # Cubic bezier interpolation engine
├── hooks/              # Custom React hooks
├── utils/
│   ├── layerCompositing.ts    # Multi-layer compositing with transforms
│   ├── layerTransformUtils.ts # Screen↔local coordinate conversion
│   └── sessionMigration.ts    # v1→v2 format migration
├── constants/          # App configuration
└── pages/              # Page components
```

## 📋 Development Status

This is currently maintained entirely by me, an animator and brand designer with next to no experience with building tools. This has been vibe-coded into existence using GitHub Copilot in VScode, using mostly Claude Opus 4.6, with the occasional GPT-5.2-Codex when Claude gets stumped. Please forgive any messy or unusal structure or vibe-code artifacts, I'm trying my best!

### Upcoming features planned

- Refactor of effects system to integrate with v2 timeline, so that effects are procedural and can be keyframed across time. 
- Update the ellipse and rectangle tool to use the bezier pen tool's vector system
- Add a "find edges" algorithm to media import using ASCII line characters
- Update bezier tool and media import conversion functions to get more accurate shape edges
- Add a post processing shader effect layer for things like CRT Effects, Chromatic abberation, bloom, etc.

Got an idea for a new feature? [Open an issue](https://github.com/CameronFoxly/Ascii-Motion/issues/new)!

## 📖 Documentation

- **[Copilot Instructions](./COPILOT_INSTRUCTIONS.md)** - Architecture overview and development guidelines
- **[Contributing Guide](./CONTRIBUTING.md)** - How to contribute
- **[Monorepo Setup Guide](./docs/MONOREPO_SETUP_GUIDE.md)** - Dual-license structure
- **[Layer Timeline Refactor Plan](./docs/LAYER_TIMELINE_REFACTOR_PLAN.md)** - v2.0.0 architecture design
- **[Technical Documentation](./docs/)** - Implementation guides and feature documentation. Each .md file was created as a planning document when that feature was worked on and may not be currently still in date, but may be useful for contributors to understand the architecture and design decisions.
- **[Development Tools](./dev-tools/)** - Test scripts and debugging utilities

## 🤝 Contributing

We welcome contributions to the **open-source core** (`packages/core/`)!

### For Open Source Contributors

**What you can contribute:**
- ✅ New drawing tools and brushes
- ✅ Animation features and effects
- ✅ Export formats and converters
- ✅ UI/UX improvements
- ✅ Bug fixes and performance optimizations
- ✅ Documentation and examples

**What is proprietary:**
- ❌ Authentication system (`packages/premium/`)
- ❌ Cloud storage features
- ❌ Payment integration

### Monorepo Setup for Contributors

**Important:** This project uses a monorepo structure with a private Git submodule for premium features.

#### Project Structure
```
Ascii-Motion/               # Main repository (public)
├── packages/
│   ├── core/              # Open source (MIT) - You work here!
│   │   ├── src/
│   │   │   ├── components/
│   │   │   ├── stores/
│   │   │   ├── hooks/
│   │   │   └── utils/
│   │   └── package.json
│   └── premium/           # Private submodule (Proprietary)
│       └── (not accessible to contributors)
├── src/                   # Legacy code (being migrated to core)
└── package.json           # Root workspace config
```

#### Getting Started

1. **Clone the repository:**
   ```bash
   git clone https://github.com/cameronfoxly/Ascii-Motion.git
   cd Ascii-Motion
   npm install
   ```

2. **The `packages/premium/` folder will be empty** - This is expected! You don't need it to contribute. The app runs without premium features.

3. **Development:**
   ```bash
   npm run dev          # Start dev server
   npm run test:run     # Run tests (343 tests)
   npm run lint         # Check code quality
   npm run build        # Production build
   ```

4. **All source code lives in `src/`** — not in `packages/core/` (which is a shared UI component library). Your contributions go directly in `src/`.

5. **Key files to know:**
   - `src/stores/timelineStore.ts` — Primary state (layers, keyframes, timeline)
   - `src/hooks/useKeyboardShortcuts.ts` — All keyboard shortcuts and undo/redo
   - `src/components/features/ToolPalette.tsx` — Tool UI and options
   - `src/utils/exportRenderer.ts` — All export format rendering
   - `src/types/timeline.ts` — Core type definitions

#### Import Paths

When writing code in `src/`, use these import patterns:

```typescript
// Stores
import { useTimelineStore } from '../stores/timelineStore';
import { useCanvasStore } from '../stores/canvasStore';
import { useToolStore } from '../stores/toolStore';

// Utils
import { screenToLocal } from '../utils/layerTransformUtils';
import { compositeLayersAtFrame } from '../utils/layerCompositing';

// Types
import type { Layer, ContentFrame, KeyframeId } from '../types/timeline';

// UI Components
import { Button } from '../components/ui/button';
```

#### What Happens to Premium Code?

- The main app (`src/` folder) imports from both `core` and `premium`
- When you run `npm run dev` from the root, both packages are built
- **If `packages/premium/` is missing,** the app will still work but without auth/cloud features
- Your contributions to `core` are completely independent of premium features

#### Testing Your Changes

```bash
# Run the full test suite (343 tests)
npm run test:run

# Run tests in watch mode during development
npm test

# Lint check
npm run lint

# TypeScript type check
npx tsc --noEmit

# Production build verification
npm run build
```

#### Submitting Pull Requests

1. Fork the repository
2. Create a feature branch: `git checkout -b feature/amazing-tool`
3. Make your changes in `packages/core/`
4. Commit with clear messages: `git commit -m "Add gradient brush tool"`
5. Push to your fork: `git push origin feature/amazing-tool`
6. Open a Pull Request to the `main` branch

**PR Checklist:**
- [ ] Changes don't modify premium code (`packages/premium/`)
- [ ] Code follows existing patterns and TypeScript strict mode
- [ ] Tests pass (`npm run test:run`)
- [ ] No linting errors (`npm run lint`)
- [ ] Build succeeds (`npm run build`)
- [ ] New features include tests where applicable
- [ ] PR description explains what and why

See [CONTRIBUTING.md](./CONTRIBUTING.md) for detailed guidelines.

## 📜 License

**Dual License:**

- **Core Features** (`packages/core/`) - [MIT License](LICENSE-MIT)
  - Free to use, modify, and distribute
  - No restrictions on commercial use

- **Premium Features** (`packages/premium/`) - [Proprietary License](LICENSE-PREMIUM)
  - Authentication and cloud storage
  - Unauthorized copying or distribution prohibited

See individual LICENSE files for full details.

---

Made with ❤️ for the ASCII art community


================================================
FILE: api/og.ts
================================================
// Vercel Edge Function for Dynamic Open Graph Tags
// This handles /community/project/:projectId URLs and injects dynamic OG meta tags

import { createClient } from '@supabase/supabase-js'

// Types for Supabase response structure
// eslint-disable-next-line @typescript-eslint/no-unused-vars
type _ProjectData = {
  id: string
  name: string
  description: string | null
  preview_image_url: string | null
  user_id: string
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
type _UserProfile = {
  display_name: string
}

export const config = {
  runtime: 'edge',
}

export default async function handler(req: Request) {
  const url = new URL(req.url)
  const userAgent = req.headers.get('user-agent') || ''
  
  // Detect if this is a bot/crawler that needs OG tags
  const isCrawler = /bot|crawler|spider|crawling|facebookexternalhit|twitterbot|linkedinbot|slackbot|whatsapp|telegrambot/i.test(userAgent)
  
  // If not a crawler, serve the SPA directly
  if (!isCrawler) {
    // Rewrite to the SPA's index.html
    return fetch(new URL('/index.html', url.origin))
  }
  
  // Extract project ID from URL pattern: /community/project/:projectId
  const pathMatch = url.pathname.match(/^\/community\/project\/([a-f0-9-]+)/)
  
  if (!pathMatch) {
    // Not a project detail page, serve default
    return fetch(new URL('/index.html', url.origin))
  }

  const projectId = pathMatch[1]

  try {
    // Initialize Supabase client (using anonymous access for public projects)
    const supabaseUrl = process.env.VITE_SUPABASE_URL || process.env.NEXT_PUBLIC_SUPABASE_URL
    const supabaseAnonKey = process.env.VITE_SUPABASE_ANON_KEY || process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY

    if (!supabaseUrl || !supabaseAnonKey) {
      throw new Error('Missing Supabase environment variables')
    }

    const supabase = createClient(supabaseUrl, supabaseAnonKey)

    // Fetch project data
    const { data: project, error: projectError } = await supabase
      .from('projects')
      .select('id, name, description, preview_image_url, user_id')
      .eq('id', projectId)
      .eq('is_published', true)
      .eq('is_hidden', false)
      .is('deleted_at', null)
      .single()

    if (projectError || !project) {
      console.error('Project not found:', projectError)
      // Serve the SPA which will handle the 404
      return fetch(new URL('/index.html', url.origin))
    }

    // Fetch author display name
    const { data: profile } = await supabase
      .from('user_profiles_public')
      .select('display_name')
      .eq('user_id', project.user_id)
      .single()

    const authorName = profile?.display_name || 'Unknown Artist'

    // Generate dynamic meta tags
    const title = `${project.name} by ${authorName} - ASCII Motion`
    const description = project.description || `Check out this ASCII art animation by ${authorName} on ASCII Motion.`
    const imageUrl = sanitizeUrl(project.preview_image_url)
    const pageUrl = `https://ascii-motion.app/community/project/${projectId}`

    // Generate HTML with dynamic OG tags
    const html = `
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    
    <!-- Dynamic Project Meta Tags -->
    <title>${escapeHtml(title)}</title>
    <meta name="description" content="${escapeHtml(description)}" />
    <link rel="canonical" href="${pageUrl}" />

    <!-- Open Graph / Social Sharing -->
    <meta property="og:type" content="website" />
    <meta property="og:url" content="${pageUrl}" />
    <meta property="og:title" content="${escapeHtml(title)}" />
    <meta property="og:description" content="${escapeHtml(description)}" />
    <meta property="og:image" content="${imageUrl}" />
    <meta property="og:image:alt" content="ASCII art animation: ${escapeHtml(project.name)}" />
    <meta property="og:image:width" content="800" />
    <meta property="og:image:height" content="600" />

    <!-- Twitter -->
    <meta name="twitter:card" content="summary_large_image" />
    <meta name="twitter:title" content="${escapeHtml(title)}" />
    <meta name="twitter:description" content="${escapeHtml(description)}" />
    <meta name="twitter:image" content="${imageUrl}" />
    <meta name="twitter:image:alt" content="ASCII art animation: ${escapeHtml(project.name)}" />

    <!-- Standard Favicon -->
    <link rel="icon" type="image/x-icon" href="/favicon.ico" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
  </head>
  <body>
    <!-- Static page for crawlers - no redirect needed -->
    <div style="
      position: fixed;
      inset: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      background-color: hsl(0, 0%, 3.9%);
      color: hsl(0, 0%, 98%);
      font-family: 'Courier New', monospace;
    ">
      <div style="text-align: center;">
        <h1>${escapeHtml(project.name)}</h1>
        <p>by ${escapeHtml(authorName)}</p>
        <p style="margin-top: 1rem;">
          <a href="${pageUrl}" style="color: hsl(0, 0%, 80%);">View on ASCII Motion</a>
        </p>
      </div>
    </div>
  </body>
</html>
`

    return new Response(html, {
      headers: {
        'Content-Type': 'text/html; charset=utf-8',
        'Cache-Control': 'public, max-age=3600, s-maxage=3600', // Cache for 1 hour
      },
    })
  } catch (error) {
    console.error('Error generating OG tags:', error)
    
    // Fallback to SPA on error
    return fetch(new URL('/index.html', url.origin))
  }
}

// Helper function to escape HTML to prevent XSS
function escapeHtml(unsafe: string): string {
  return unsafe
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#039;')
}

// Helper function to validate and sanitize URLs
function sanitizeUrl(url: string | null): string {
  if (!url) return 'https://ascii-motion.app/og-image.png'
  
  try {
    const parsed = new URL(url)
    // Only allow http/https protocols
    if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
      return 'https://ascii-motion.app/og-image.png'
    }
    return escapeHtml(parsed.toString())
  } catch {
    // Invalid URL, return default
    return 'https://ascii-motion.app/og-image.png'
  }
}


================================================
FILE: components.json
================================================
{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "new-york",
  "rsc": false,
  "tsx": true,
  "tailwind": {
    "config": "tailwind.config.js",
    "css": "src/index.css",
    "baseColor": "neutral",
    "cssVariables": true,
    "prefix": ""
  },
  "iconLibrary": "lucide",
  "aliases": {
    "components": "@/components",
    "utils": "@/lib/utils",
    "ui": "@/components/ui",
    "lib": "@/lib",
    "hooks": "@/hooks"
  }
}


================================================
FILE: dev-tools/README.md
================================================
# Development Tools & Test Files

This directory contains development utilities, test scripts, and debugging tools used during ASCII Motion development.

## 🧪 **Test Files**

### **Clipboard Testing**
- [`clipboard-test.js`](./clipboard-test.js) - OS clipboard integration testing script

### **Video Export Testing**
- [`debug-video-export.js`](./debug-video-export.js) - Video export debugging utilities
- [`test-video-export.js`](./test-video-export.js) - Video export functionality tests
- [`test-video-loops.js`](./test-video-loops.js) - Animation loop testing

### **Performance & Timing**
- [`test-frame-timing.js`](./test-frame-timing.js) - Frame timing and performance tests

### **UI Testing**
- [`font-test.html`](./font-test.html) - Typography and font rendering tests

### **Data Files**
- [`test-palette.json`](./test-palette.json) - Test color palette data

## 🔧 **Usage**

These files are development utilities and are not part of the main application build. They can be run independently for testing specific features during development.

**Note**: These files are excluded from production builds and are intended for development use only.

## 🗑️ **Cleanup**

Periodically review and remove obsolete test files that are no longer needed for current development work.

================================================
FILE: dev-tools/bubbletea-test-cli/README.md
================================================
# Bubbletea Test CLI

Test harness for ASCII Motion Bubbletea (Go) component exports.

## Prerequisites

- Go 1.21 or later
- Bubbletea and Lipgloss packages

## Quick Start

1. **Install dependencies:**
   ```bash
   cd dev-tools/bubbletea-test-cli
   go mod tidy
   ```

2. **Export an animation from ASCII Motion:**
   - Open ASCII Motion
   - Create or load an animation
   - Click Export → Bubbletea Component
   - Configure settings (color mode, playback style, loop)
   - Download the `.go` file

3. **Add your animation:**
   ```bash
   # Create a directory for your animation package
   mkdir -p animations/asciimotion
   
   # Move your exported file
   mv ~/Downloads/ascii_motion_anim.go animations/asciimotion/
   ```

4. **Update main.go:**
   ```go
   import (
       anim "bubbletea-test-cli/animations/asciimotion"
   )
   
   func main() {
       // Pass true for dark terminal backgrounds, false for light
       model := anim.New(true)
       
       // Or use the convenience function (defaults to dark):
       // model := anim.NewWithDefaults()

       p := tea.NewProgram(model, tea.WithAltScreen())
       if _, err := p.Run(); err != nil {
           fmt.Printf("Error: %v\n", err)
           os.Exit(1)
       }
   }
   ```

5. **Run the animation:**
   ```bash
   go run main.go
   ```

## Playback Styles

### Autoplay
Animation runs automatically with no user controls.

### Keyboard Controls
- `Space` - Play/Pause toggle
- `R` - Restart animation
- `Q` - Quit

### API-based
For embedding in larger applications:
```go
// In your parent model
type ParentModel struct {
    animation anim.Model
    // ... other fields
}

func (m ParentModel) Init() tea.Cmd {
    return m.animation.Init()
}

func (m ParentModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    switch msg := msg.(type) {
    case anim.TickMsg:
        var cmd tea.Cmd
        m.animation, cmd = m.animation.Update(msg)
        return m, cmd
    }
    return m, nil
}

func (m ParentModel) View() string {
    return m.animation.View()
}

// API methods available on the model:
// m.animation.Play()       - Start playback (returns tea.Cmd)
// m.animation.Pause()      - Pause playback
// m.animation.Restart()    - Restart from frame 0 (returns tea.Cmd)
// m.animation.SetFrame(n)  - Jump to frame n
// m.animation.CurrentFrame() - Get current frame index
// m.animation.IsPlaying()  - Check if playing
// m.animation.FrameCount() - Get total frames
// m.animation.Width()      - Get animation width
// m.animation.Height()     - Get animation height
```

## Color Modes

Both color modes include dark and light color palettes for runtime selection:

### Hex (exact)
Uses true color hex values for precise color reproduction:
```go
// Dark terminal colors
var COLORS_DARK = map[string]lipgloss.TerminalColor{
    "c0": lipgloss.Color("#FF00FF"),
    "c1": lipgloss.Color("#00FFFF"),
}

// Light terminal colors  
var COLORS_LIGHT = map[string]lipgloss.TerminalColor{
    "c0": lipgloss.Color("#CC00CC"),
    "c1": lipgloss.Color("#00CCCC"),
}
```

### Semantic (ANSI 16)
Maps to terminal palette with human-readable comments:
```go
// Dark terminal theme
var THEME_DARK = map[string]lipgloss.TerminalColor{
    "c0": lipgloss.Color("13"),  // bright magenta
    "c1": lipgloss.Color("14"),  // bright cyan
}

// Light terminal theme
var THEME_LIGHT = map[string]lipgloss.TerminalColor{
    "c0": lipgloss.Color("5"),   // magenta
    "c1": lipgloss.Color("6"),   // cyan
}
```

### Runtime Selection
The `hasDarkBackground` parameter passed to `New()` controls which palette is used:
```go
// For dark terminals (e.g., iTerm2 dark theme)
model := anim.New(true)

// For light terminals (e.g., macOS Terminal light theme)
model := anim.New(false)
```

## Troubleshooting

### "package not found" error
Make sure your animation package directory matches the import path:
```
bubbletea-test-cli/
└── animations/
    └── asciimotion/      <- This must match "animations/asciimotion" in import
        └── ascii_motion_anim.go
```

### Colors don't look right
Try different color modes in the export dialog:
- **Hex** for exact colors (requires terminal with true color support)
- **Semantic** for maximum compatibility

Also make sure you're passing the correct `hasDarkBackground` value:
```go
// If your terminal has a dark background:
model := anim.New(true)

// If your terminal has a light background:
model := anim.New(false)
```

### Animation is choppy
The animation timing is based on frame durations from ASCII Motion. If frames have very short durations, you may see performance issues on some terminals.

## Project Structure

```
bubbletea-test-cli/
├── go.mod
├── go.sum (generated after go mod tidy)
├── main.go
├── README.md
└── animations/
    └── (your exported packages go here)
```


================================================
FILE: dev-tools/bubbletea-test-cli/animations/ascii_motion_anim.go
================================================
package asciimotion

import (
	"fmt"
	"strings"
	"time"

	tea "github.com/charmbracelet/bubbletea"
	"github.com/charmbracelet/lipgloss"
)

// Color themes - edit these values to customize for each background type
// COLORS_DARK is used when HasDarkBackground=true (default)
// COLORS_LIGHT is used when HasDarkBackground=false
var COLORS_DARK = map[string]lipgloss.Color{
	"c0": lipgloss.Color("#9f29ff"),
	"c1": lipgloss.Color("#04c7ff"),
	"c2": lipgloss.Color("#942eff"),
	"c3": lipgloss.Color("#004bff"),
	"c4": lipgloss.Color("#03b7ff"),
	"c5": lipgloss.Color("#FFFFFF"),
	"c6": lipgloss.Color("#003aff"),
	"c7": lipgloss.Color("#02a7ff"),
	"c8": lipgloss.Color("#0028ff"),
	"c9": lipgloss.Color("#0298ff"),
	"c10": lipgloss.Color("#0188ff"),
	"c11": lipgloss.Color("#5b46ff"),
	"c12": lipgloss.Color("#5429ff"),
	"c13": lipgloss.Color("#0078ff"),
	"c14": lipgloss.Color("#504bff"),
	"c15": lipgloss.Color("#4922ff"),
	"c16": lipgloss.Color("#444fff"),
	"c17": lipgloss.Color("#3d1bff"),
	"c18": lipgloss.Color("#00ff00"),
	"c19": lipgloss.Color("#3215ff"),
	"c20": lipgloss.Color("#3954ff"),
	"c21": lipgloss.Color("#260eff"),
	"c22": lipgloss.Color("#2d59ff"),
	"c23": lipgloss.Color("#1b07ff"),
	"c24": lipgloss.Color("#225eff"),
	"c25": lipgloss.Color("#0f00ff"),
	"c26": lipgloss.Color("#1762ff"),
	"c27": lipgloss.Color("#0b67ff"),
	"c28": lipgloss.Color("#9b2bff"),
	"c29": lipgloss.Color("#9c2aff"),
	"c30": lipgloss.Color("#9d2aff"),
	"c31": lipgloss.Color("#9e29ff"),
	"c32": lipgloss.Color("#922eff"),
	"c33": lipgloss.Color("#03baff"),
	"c34": lipgloss.Color("#03adff"),
	"c35": lipgloss.Color("#02a0ff"),
	"c36": lipgloss.Color("#0192ff"),
	"c37": lipgloss.Color("#6f3dff"),
	"c38": lipgloss.Color("#703dff"),
	"c39": lipgloss.Color("#0185ff"),
	"c40": lipgloss.Color("#6342ff"),
	"c41": lipgloss.Color("#6442ff"),
	"c42": lipgloss.Color("#6541ff"),
	"c43": lipgloss.Color("#6641ff"),
	"c44": lipgloss.Color("#6741ff"),
	"c45": lipgloss.Color("#6740ff"),
	"c46": lipgloss.Color("#4350ff"),
	"c47": lipgloss.Color("#454fff"),
	"c48": lipgloss.Color("#5847ff"),
	"c49": lipgloss.Color("#5947ff"),
	"c50": lipgloss.Color("#5a46ff"),
	"c51": lipgloss.Color("#5c45ff"),
	"c52": lipgloss.Color("#5d45ff"),
	"c53": lipgloss.Color("#5e45ff"),
	"c54": lipgloss.Color("#3855ff"),
	"c55": lipgloss.Color("#4d4cff"),
	"c56": lipgloss.Color("#4d4bff"),
	"c57": lipgloss.Color("#4e4bff"),
	"c58": lipgloss.Color("#4f4bff"),
	"c59": lipgloss.Color("#504aff"),
	"c60": lipgloss.Color("#514aff"),
	"c61": lipgloss.Color("#524aff"),
	"c62": lipgloss.Color("#2c59ff"),
	"c63": lipgloss.Color("#2e59ff"),
	"c64": lipgloss.Color("#4150ff"),
	"c65": lipgloss.Color("#4250ff"),
	"c66": lipgloss.Color("#464eff"),
	"c67": lipgloss.Color("#235dff"),
	"c68": lipgloss.Color("#3655ff"),
	"c69": lipgloss.Color("#3854ff"),
	"c70": lipgloss.Color("#3a54ff"),
	"c71": lipgloss.Color("#3b53ff"),
	"c72": lipgloss.Color("#1862ff"),
	"c73": lipgloss.Color("#2b5aff"),
	"c74": lipgloss.Color("#0d67ff"),
	"c75": lipgloss.Color("#0e66ff"),
	"c76": lipgloss.Color("#0f66ff"),
	"c77": lipgloss.Color("#1d60ff"),
	"c78": lipgloss.Color("#1e5fff"),
	"c79": lipgloss.Color("#1f5fff"),
	"c80": lipgloss.Color("#046aff"),
	"c81": lipgloss.Color("#056aff"),
	"c82": lipgloss.Color("#066aff"),
	"c83": lipgloss.Color("#0669ff"),
	"c84": lipgloss.Color("#0769ff"),
	"c85": lipgloss.Color("#0869ff"),
	"c86": lipgloss.Color("#0968ff"),
	"c87": lipgloss.Color("#0a68ff"),
	"c88": lipgloss.Color("#0c67ff"),
	"c89": lipgloss.Color("#1065ff"),
	"c90": lipgloss.Color("#1165ff"),
	"c91": lipgloss.Color("#1265ff"),
	"c92": lipgloss.Color("#1364ff"),
	"c93": lipgloss.Color("#9a2bff"),
	"c94": lipgloss.Color("#005dff"),
	"c95": lipgloss.Color("#972cff"),
	"c96": lipgloss.Color("#982cff"),
	"c97": lipgloss.Color("#992cff"),
	"c98": lipgloss.Color("#992bff"),
	"c99": lipgloss.Color("#8d30ff"),
	"c100": lipgloss.Color("#8e30ff"),
	"c101": lipgloss.Color("#8f30ff"),
	"c102": lipgloss.Color("#902fff"),
	"c103": lipgloss.Color("#8235ff"),
	"c104": lipgloss.Color("#8335ff"),
	"c105": lipgloss.Color("#8435ff"),
	"c106": lipgloss.Color("#8434ff"),
	"c107": lipgloss.Color("#8534ff"),
	"c108": lipgloss.Color("#8634ff"),
	"c109": lipgloss.Color("#773aff"),
	"c110": lipgloss.Color("#7839ff"),
	"c111": lipgloss.Color("#7939ff"),
	"c112": lipgloss.Color("#7a39ff"),
	"c113": lipgloss.Color("#7b38ff"),
	"c114": lipgloss.Color("#6b3fff"),
	"c115": lipgloss.Color("#6c3eff"),
	"c116": lipgloss.Color("#6d3eff"),
	"c117": lipgloss.Color("#6e3eff"),
	"c118": lipgloss.Color("#5e44ff"),
	"c119": lipgloss.Color("#5f44ff"),
	"c120": lipgloss.Color("#6044ff"),
	"c121": lipgloss.Color("#6143ff"),
	"c122": lipgloss.Color("#6243ff"),
	"c123": lipgloss.Color("#5449ff"),
	"c124": lipgloss.Color("#5548ff"),
	"c125": lipgloss.Color("#5648ff"),
	"c126": lipgloss.Color("#5747ff"),
	"c127": lipgloss.Color("#494dff"),
	"c128": lipgloss.Color("#4a4dff"),
	"c129": lipgloss.Color("#4b4cff"),
	"c130": lipgloss.Color("#4c4cff"),
	"c131": lipgloss.Color("#3d52ff"),
	"c132": lipgloss.Color("#3e52ff"),
	"c133": lipgloss.Color("#3f51ff"),
	"c134": lipgloss.Color("#4051ff"),
	"c135": lipgloss.Color("#4151ff"),
	"c136": lipgloss.Color("#3257ff"),
	"c137": lipgloss.Color("#3357ff"),
	"c138": lipgloss.Color("#3456ff"),
	"c139": lipgloss.Color("#3556ff"),
	"c140": lipgloss.Color("#265cff"),
	"c141": lipgloss.Color("#275cff"),
	"c142": lipgloss.Color("#285bff"),
	"c143": lipgloss.Color("#2a5aff"),
	"c144": lipgloss.Color("#1961ff"),
	"c145": lipgloss.Color("#1a61ff"),
	"c146": lipgloss.Color("#1b61ff"),
	"c147": lipgloss.Color("#1b60ff"),
	"c148": lipgloss.Color("#1c60ff"),
	"c149": lipgloss.Color("#006cff"),
	"c150": lipgloss.Color("#016cff"),
	"c151": lipgloss.Color("#026bff"),
	"c152": lipgloss.Color("#036bff"),
	"c153": lipgloss.Color("#8833ff"),
	"c154": lipgloss.Color("#7d37ff"),
	"c155": lipgloss.Color("#723cff"),
	"c156": lipgloss.Color("#4b24ff"),
	"c157": lipgloss.Color("#431fff"),
	"c158": lipgloss.Color("#3a1aff"),
	"c159": lipgloss.Color("#290fff"),
	"c160": lipgloss.Color("#200aff"),
	"c161": lipgloss.Color("#1805ff"),
	"c162": lipgloss.Color("#0043ff"),
	"c163": lipgloss.Color("#0046ff"),
	"c164": lipgloss.Color("#0049ff"),
	"c165": lipgloss.Color("#0054ff"),
	"c166": lipgloss.Color("#002fff"),
	"c167": lipgloss.Color("#004cff"),
	"c168": lipgloss.Color("#0035ff"),
	"c169": lipgloss.Color("#0038ff"),
	"c170": lipgloss.Color("#4520ff"),
	"c171": lipgloss.Color("#3517ff"),
	"c172": lipgloss.Color("#2e12ff"),
	"c173": lipgloss.Color("#1e09ff"),
	"c174": lipgloss.Color("#1705ff"),
	"c175": lipgloss.Color("#0040ff"),
	"c176": lipgloss.Color("#002cff"),
	"c177": lipgloss.Color("#004eff"),
	"c178": lipgloss.Color("#003fff"),
	"c179": lipgloss.Color("#03bcff"),
	"c180": lipgloss.Color("#0030ff"),
	"c181": lipgloss.Color("#03b0ff"),
	"c182": lipgloss.Color("#0183ff"),
	"c183": lipgloss.Color("#912fff"),
	"c184": lipgloss.Color("#932eff"),
	"c185": lipgloss.Color("#952dff"),
	"c186": lipgloss.Color("#962dff"),
	"c187": lipgloss.Color("#00cdcd"),
	"c188": lipgloss.Color("#8136ff"),
	"c189": lipgloss.Color("#8733ff"),
	"c190": lipgloss.Color("#8932ff"),
	"c191": lipgloss.Color("#8a32ff"),
	"c192": lipgloss.Color("#8b32ff"),
	"c193": lipgloss.Color("#8c31ff"),
	"c194": lipgloss.Color("#753bff"),
	"c195": lipgloss.Color("#763aff"),
	"c196": lipgloss.Color("#7c38ff"),
	"c197": lipgloss.Color("#7e37ff"),
	"c198": lipgloss.Color("#7f37ff"),
	"c199": lipgloss.Color("#8036ff"),
	"c200": lipgloss.Color("#6840ff"),
	"c201": lipgloss.Color("#6940ff"),
	"c202": lipgloss.Color("#6a3fff"),
	"c203": lipgloss.Color("#713cff"),
	"c204": lipgloss.Color("#733cff"),
	"c205": lipgloss.Color("#733bff"),
	"c206": lipgloss.Color("#743bff"),
	"c207": lipgloss.Color("#5249ff"),
	"c208": lipgloss.Color("#5349ff"),
	"c209": lipgloss.Color("#474eff"),
	"c210": lipgloss.Color("#484eff"),
	"c211": lipgloss.Color("#3755ff"),
	"c212": lipgloss.Color("#3c53ff"),
	"c213": lipgloss.Color("#295bff"),
	"c214": lipgloss.Color("#2f58ff"),
	"c215": lipgloss.Color("#3058ff"),
	"c216": lipgloss.Color("#3157ff"),
	"c217": lipgloss.Color("#245dff"),
	"c218": lipgloss.Color("#255cff"),
	"c219": lipgloss.Color("#4c24ff"),
	"c220": lipgloss.Color("#942dff"),
	"c221": lipgloss.Color("#7f36ff"),
	"c222": lipgloss.Color("#4d25ff"),
	"c223": lipgloss.Color("#4621ff"),
	"c224": lipgloss.Color("#3f1dff"),
	"c225": lipgloss.Color("#3819ff"),
	"c226": lipgloss.Color("#2b10ff"),
	"c227": lipgloss.Color("#240cff"),
	"c228": lipgloss.Color("#1d08ff"),
	"c229": lipgloss.Color("#205fff"),
	"c230": lipgloss.Color("#1604ff"),
	"c231": lipgloss.Color("#1563ff"),
	"c232": lipgloss.Color("#04c6ff"),
	"c233": lipgloss.Color("#04beff"),
	"c234": lipgloss.Color("#04bfff"),
	"c235": lipgloss.Color("#04c0ff"),
	"c236": lipgloss.Color("#03b8ff"),
	"c237": lipgloss.Color("#03b9ff"),
	"c238": lipgloss.Color("#2c5aff"),
	"c239": lipgloss.Color("#205eff"),
	"c240": lipgloss.Color("#215eff"),
	"c241": lipgloss.Color("#1663ff"),
	"c242": lipgloss.Color("#9e2aff"),
	"c243": lipgloss.Color("#9b2aff"),
	"c244": lipgloss.Color("#972dff"),
	"c245": lipgloss.Color("#922fff"),
	"c246": lipgloss.Color("#9030ff"),
	"c247": lipgloss.Color("#8d31ff"),
	"c248": lipgloss.Color("#8b31ff"),
	"c249": lipgloss.Color("#8832ff"),
	"c250": lipgloss.Color("#8633ff"),
	"c251": lipgloss.Color("#8135ff"),
	"c252": lipgloss.Color("#7d38ff"),
	"c253": lipgloss.Color("#7a38ff"),
	"c254": lipgloss.Color("#783aff"),
	"c255": lipgloss.Color("#753aff"),
	"c256": lipgloss.Color("#713dff"),
	"c257": lipgloss.Color("#02a5ff"),
	"c258": lipgloss.Color("#6e3dff"),
	"c259": lipgloss.Color("#6c3fff"),
	"c260": lipgloss.Color("#6a40ff"),
	"c261": lipgloss.Color("#6542ff"),
	"c262": lipgloss.Color("#029aff"),
	"c263": lipgloss.Color("#6242ff"),
	"c264": lipgloss.Color("#6043ff"),
	"c265": lipgloss.Color("#5b45ff"),
	"c266": lipgloss.Color("#5946ff"),
	"c267": lipgloss.Color("#018fff"),
	"c268": lipgloss.Color("#5748ff"),
	"c269": lipgloss.Color("#5448ff"),
	"c270": lipgloss.Color("#4b4dff"),
	"c271": lipgloss.Color("#464fff"),
	"c272": lipgloss.Color("#4450ff"),
	"c273": lipgloss.Color("#3a53ff"),
	"c274": lipgloss.Color("#3555ff"),
	"c275": lipgloss.Color("#3158ff"),
	"c276": lipgloss.Color("#2e58ff"),
	"c277": lipgloss.Color("#275bff"),
	"c278": lipgloss.Color("#255dff"),
	"c279": lipgloss.Color("#1962ff"),
	"c280": lipgloss.Color("#0f65ff"),
	"c281": lipgloss.Color("#0d66ff"),
	"c282": lipgloss.Color("#046bff"),
	"c283": lipgloss.Color("#04c5ff"),
	"c284": lipgloss.Color("#04c3ff"),
	"c285": lipgloss.Color("#04c1ff"),
	"c286": lipgloss.Color("#03b2ff"),
	"c287": lipgloss.Color("#03b4ff"),
	"c288": lipgloss.Color("#02a3ff"),
	"c289": lipgloss.Color("#02a1ff"),
	"c290": lipgloss.Color("#0194ff"),
	"c291": lipgloss.Color("#0189ff"),
	"c292": lipgloss.Color("#0187ff"),
	"c293": lipgloss.Color("#0081ff"),
	"c294": lipgloss.Color("#007eff"),
	"c295": lipgloss.Color("#007cff"),
	"c296": lipgloss.Color("#007aff"),
	"c297": lipgloss.Color("#1463ff"),
	"c298": lipgloss.Color("#5228ff"),
	"c299": lipgloss.Color("#5128ff"),
	"c300": lipgloss.Color("#4a23ff"),
	"c301": lipgloss.Color("#4923ff"),
	"c302": lipgloss.Color("#421fff"),
	"c303": lipgloss.Color("#3919ff"),
	"c304": lipgloss.Color("#3114ff"),
	"c305": lipgloss.Color("#3014ff"),
	"c306": lipgloss.Color("#2f13ff"),
	"c307": lipgloss.Color("#2c11ff"),
	"c308": lipgloss.Color("#2b11ff"),
	"c309": lipgloss.Color("#2a10ff"),
	"c310": lipgloss.Color("#2910ff"),
	"c311": lipgloss.Color("#280fff"),
	"c312": lipgloss.Color("#270fff"),
	"c313": lipgloss.Color("#270eff"),
	"c314": lipgloss.Color("#250dff"),
	"c315": lipgloss.Color("#240dff"),
	"c316": lipgloss.Color("#230cff"),
	"c317": lipgloss.Color("#220cff"),
	"c318": lipgloss.Color("#1d09ff"),
	"c319": lipgloss.Color("#1c08ff"),
	"c320": lipgloss.Color("#1a07ff"),
	"c321": lipgloss.Color("#1403ff"),
	"c322": lipgloss.Color("#1303ff"),
	"c323": lipgloss.Color("#1202ff"),
	"c324": lipgloss.Color("#1101ff"),
	"c325": lipgloss.Color("#1001ff"),
	"c326": lipgloss.Color("#00ffff"),
}

var COLORS_LIGHT = map[string]lipgloss.Color{
	"c0": lipgloss.Color("#9f29ff"),
	"c1": lipgloss.Color("#04c7ff"),
	"c2": lipgloss.Color("#942eff"),
	"c3": lipgloss.Color("#004bff"),
	"c4": lipgloss.Color("#03b7ff"),
	"c5": lipgloss.Color("#4d4d4d"),
	"c6": lipgloss.Color("#003aff"),
	"c7": lipgloss.Color("#02a7ff"),
	"c8": lipgloss.Color("#0028ff"),
	"c9": lipgloss.Color("#0298ff"),
	"c10": lipgloss.Color("#0188ff"),
	"c11": lipgloss.Color("#5b46ff"),
	"c12": lipgloss.Color("#5429ff"),
	"c13": lipgloss.Color("#0078ff"),
	"c14": lipgloss.Color("#504bff"),
	"c15": lipgloss.Color("#4922ff"),
	"c16": lipgloss.Color("#444fff"),
	"c17": lipgloss.Color("#3d1bff"),
	"c18": lipgloss.Color("#00ff00"),
	"c19": lipgloss.Color("#3215ff"),
	"c20": lipgloss.Color("#3954ff"),
	"c21": lipgloss.Color("#260eff"),
	"c22": lipgloss.Color("#2d59ff"),
	"c23": lipgloss.Color("#1b07ff"),
	"c24": lipgloss.Color("#225eff"),
	"c25": lipgloss.Color("#0f00ff"),
	"c26": lipgloss.Color("#1762ff"),
	"c27": lipgloss.Color("#0b67ff"),
	"c28": lipgloss.Color("#9b2bff"),
	"c29": lipgloss.Color("#9c2aff"),
	"c30": lipgloss.Color("#9d2aff"),
	"c31": lipgloss.Color("#9e29ff"),
	"c32": lipgloss.Color("#922eff"),
	"c33": lipgloss.Color("#03baff"),
	"c34": lipgloss.Color("#03adff"),
	"c35": lipgloss.Color("#02a0ff"),
	"c36": lipgloss.Color("#0192ff"),
	"c37": lipgloss.Color("#6f3dff"),
	"c38": lipgloss.Color("#703dff"),
	"c39": lipgloss.Color("#0185ff"),
	"c40": lipgloss.Color("#6342ff"),
	"c41": lipgloss.Color("#6442ff"),
	"c42": lipgloss.Color("#6541ff"),
	"c43": lipgloss.Color("#6641ff"),
	"c44": lipgloss.Color("#6741ff"),
	"c45": lipgloss.Color("#6740ff"),
	"c46": lipgloss.Color("#4350ff"),
	"c47": lipgloss.Color("#454fff"),
	"c48": lipgloss.Color("#5847ff"),
	"c49": lipgloss.Color("#5947ff"),
	"c50": lipgloss.Color("#5a46ff"),
	"c51": lipgloss.Color("#5c45ff"),
	"c52": lipgloss.Color("#5d45ff"),
	"c53": lipgloss.Color("#5e45ff"),
	"c54": lipgloss.Color("#3855ff"),
	"c55": lipgloss.Color("#4d4cff"),
	"c56": lipgloss.Color("#4d4bff"),
	"c57": lipgloss.Color("#4e4bff"),
	"c58": lipgloss.Color("#4f4bff"),
	"c59": lipgloss.Color("#504aff"),
	"c60": lipgloss.Color("#514aff"),
	"c61": lipgloss.Color("#524aff"),
	"c62": lipgloss.Color("#2c59ff"),
	"c63": lipgloss.Color("#2e59ff"),
	"c64": lipgloss.Color("#4150ff"),
	"c65": lipgloss.Color("#4250ff"),
	"c66": lipgloss.Color("#464eff"),
	"c67": lipgloss.Color("#235dff"),
	"c68": lipgloss.Color("#3655ff"),
	"c69": lipgloss.Color("#3854ff"),
	"c70": lipgloss.Color("#3a54ff"),
	"c71": lipgloss.Color("#3b53ff"),
	"c72": lipgloss.Color("#1862ff"),
	"c73": lipgloss.Color("#2b5aff"),
	"c74": lipgloss.Color("#0d67ff"),
	"c75": lipgloss.Color("#0e66ff"),
	"c76": lipgloss.Color("#0f66ff"),
	"c77": lipgloss.Color("#1d60ff"),
	"c78": lipgloss.Color("#1e5fff"),
	"c79": lipgloss.Color("#1f5fff"),
	"c80": lipgloss.Color("#046aff"),
	"c81": lipgloss.Color("#056aff"),
	"c82": lipgloss.Color("#066aff"),
	"c83": lipgloss.Color("#0669ff"),
	"c84": lipgloss.Color("#0769ff"),
	"c85": lipgloss.Color("#0869ff"),
	"c86": lipgloss.Color("#0968ff"),
	"c87": lipgloss.Color("#0a68ff"),
	"c88": lipgloss.Color("#0c67ff"),
	"c89": lipgloss.Color("#1065ff"),
	"c90": lipgloss.Color("#1165ff"),
	"c91": lipgloss.Color("#1265ff"),
	"c92": lipgloss.Color("#1364ff"),
	"c93": lipgloss.Color("#9a2bff"),
	"c94": lipgloss.Color("#005dff"),
	"c95": lipgloss.Color("#972cff"),
	"c96": lipgloss.Color("#982cff"),
	"c97": lipgloss.Color("#992cff"),
	"c98": lipgloss.Color("#992bff"),
	"c99": lipgloss.Color("#8d30ff"),
	"c100": lipgloss.Color("#8e30ff"),
	"c101": lipgloss.Color("#8f30ff"),
	"c102": lipgloss.Color("#902fff"),
	"c103": lipgloss.Color("#8235ff"),
	"c104": lipgloss.Color("#8335ff"),
	"c105": lipgloss.Color("#8435ff"),
	"c106": lipgloss.Color("#8434ff"),
	"c107": lipgloss.Color("#8534ff"),
	"c108": lipgloss.Color("#8634ff"),
	"c109": lipgloss.Color("#773aff"),
	"c110": lipgloss.Color("#7839ff"),
	"c111": lipgloss.Color("#7939ff"),
	"c112": lipgloss.Color("#7a39ff"),
	"c113": lipgloss.Color("#7b38ff"),
	"c114": lipgloss.Color("#6b3fff"),
	"c115": lipgloss.Color("#6c3eff"),
	"c116": lipgloss.Color("#6d3eff"),
	"c117": lipgloss.Color("#6e3eff"),
	"c118": lipgloss.Color("#5e44ff"),
	"c119": lipgloss.Color("#5f44ff"),
	"c120": lipgloss.Color("#6044ff"),
	"c121": lipgloss.Color("#6143ff"),
	"c122": lipgloss.Color("#6243ff"),
	"c123": lipgloss.Color("#5449ff"),
	"c124": lipgloss.Color("#5548ff"),
	"c125": lipgloss.Color("#5648ff"),
	"c126": lipgloss.Color("#5747ff"),
	"c127": lipgloss.Color("#494dff"),
	"c128": lipgloss.Color("#4a4dff"),
	"c129": lipgloss.Color("#4b4cff"),
	"c130": lipgloss.Color("#4c4cff"),
	"c131": lipgloss.Color("#3d52ff"),
	"c132": lipgloss.Color("#3e52ff"),
	"c133": lipgloss.Color("#3f51ff"),
	"c134": lipgloss.Color("#4051ff"),
	"c135": lipgloss.Color("#4151ff"),
	"c136": lipgloss.Color("#3257ff"),
	"c137": lipgloss.Color("#3357ff"),
	"c138": lipgloss.Color("#3456ff"),
	"c139": lipgloss.Color("#3556ff"),
	"c140": lipgloss.Color("#265cff"),
	"c141": lipgloss.Color("#275cff"),
	"c142": lipgloss.Color("#285bff"),
	"c143": lipgloss.Color("#2a5aff"),
	"c144": lipgloss.Color("#1961ff"),
	"c145": lipgloss.Color("#1a61ff"),
	"c146": lipgloss.Color("#1b61ff"),
	"c147": lipgloss.Color("#1b60ff"),
	"c148": lipgloss.Color("#1c60ff"),
	"c149": lipgloss.Color("#006cff"),
	"c150": lipgloss.Color("#016cff"),
	"c151": lipgloss.Color("#026bff"),
	"c152": lipgloss.Color("#036bff"),
	"c153": lipgloss.Color("#8833ff"),
	"c154": lipgloss.Color("#7d37ff"),
	"c155": lipgloss.Color("#723cff"),
	"c156": lipgloss.Color("#4b24ff"),
	"c157": lipgloss.Color("#431fff"),
	"c158": lipgloss.Color("#3a1aff"),
	"c159": lipgloss.Color("#290fff"),
	"c160": lipgloss.Color("#200aff"),
	"c161": lipgloss.Color("#1805ff"),
	"c162": lipgloss.Color("#0043ff"),
	"c163": lipgloss.Color("#0046ff"),
	"c164": lipgloss.Color("#0049ff"),
	"c165": lipgloss.Color("#0054ff"),
	"c166": lipgloss.Color("#002fff"),
	"c167": lipgloss.Color("#004cff"),
	"c168": lipgloss.Color("#0035ff"),
	"c169": lipgloss.Color("#0038ff"),
	"c170": lipgloss.Color("#4520ff"),
	"c171": lipgloss.Color("#3517ff"),
	"c172": lipgloss.Color("#2e12ff"),
	"c173": lipgloss.Color("#1e09ff"),
	"c174": lipgloss.Color("#1705ff"),
	"c175": lipgloss.Color("#0040ff"),
	"c176": lipgloss.Color("#002cff"),
	"c177": lipgloss.Color("#004eff"),
	"c178": lipgloss.Color("#003fff"),
	"c179": lipgloss.Color("#03bcff"),
	"c180": lipgloss.Color("#0030ff"),
	"c181": lipgloss.Color("#03b0ff"),
	"c182": lipgloss.Color("#0183ff"),
	"c183": lipgloss.Color("#912fff"),
	"c184": lipgloss.Color("#932eff"),
	"c185": lipgloss.Color("#952dff"),
	"c186": lipgloss.Color("#962dff"),
	"c187": lipgloss.Color("#00cdcd"),
	"c188": lipgloss.Color("#8136ff"),
	"c189": lipgloss.Color("#8733ff"),
	"c190": lipgloss.Color("#8932ff"),
	"c191": lipgloss.Color("#8a32ff"),
	"c192": lipgloss.Color("#8b32ff"),
	"c193": lipgloss.Color("#8c31ff"),
	"c194": lipgloss.Color("#753bff"),
	"c195": lipgloss.Color("#763aff"),
	"c196": lipgloss.Color("#7c38ff"),
	"c197": lipgloss.Color("#7e37ff"),
	"c198": lipgloss.Color("#7f37ff"),
	"c199": lipgloss.Color("#8036ff"),
	"c200": lipgloss.Color("#6840ff"),
	"c201": lipgloss.Color("#6940ff"),
	"c202": lipgloss.Color("#6a3fff"),
	"c203": lipgloss.Color("#713cff"),
	"c204": lipgloss.Color("#733cff"),
	"c205": lipgloss.Color("#733bff"),
	"c206": lipgloss.Color("#743bff"),
	"c207": lipgloss.Color("#5249ff"),
	"c208": lipgloss.Color("#5349ff"),
	"c209": lipgloss.Color("#474eff"),
	"c210": lipgloss.Color("#484eff"),
	"c211": lipgloss.Color("#3755ff"),
	"c212": lipgloss.Color("#3c53ff"),
	"c213": lipgloss.Color("#295bff"),
	"c214": lipgloss.Color("#2f58ff"),
	"c215": lipgloss.Color("#3058ff"),
	"c216": lipgloss.Color("#3157ff"),
	"c217": lipgloss.Color("#245dff"),
	"c218": lipgloss.Color("#255cff"),
	"c219": lipgloss.Color("#4c24ff"),
	"c220": lipgloss.Color("#942dff"),
	"c221": lipgloss.Color("#7f36ff"),
	"c222": lipgloss.Color("#4d25ff"),
	"c223": lipgloss.Color("#4621ff"),
	"c224": lipgloss.Color("#3f1dff"),
	"c225": lipgloss.Color("#3819ff"),
	"c226": lipgloss.Color("#2b10ff"),
	"c227": lipgloss.Color("#240cff"),
	"c228": lipgloss.Color("#1d08ff"),
	"c229": lipgloss.Color("#205fff"),
	"c230": lipgloss.Color("#1604ff"),
	"c231": lipgloss.Color("#1563ff"),
	"c232": lipgloss.Color("#04c6ff"),
	"c233": lipgloss.Color("#04beff"),
	"c234": lipgloss.Color("#04bfff"),
	"c235": lipgloss.Color("#04c0ff"),
	"c236": lipgloss.Color("#03b8ff"),
	"c237": lipgloss.Color("#03b9ff"),
	"c238": lipgloss.Color("#2c5aff"),
	"c239": lipgloss.Color("#205eff"),
	"c240": lipgloss.Color("#215eff"),
	"c241": lipgloss.Color("#1663ff"),
	"c242": lipgloss.Color("#9e2aff"),
	"c243": lipgloss.Color("#9b2aff"),
	"c244": lipgloss.Color("#972dff"),
	"c245": lipgloss.Color("#922fff"),
	"c246": lipgloss.Color("#9030ff"),
	"c247": lipgloss.Color("#8d31ff"),
	"c248": lipgloss.Color("#8b31ff"),
	"c249": lipgloss.Color("#8832ff"),
	"c250": lipgloss.Color("#8633ff"),
	"c251": lipgloss.Color("#8135ff"),
	"c252": lipgloss.Color("#7d38ff"),
	"c253": lipgloss.Color("#7a38ff"),
	"c254": lipgloss.Color("#783aff"),
	"c255": lipgloss.Color("#753aff"),
	"c256": lipgloss.Color("#713dff"),
	"c257": lipgloss.Color("#02a5ff"),
	"c258": lipgloss.Color("#6e3dff"),
	"c259": lipgloss.Color("#6c3fff"),
	"c260": lipgloss.Color("#6a40ff"),
	"c261": lipgloss.Color("#6542ff"),
	"c262": lipgloss.Color("#029aff"),
	"c263": lipgloss.Color("#6242ff"),
	"c264": lipgloss.Color("#6043ff"),
	"c265": lipgloss.Color("#5b45ff"),
	"c266": lipgloss.Color("#5946ff"),
	"c267": lipgloss.Color("#018fff"),
	"c268": lipgloss.Color("#5748ff"),
	"c269": lipgloss.Color("#5448ff"),
	"c270": lipgloss.Color("#4b4dff"),
	"c271": lipgloss.Color("#464fff"),
	"c272": lipgloss.Color("#4450ff"),
	"c273": lipgloss.Color("#3a53ff"),
	"c274": lipgloss.Color("#3555ff"),
	"c275": lipgloss.Color("#3158ff"),
	"c276": lipgloss.Color("#2e58ff"),
	"c277": lipgloss.Color("#275bff"),
	"c278": lipgloss.Color("#255dff"),
	"c279": lipgloss.Color("#1962ff"),
	"c280": lipgloss.Color("#0f65ff"),
	"c281": lipgloss.Color("#0d66ff"),
	"c282": lipgloss.Color("#046bff"),
	"c283": lipgloss.Color("#04c5ff"),
	"c284": lipgloss.Color("#04c3ff"),
	"c285": lipgloss.Color("#04c1ff"),
	"c286": lipgloss.Color("#03b2ff"),
	"c287": lipgloss.Color("#03b4ff"),
	"c288": lipgloss.Color("#02a3ff"),
	"c289": lipgloss.Color("#02a1ff"),
	"c290": lipgloss.Color("#0194ff"),
	"c291": lipgloss.Color("#0189ff"),
	"c292": lipgloss.Color("#0187ff"),
	"c293": lipgloss.Color("#0081ff"),
	"c294": lipgloss.Color("#007eff"),
	"c295": lipgloss.Color("#007cff"),
	"c296": lipgloss.Color("#007aff"),
	"c297": lipgloss.Color("#1463ff"),
	"c298": lipgloss.Color("#5228ff"),
	"c299": lipgloss.Color("#5128ff"),
	"c300": lipgloss.Color("#4a23ff"),
	"c301": lipgloss.Color("#4923ff"),
	"c302": lipgloss.Color("#421fff"),
	"c303": lipgloss.Color("#3919ff"),
	"c304": lipgloss.Color("#3114ff"),
	"c305": lipgloss.Color("#3014ff"),
	"c306": lipgloss.Color("#2f13ff"),
	"c307": lipgloss.Color("#2c11ff"),
	"c308": lipgloss.Color("#2b11ff"),
	"c309": lipgloss.Color("#2a10ff"),
	"c310": lipgloss.Color("#2910ff"),
	"c311": lipgloss.Color("#280fff"),
	"c312": lipgloss.Color("#270fff"),
	"c313": lipgloss.Color("#270eff"),
	"c314": lipgloss.Color("#250dff"),
	"c315": lipgloss.Color("#240dff"),
	"c316": lipgloss.Color("#230cff"),
	"c317": lipgloss.Color("#220cff"),
	"c318": lipgloss.Color("#1d09ff"),
	"c319": lipgloss.Color("#1c08ff"),
	"c320": lipgloss.Color("#1a07ff"),
	"c321": lipgloss.Color("#1403ff"),
	"c322": lipgloss.Color("#1303ff"),
	"c323": lipgloss.Color("#1202ff"),
	"c324": lipgloss.Color("#1101ff"),
	"c325": lipgloss.Color("#1001ff"),
	"c326": lipgloss.Color("#004d4d"),
}

// Frame represents a single animation frame
type Frame struct {
	Duration time.Duration
	Content  []string
	FgColors map[string]string // Maps "x,y" -> color key
	BgColors map[string]string // Maps "x,y" -> color key
}

// Model is the Bubbletea model for the animation
type Model struct {
	frames            []Frame
	frameIndex        int
	isPlaying         bool
	loop              bool
	width             int
	height            int
	hasDarkBackground bool
}

type tickMsg time.Time

// New creates a new animation model
// Set hasDarkBackground to true for dark terminals, false for light terminals
func New(hasDarkBackground bool) Model {
	return Model{
		frames:            frames,
		frameIndex:        0,
		isPlaying:         true,
		loop:              true,
		width:             60,
		height:            24,
		hasDarkBackground: hasDarkBackground,
	}
}

// NewWithDefaults creates a new animation model with dark background (default)
func NewWithDefaults() Model {
	return New(true)
}

// Init initializes the model
func (m Model) Init() tea.Cmd {
	return m.tick()
}

func (m Model) tick() tea.Cmd {
	if !m.isPlaying || len(m.frames) == 0 {
		return nil
	}
	return tea.Tick(m.frames[m.frameIndex].Duration, func(t time.Time) tea.Msg {
		return tickMsg(t)
	})
}

// Update handles messages
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
	switch msg := msg.(type) {
	case tea.KeyMsg:
		switch msg.String() {
		case "q", "ctrl+c":
			return m, tea.Quit
		}
	case tickMsg:
		if m.isPlaying && len(m.frames) > 0 {
			m.frameIndex++
			if m.frameIndex >= len(m.frames) {
				if m.loop {
					m.frameIndex = 0
				} else {
					m.frameIndex = len(m.frames) - 1
					m.isPlaying = false
					return m, nil
				}
			}
			return m, m.tick()
		}
	}
	return m, nil
}

// getColor returns the appropriate color for the current background mode
func (m Model) getColor(colorKey string) lipgloss.TerminalColor {
	if m.hasDarkBackground {
		return COLORS_DARK[colorKey]
	}
	return COLORS_LIGHT[colorKey]
}

// View renders the animation
func (m Model) View() string {
	if len(m.frames) == 0 {
		return ""
	}
	frame := m.frames[m.frameIndex]
	var sb strings.Builder

	for y, row := range frame.Content {
		// Convert to runes to get character indices (not byte offsets)
		chars := []rune(row)
		for x, ch := range chars {
			key := fmt.Sprintf("%d,%d", x, y)
			style := lipgloss.NewStyle()
			if fgKey, ok := frame.FgColors[key]; ok {
				style = style.Foreground(m.getColor(fgKey))
			}
			if bgKey, ok := frame.BgColors[key]; ok {
				style = style.Background(m.getColor(bgKey))
			}
			sb.WriteString(style.Render(string(ch)))
		}
		if y < len(frame.Content)-1 {
			sb.WriteString("\n")
		}
	}
	return sb.String()
}

// Play starts or resumes the animation
func (m *Model) Play() tea.Cmd {
	m.isPlaying = true
	return m.tick()
}

// Pause stops the animation
func (m *Model) Pause() {
	m.isPlaying = false
}

// Restart resets to the first frame
func (m *Model) Restart() tea.Cmd {
	m.frameIndex = 0
	return m.tick()
}

// IsPlaying returns whether the animation is playing
func (m Model) IsPlaying() bool {
	return m.isPlaying
}

// CurrentFrame returns the current frame index
func (m Model) CurrentFrame() int {
	return m.frameIndex
}

// TotalFrames returns the total number of frames
func (m Model) TotalFrames() int {
	return len(m.frames)
}

// Frame data
var frames = []Frame{
	{
		Duration: 125 * time.Millisecond,
		Content: []string{
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                        ▄▄████████▄▄                        ",
			"                   ▄████████████████████▄                   ",
			"                  ████     █████  ███ ████                  ",
			"                 ███        ████ ███    ██                  ",
			"                 ███        ████████    ██                  ",
			"                 ███       ████████    ███                  ",
			"               ▅█████████████ ██████████████▅               ",
			"             █████  ▀▀▀▀▀▀▀     ▀▀▀▀▀▀▀▀ ██████             ",
			"            ██████        ▟▙    ▟▙       ███████            ",
			"            ██████        ██    ██       ███████            ",
			"            ██████        ██    ██       ███████            ",
			"             █████                       ██████             ",
			"                ████▅                  ▅█████               ",
			"                   ██████████████████████                   ",
			"                         ▀▀▀▀▀▀▀▀▀▀                         ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
		},
		FgColors: map[string]string{
			"24,4": "c0",
			"25,4": "c0",
			"26,4": "c0",
			"27,4": "c0",
			"28,4": "c0",
			"29,4": "c0",
			"30,4": "c0",
			"31,4": "c0",
			"32,4": "c0",
			"33,4": "c0",
			"34,4": "c0",
			"35,4": "c0",
			"19,5": "c1",
			"20,5": "c1",
			"21,5": "c1",
			"22,5": "c1",
			"23,5": "c1",
			"24,5": "c1",
			"25,5": "c1",
			"26,5": "c1",
			"27,5": "c1",
			"28,5": "c1",
			"29,5": "c2",
			"30,5": "c1",
			"31,5": "c1",
			"32,5": "c1",
			"33,5": "c1",
			"34,5": "c1",
			"35,5": "c1",
			"36,5": "c1",
			"37,5": "c1",
			"38,5": "c1",
			"39,5": "c1",
			"40,5": "c1",
			"18,6": "c3",
			"19,6": "c4",
			"20,6": "c4",
			"21,6": "c4",
			"27,6": "c3",
			"28,6": "c4",
			"29,6": "c3",
			"30,6": "c4",
			"31,6": "c4",
			"34,6": "c5",
			"35,6": "c5",
			"36,6": "c5",
			"38,6": "c3",
			"39,6": "c3",
			"40,6": "c4",
			"41,6": "c4",
			"17,7": "c6",
			"18,7": "c6",
			"19,7": "c7",
			"28,7": "c7",
			"29,7": "c6",
			"30,7": "c7",
			"31,7": "c7",
			"33,7": "c5",
			"34,7": "c5",
			"35,7": "c5",
			"40,7": "c6",
			"41,7": "c7",
			"17,8": "c8",
			"18,8": "c8",
			"19,8": "c9",
			"28,8": "c9",
			"29,8": "c8",
			"30,8": "c9",
			"31,8": "c9",
			"32,8": "c5",
			"33,8": "c5",
			"34,8": "c5",
			"35,8": "c5",
			"40,8": "c8",
			"41,8": "c9",
			"17,9": "c8",
			"18,9": "c8",
			"19,9": "c10",
			"27,9": "c10",
			"28,9": "c10",
			"29,9": "c8",
			"30,9": "c10",
			"31,9": "c10",
			"32,9": "c5",
			"33,9": "c5",
			"34,9": "c5",
			"39,9": "c8",
			"40,9": "c10",
			"41,9": "c10",
			"15,10": "c11",
			"16,10": "c12",
			"17,10": "c12",
			"18,10": "c8",
			"19,10": "c8",
			"20,10": "c8",
			"21,10": "c13",
			"22,10": "c13",
			"23,10": "c13",
			"24,10": "c13",
			"25,10": "c13",
			"26,10": "c13",
			"27,10": "c13",
			"28,10": "c8",
			"30,10": "c8",
			"31,10": "c13",
			"32,10": "c13",
			"33,10": "c13",
			"34,10": "c13",
			"35,10": "c13",
			"36,10": "c13",
			"37,10": "c13",
			"38,10": "c13",
			"39,10": "c13",
			"40,10": "c13",
			"41,10": "c11",
			"42,10": "c11",
			"43,10": "c11",
			"44,10": "c11",
			"13,11": "c14",
			"14,11": "c14",
			"15,11": "c14",
			"16,11": "c15",
			"17,11": "c14",
			"20,11": "c8",
			"21,11": "c8",
			"22,11": "c8",
			"23,11": "c8",
			"24,11": "c8",
			"25,11": "c8",
			"26,11": "c8",
			"32,11": "c8",
			"33,11": "c8",
			"34,11": "c8",
			"35,11": "c8",
			"36,11": "c8",
			"37,11": "c8",
			"38,11": "c8",
			"39,11": "c8",
			"41,11": "c14",
			"42,11": "c14",
			"43,11": "c14",
			"44,11": "c14",
			"45,11": "c14",
			"46,11": "c14",
			"12,12": "c16",
			"13,12": "c16",
			"14,12": "c16",
			"15,12": "c16",
			"16,12": "c17",
			"17,12": "c16",
			"26,12": "c18",
			"27,12": "c18",
			"32,12": "c18",
			"33,12": "c18",
			"41,12": "c16",
			"42,12": "c16",
			"43,12": "c16",
			"44,12": "c16",
			"45,12": "c16",
			"46,12": "c16",
			"47,12": "c16",
			"12,13": "c19",
			"13,13": "c20",
			"14,13": "c20",
			"15,13": "c20",
			"16,13": "c19",
			"17,13": "c20",
			"26,13": "c18",
			"27,13": "c18",
			"32,13": "c18",
			"33,13": "c18",
			"41,13": "c20",
			"42,13": "c20",
			"43,13": "c20",
			"44,13": "c20",
			"45,13": "c20",
			"46,13": "c20",
			"47,13": "c20",
			"12,14": "c21",
			"13,14": "c21",
			"14,14": "c21",
			"15,14": "c21",
			"16,14": "c21",
			"17,14": "c22",
			"26,14": "c18",
			"27,14": "c18",
			"32,14": "c18",
			"33,14": "c18",
			"41,14": "c22",
			"42,14": "c21",
			"43,14": "c22",
			"44,14": "c22",
			"45,14": "c22",
			"46,14": "c22",
			"47,14": "c22",
			"13,15": "c23",
			"14,15": "c23",
			"15,15": "c23",
			"16,15": "c23",
			"17,15": "c24",
			"41,15": "c24",
			"42,15": "c23",
			"43,15": "c24",
			"44,15": "c23",
			"45,15": "c23",
			"46,15": "c23",
			"16,16": "c25",
			"17,16": "c26",
			"18,16": "c26",
			"19,16": "c26",
			"20,16": "c26",
			"39,16": "c26",
			"40,16": "c26",
			"41,16": "c26",
			"42,16": "c25",
			"43,16": "c25",
			"44,16": "c25",
			"19,17": "c25",
			"20,17": "c27",
			"21,17": "c27",
			"22,17": "c27",
			"23,17": "c27",
			"24,17": "c27",
			"25,17": "c27",
			"26,17": "c27",
			"27,17": "c27",
			"28,17": "c27",
			"29,17": "c27",
			"30,17": "c27",
			"31,17": "c27",
			"32,17": "c27",
			"33,17": "c27",
			"34,17": "c27",
			"35,17": "c27",
			"36,17": "c27",
			"37,17": "c27",
			"38,17": "c27",
			"39,17": "c27",
			"40,17": "c27",
			"25,18": "c25",
			"26,18": "c25",
			"27,18": "c25",
			"28,18": "c25",
			"29,18": "c25",
			"30,18": "c25",
			"31,18": "c25",
			"32,18": "c25",
			"33,18": "c25",
			"34,18": "c25",
		},
		BgColors: nil,
	},
	{
		Duration: 125 * time.Millisecond,
		Content: []string{
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                        ▄▄████████▄▄                        ",
			"                   ███████████████████                      ",
			"                 ████    ████     ██████                    ",
			"                ██       ████     ██████                    ",
			"               ███      █████    ███ ████                   ",
			"               ███      █████    ███ █████                  ",
			"               ███████████ █████████████████▄               ",
			"             ████  ▀▀▀▀▀     ▀▀▀▀▀▀▀   ███████▄             ",
			"            ████       ▟▙    ▟▙        ███████▐             ",
			"            ████       ██    ██        ███████▐             ",
			"            ████       ██    ██        ███████▐             ",
			"             ████                      ████████             ",
			"               ████                 ████████▀▀              ",
			"                 ██████████████████████                     ",
			"                      ▀▀▀▀▀▀▀▀▀▀▀▀                          ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
		},
		FgColors: map[string]string{
			"24,4": "c28",
			"25,4": "c29",
			"26,4": "c30",
			"27,4": "c30",
			"28,4": "c31",
			"29,4": "c0",
			"30,4": "c0",
			"31,4": "c0",
			"32,4": "c0",
			"33,4": "c0",
			"34,4": "c0",
			"35,4": "c0",
			"19,5": "c1",
			"20,5": "c1",
			"21,5": "c1",
			"22,5": "c1",
			"23,5": "c1",
			"24,5": "c1",
			"25,5": "c1",
			"26,5": "c1",
			"27,5": "c32",
			"28,5": "c1",
			"29,5": "c1",
			"30,5": "c1",
			"31,5": "c1",
			"32,5": "c1",
			"33,5": "c1",
			"34,5": "c1",
			"35,5": "c1",
			"36,5": "c1",
			"37,5": "c1",
			"17,6": "c3",
			"18,6": "c3",
			"19,6": "c3",
			"20,6": "c3",
			"25,6": "c33",
			"26,6": "c33",
			"27,6": "c3",
			"28,6": "c33",
			"34,6": "c3",
			"35,6": "c5",
			"36,6": "c3",
			"37,6": "c33",
			"38,6": "c33",
			"39,6": "c33",
			"16,7": "c6",
			"17,7": "c34",
			"25,7": "c34",
			"26,7": "c34",
			"27,7": "c6",
			"28,7": "c34",
			"34,7": "c5",
			"35,7": "c5",
			"36,7": "c5",
			"37,7": "c6",
			"38,7": "c34",
			"39,7": "c34",
			"15,8": "c8",
			"16,8": "c35",
			"17,8": "c35",
			"24,8": "c35",
			"25,8": "c35",
			"26,8": "c35",
			"27,8": "c8",
			"28,8": "c35",
			"33,8": "c5",
			"34,8": "c5",
			"35,8": "c5",
			"37,8": "c8",
			"38,8": "c35",
			"39,8": "c35",
			"40,8": "c12",
			"15,9": "c8",
			"16,9": "c8",
			"17,9": "c36",
			"24,9": "c36",
			"25,9": "c36",
			"26,9": "c8",
			"27,9": "c36",
			"28,9": "c36",
			"33,9": "c5",
			"34,9": "c5",
			"35,9": "c5",
			"37,9": "c36",
			"38,9": "c36",
			"39,9": "c12",
			"40,9": "c37",
			"41,9": "c38",
			"15,10": "c12",
			"16,10": "c8",
			"17,10": "c8",
			"18,10": "c8",
			"19,10": "c8",
			"20,10": "c39",
			"21,10": "c39",
			"22,10": "c39",
			"23,10": "c39",
			"24,10": "c39",
			"25,10": "c8",
			"27,10": "c8",
			"28,10": "c39",
			"29,10": "c39",
			"30,10": "c39",
			"31,10": "c39",
			"32,10": "c39",
			"33,10": "c39",
			"34,10": "c39",
			"35,10": "c39",
			"36,10": "c39",
			"37,10": "c39",
			"38,10": "c12",
			"39,10": "c40",
			"40,10": "c41",
			"41,10": "c42",
			"42,10": "c43",
			"43,10": "c44",
			"44,10": "c45",
			"13,11": "c46",
			"14,11": "c15",
			"15,11": "c47",
			"16,11": "c47",
			"19,11": "c8",
			"20,11": "c8",
			"21,11": "c8",
			"22,11": "c8",
			"23,11": "c8",
			"29,11": "c8",
			"30,11": "c8",
			"31,11": "c8",
			"32,11": "c8",
			"33,11": "c8",
			"34,11": "c8",
			"35,11": "c8",
			"39,11": "c48",
			"40,11": "c49",
			"41,11": "c50",
			"42,11": "c50",
			"43,11": "c11",
			"44,11": "c51",
			"45,11": "c52",
			"46,11": "c53",
			"12,12": "c17",
			"13,12": "c54",
			"14,12": "c17",
			"15,12": "c20",
			"23,12": "c18",
			"24,12": "c18",
			"29,12": "c18",
			"30,12": "c18",
			"39,12": "c55",
			"40,12": "c56",
			"41,12": "c57",
			"42,12": "c58",
			"43,12": "c59",
			"44,12": "c60",
			"45,12": "c61",
			"46,12": "c17",
			"12,13": "c19",
			"13,13": "c62",
			"14,13": "c19",
			"15,13": "c63",
			"23,13": "c18",
			"24,13": "c18",
			"29,13": "c18",
			"30,13": "c18",
			"39,13": "c64",
			"40,13": "c65",
			"41,13": "c46",
			"42,13": "c16",
			"43,13": "c47",
			"44,13": "c47",
			"45,13": "c66",
			"46,13": "c19",
			"12,14": "c21",
			"13,14": "c21",
			"14,14": "c21",
			"15,14": "c67",
			"23,14": "c18",
			"24,14": "c18",
			"29,14": "c18",
			"30,14": "c18",
			"39,14": "c68",
			"40,14": "c21",
			"41,14": "c54",
			"42,14": "c69",
			"43,14": "c20",
			"44,14": "c70",
			"45,14": "c71",
			"46,14": "c21",
			"13,15": "c23",
			"14,15": "c23",
			"15,15": "c26",
			"16,15": "c72",
			"39,15": "c73",
			"40,15": "c23",
			"41,15": "c62",
			"42,15": "c22",
			"43,15": "c23",
			"44,15": "c23",
			"45,15": "c23",
			"46,15": "c23",
			"15,16": "c25",
			"16,16": "c74",
			"17,16": "c75",
			"18,16": "c76",
			"36,16": "c77",
			"37,16": "c78",
			"38,16": "c79",
			"39,16": "c79",
			"40,16": "c25",
			"41,16": "c25",
			"42,16": "c25",
			"43,16": "c25",
			"44,16": "c25",
			"45,16": "c25",
			"17,17": "c25",
			"18,17": "c25",
			"19,17": "c80",
			"20,17": "c81",
			"21,17": "c82",
			"22,17": "c83",
			"23,17": "c84",
			"24,17": "c85",
			"25,17": "c86",
			"26,17": "c87",
			"27,17": "c87",
			"28,17": "c27",
			"29,17": "c88",
			"30,17": "c74",
			"31,17": "c75",
			"32,17": "c76",
			"33,17": "c76",
			"34,17": "c89",
			"35,17": "c90",
			"36,17": "c91",
			"37,17": "c92",
			"38,17": "c25",
			"22,18": "c25",
			"23,18": "c25",
			"24,18": "c25",
			"25,18": "c25",
			"26,18": "c25",
			"27,18": "c25",
			"28,18": "c25",
			"29,18": "c25",
			"30,18": "c25",
			"31,18": "c25",
			"32,18": "c25",
			"33,18": "c25",
		},
		BgColors: nil,
	},
	{
		Duration: 125 * time.Millisecond,
		Content: []string{
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                       ▄▄█████████▄                         ",
			"                 ▐███████████████████                       ",
			"                ██  ████      █████████                     ",
			"               █   ████        ██████████                   ",
			"              █    ████       ████████████                  ",
			"             ██   █████      █████████████                  ",
			"             ███████████████████████████████▄               ",
			"              ▀▀▀▀    ▀▀▀▀▀▀▀     ██████████▀█              ",
			"              ▐   █    █▙         █████████▌  ▌             ",
			"              █   █    ██         █████████▌  ▌             ",
			"              █   █    ██         ██████████ ▐              ",
			"              █                  █████████████              ",
			"               █              █████████████                 ",
			"                ██████████████████████                      ",
			"                  ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀                           ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
		},
		FgColors: map[string]string{
			"23,4": "c93",
			"24,4": "c28",
			"25,4": "c29",
			"26,4": "c30",
			"27,4": "c30",
			"28,4": "c31",
			"29,4": "c0",
			"30,4": "c0",
			"31,4": "c0",
			"32,4": "c0",
			"33,4": "c0",
			"34,4": "c0",
			"17,5": "c94",
			"18,5": "c94",
			"19,5": "c1",
			"20,5": "c1",
			"21,5": "c1",
			"22,5": "c1",
			"23,5": "c1",
			"24,5": "c1",
			"25,5": "c1",
			"26,5": "c1",
			"27,5": "c1",
			"28,5": "c1",
			"29,5": "c1",
			"30,5": "c1",
			"31,5": "c1",
			"32,5": "c1",
			"33,5": "c95",
			"34,5": "c96",
			"35,5": "c97",
			"36,5": "c98",
			"16,6": "c3",
			"17,6": "c3",
			"20,6": "c4",
			"21,6": "c3",
			"22,6": "c4",
			"23,6": "c3",
			"30,6": "c3",
			"31,6": "c3",
			"32,6": "c4",
			"33,6": "c4",
			"34,6": "c4",
			"35,6": "c99",
			"36,6": "c100",
			"37,6": "c101",
			"38,6": "c102",
			"15,7": "c7",
			"19,7": "c6",
			"20,7": "c6",
			"21,7": "c7",
			"22,7": "c7",
			"32,7": "c7",
			"33,7": "c7",
			"34,7": "c12",
			"35,7": "c103",
			"36,7": "c104",
			"37,7": "c105",
			"38,7": "c106",
			"39,7": "c107",
			"40,7": "c108",
			"14,8": "c9",
			"19,8": "c8",
			"20,8": "c9",
			"21,8": "c9",
			"22,8": "c8",
			"31,8": "c9",
			"32,8": "c9",
			"33,8": "c9",
			"34,8": "c12",
			"35,8": "c109",
			"36,8": "c109",
			"37,8": "c110",
			"38,8": "c111",
			"39,8": "c112",
			"40,8": "c113",
			"41,8": "c113",
			"13,9": "c10",
			"14,9": "c10",
			"18,9": "c8",
			"19,9": "c8",
			"20,9": "c8",
			"21,9": "c8",
			"22,9": "c10",
			"30,9": "c10",
			"31,9": "c10",
			"32,9": "c10",
			"33,9": "c12",
			"34,9": "c114",
			"35,9": "c114",
			"36,9": "c115",
			"37,9": "c116",
			"38,9": "c117",
			"39,9": "c37",
			"40,9": "c37",
			"41,9": "c38",
			"13,10": "c8",
			"14,10": "c8",
			"15,10": "c8",
			"16,10": "c8",
			"17,10": "c8",
			"18,10": "c8",
			"19,10": "c8",
			"20,10": "c8",
			"21,10": "c8",
			"22,10": "c13",
			"23,10": "c13",
			"24,10": "c13",
			"25,10": "c13",
			"26,10": "c13",
			"27,10": "c13",
			"28,10": "c13",
			"29,10": "c13",
			"30,10": "c13",
			"31,10": "c12",
			"32,10": "c12",
			"33,10": "c118",
			"34,10": "c119",
			"35,10": "c120",
			"36,10": "c121",
			"37,10": "c122",
			"38,10": "c122",
			"39,10": "c40",
			"40,10": "c41",
			"41,10": "c42",
			"42,10": "c43",
			"43,10": "c44",
			"44,10": "c45",
			"14,11": "c8",
			"15,11": "c8",
			"16,11": "c8",
			"17,11": "c8",
			"22,11": "c8",
			"23,11": "c8",
			"24,11": "c8",
			"25,11": "c8",
			"26,11": "c8",
			"27,11": "c8",
			"28,11": "c8",
			"34,11": "c123",
			"35,11": "c124",
			"36,11": "c125",
			"37,11": "c125",
			"38,11": "c126",
			"39,11": "c48",
			"40,11": "c49",
			"41,11": "c50",
			"42,11": "c50",
			"43,11": "c11",
			"44,11": "c12",
			"45,11": "c12",
			"14,12": "c12",
			"18,12": "c18",
			"23,12": "c18",
			"24,12": "c18",
			"34,12": "c127",
			"35,12": "c127",
			"36,12": "c128",
			"37,12": "c129",
			"38,12": "c130",
			"39,12": "c55",
			"40,12": "c56",
			"41,12": "c57",
			"42,12": "c58",
			"43,12": "c12",
			"46,12": "c12",
			"14,13": "c15",
			"18,13": "c18",
			"23,13": "c18",
			"24,13": "c18",
			"34,13": "c131",
			"35,13": "c132",
			"36,13": "c133",
			"37,13": "c134",
			"38,13": "c135",
			"39,13": "c64",
			"40,13": "c65",
			"41,13": "c46",
			"42,13": "c16",
			"43,13": "c15",
			"46,13": "c15",
			"14,14": "c17",
			"18,14": "c18",
			"23,14": "c18",
			"24,14": "c18",
			"34,14": "c136",
			"35,14": "c137",
			"36,14": "c17",
			"37,14": "c138",
			"38,14": "c139",
			"39,14": "c68",
			"40,14": "c17",
			"41,14": "c17",
			"42,14": "c17",
			"43,14": "c17",
			"45,14": "c17",
			"14,15": "c19",
			"33,15": "c140",
			"34,15": "c141",
			"35,15": "c142",
			"36,15": "c19",
			"37,15": "c19",
			"38,15": "c143",
			"39,15": "c19",
			"40,15": "c19",
			"41,15": "c19",
			"42,15": "c19",
			"43,15": "c19",
			"44,15": "c19",
			"45,15": "c19",
			"15,16": "c21",
			"30,16": "c72",
			"31,16": "c144",
			"32,16": "c145",
			"33,16": "c146",
			"34,16": "c147",
			"35,16": "c148",
			"36,16": "c21",
			"37,16": "c21",
			"38,16": "c21",
			"39,16": "c21",
			"40,16": "c21",
			"41,16": "c21",
			"42,16": "c21",
			"16,17": "c23",
			"17,17": "c23",
			"18,17": "c23",
			"19,17": "c80",
			"20,17": "c81",
			"21,17": "c82",
			"22,17": "c83",
			"23,17": "c84",
			"24,17": "c85",
			"25,17": "c86",
			"26,17": "c87",
			"27,17": "c87",
			"28,17": "c27",
			"29,17": "c88",
			"30,17": "c74",
			"31,17": "c75",
			"32,17": "c76",
			"33,17": "c76",
			"34,17": "c89",
			"35,17": "c23",
			"36,17": "c23",
			"37,17": "c23",
			"18,18": "c25",
			"19,18": "c25",
			"20,18": "c25",
			"21,18": "c25",
			"22,18": "c25",
			"23,18": "c25",
			"24,18": "c149",
			"25,18": "c149",
			"26,18": "c149",
			"27,18": "c149",
			"28,18": "c149",
			"29,18": "c150",
			"30,18": "c151",
			"31,18": "c151",
			"32,18": "c152",
		},
		BgColors: nil,
	},
	{
		Duration: 125 * time.Millisecond,
		Content: []string{
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                       ▄▄█████████▄▄                        ",
			"                  ████████████████████▄                     ",
			"                ██████      █████████████                   ",
			"               █ ████       ██████████████                  ",
			"              █  ███       ████████████████                 ",
			"             ██ ████      █████████████████                 ",
			"             ███████████████████████████████                ",
			"              ▀▀▀  ▀▀▀▀▀▀      ███████████▀█▌               ",
			"               ▌█   █▙         ██████████   █               ",
			"               ▌█   ██         █████████    █               ",
			"               ▌█   ██         ██████████   ▌               ",
			"               ▌              ██████████████                ",
			"               █            ██████████████                  ",
			"                █████████████████████                       ",
			"                 ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀                           ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
		},
		FgColors: map[string]string{
			"23,4": "c0",
			"24,4": "c0",
			"25,4": "c0",
			"26,4": "c0",
			"27,4": "c0",
			"28,4": "c0",
			"29,4": "c0",
			"30,4": "c0",
			"31,4": "c0",
			"32,4": "c0",
			"33,4": "c0",
			"34,4": "c0",
			"35,4": "c0",
			"18,5": "c94",
			"19,5": "c94",
			"20,5": "c1",
			"21,5": "c1",
			"22,5": "c1",
			"23,5": "c1",
			"24,5": "c1",
			"25,5": "c1",
			"26,5": "c1",
			"27,5": "c1",
			"28,5": "c1",
			"29,5": "c1",
			"30,5": "c1",
			"31,5": "c2",
			"32,5": "c2",
			"33,5": "c2",
			"34,5": "c2",
			"35,5": "c2",
			"36,5": "c2",
			"37,5": "c2",
			"38,5": "c2",
			"16,6": "c3",
			"17,6": "c3",
			"18,6": "c3",
			"19,6": "c4",
			"20,6": "c3",
			"21,6": "c3",
			"28,6": "c3",
			"29,6": "c4",
			"30,6": "c4",
			"31,6": "c4",
			"32,6": "c153",
			"33,6": "c153",
			"34,6": "c153",
			"35,6": "c153",
			"36,6": "c153",
			"37,6": "c153",
			"38,6": "c153",
			"39,6": "c153",
			"40,6": "c153",
			"15,7": "c7",
			"17,7": "c6",
			"18,7": "c7",
			"19,7": "c6",
			"20,7": "c7",
			"28,7": "c7",
			"29,7": "c7",
			"30,7": "c7",
			"31,7": "c154",
			"32,7": "c154",
			"33,7": "c154",
			"34,7": "c154",
			"35,7": "c154",
			"36,7": "c154",
			"37,7": "c154",
			"38,7": "c154",
			"39,7": "c154",
			"40,7": "c154",
			"41,7": "c154",
			"14,8": "c9",
			"17,8": "c9",
			"18,8": "c8",
			"19,8": "c9",
			"27,8": "c8",
			"28,8": "c9",
			"29,8": "c9",
			"30,8": "c8",
			"31,8": "c155",
			"32,8": "c155",
			"33,8": "c155",
			"34,8": "c155",
			"35,8": "c155",
			"36,8": "c155",
			"37,8": "c155",
			"38,8": "c155",
			"39,8": "c155",
			"40,8": "c155",
			"41,8": "c155",
			"42,8": "c155",
			"13,9": "c10",
			"14,9": "c10",
			"16,9": "c8",
			"17,9": "c8",
			"18,9": "c8",
			"19,9": "c10",
			"26,9": "c10",
			"27,9": "c10",
			"28,9": "c10",
			"29,9": "c8",
			"30,9": "c43",
			"31,9": "c43",
			"32,9": "c43",
			"33,9": "c43",
			"34,9": "c43",
			"35,9": "c43",
			"36,9": "c43",
			"37,9": "c43",
			"38,9": "c43",
			"39,9": "c43",
			"40,9": "c43",
			"41,9": "c43",
			"42,9": "c43",
			"13,10": "c13",
			"14,10": "c8",
			"15,10": "c8",
			"16,10": "c8",
			"17,10": "c8",
			"18,10": "c8",
			"19,10": "c8",
			"20,10": "c8",
			"21,10": "c8",
			"22,10": "c8",
			"23,10": "c8",
			"24,10": "c13",
			"25,10": "c13",
			"26,10": "c13",
			"27,10": "c8",
			"28,10": "c12",
			"29,10": "c12",
			"30,10": "c11",
			"31,10": "c11",
			"32,10": "c11",
			"33,10": "c11",
			"34,10": "c11",
			"35,10": "c11",
			"36,10": "c11",
			"37,10": "c11",
			"38,10": "c11",
			"39,10": "c11",
			"40,10": "c11",
			"41,10": "c11",
			"42,10": "c11",
			"43,10": "c11",
			"14,11": "c8",
			"15,11": "c8",
			"16,11": "c8",
			"19,11": "c8",
			"20,11": "c8",
			"21,11": "c8",
			"22,11": "c8",
			"23,11": "c8",
			"24,11": "c8",
			"31,11": "c14",
			"32,11": "c14",
			"33,11": "c14",
			"34,11": "c14",
			"35,11": "c14",
			"36,11": "c14",
			"37,11": "c14",
			"38,11": "c14",
			"39,11": "c14",
			"40,11": "c14",
			"41,11": "c14",
			"42,11": "c156",
			"43,11": "c14",
			"44,11": "c156",
			"15,12": "c157",
			"16,12": "c18",
			"20,12": "c18",
			"21,12": "c18",
			"31,12": "c16",
			"32,12": "c16",
			"33,12": "c16",
			"34,12": "c16",
			"35,12": "c16",
			"36,12": "c16",
			"37,12": "c16",
			"38,12": "c16",
			"39,12": "c16",
			"40,12": "c157",
			"44,12": "c16",
			"15,13": "c158",
			"16,13": "c18",
			"20,13": "c18",
			"21,13": "c18",
			"31,13": "c20",
			"32,13": "c20",
			"33,13": "c20",
			"34,13": "c20",
			"35,13": "c20",
			"36,13": "c20",
			"37,13": "c20",
			"38,13": "c20",
			"39,13": "c20",
			"44,13": "c20",
			"15,14": "c19",
			"16,14": "c18",
			"20,14": "c18",
			"21,14": "c18",
			"31,14": "c22",
			"32,14": "c22",
			"33,14": "c19",
			"34,14": "c22",
			"35,14": "c22",
			"36,14": "c22",
			"37,14": "c22",
			"38,14": "c19",
			"39,14": "c19",
			"40,14": "c19",
			"44,14": "c19",
			"15,15": "c159",
			"30,15": "c24",
			"31,15": "c24",
			"32,15": "c24",
			"33,15": "c159",
			"34,15": "c159",
			"35,15": "c24",
			"36,15": "c159",
			"37,15": "c159",
			"38,15": "c159",
			"39,15": "c159",
			"40,15": "c159",
			"41,15": "c159",
			"42,15": "c159",
			"43,15": "c159",
			"15,16": "c160",
			"28,16": "c26",
			"29,16": "c26",
			"30,16": "c26",
			"31,16": "c26",
			"32,16": "c26",
			"33,16": "c160",
			"34,16": "c160",
			"35,16": "c160",
			"36,16": "c160",
			"37,16": "c160",
			"38,16": "c160",
			"39,16": "c160",
			"40,16": "c160",
			"41,16": "c160",
			"16,17": "c161",
			"17,17": "c161",
			"18,17": "c161",
			"19,17": "c161",
			"20,17": "c27",
			"21,17": "c27",
			"22,17": "c27",
			"23,17": "c27",
			"24,17": "c27",
			"25,17": "c27",
			"26,17": "c27",
			"27,17": "c27",
			"28,17": "c27",
			"29,17": "c27",
			"30,17": "c27",
			"31,17": "c27",
			"32,17": "c27",
			"33,17": "c161",
			"34,17": "c161",
			"35,17": "c161",
			"36,17": "c161",
			"17,18": "c25",
			"18,18": "c25",
			"19,18": "c25",
			"20,18": "c25",
			"21,18": "c25",
			"22,18": "c25",
			"23,18": "c25",
			"24,18": "c149",
			"25,18": "c149",
			"26,18": "c149",
			"27,18": "c149",
			"28,18": "c149",
			"29,18": "c149",
			"30,18": "c149",
			"31,18": "c149",
			"32,18": "c149",
		},
		BgColors: nil,
	},
	{
		Duration: 125 * time.Millisecond,
		Content: []string{
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                        ▄▄████████▄▄                        ",
			"                  ████████████████████▄▄                    ",
			"                ███   ███████████████████                   ",
			"               ███    ████████████████████                  ",
			"               ██    ██████████████████████                 ",
			"              ██    ████████████████████████                ",
			"              ███████▀   ███████████████████                ",
			"              ▀███▀      █████████▀▀▀███████                ",
			"               ▐▄        ████████     ██████                ",
			"               ▐█        ████████     █████                 ",
			"               ▐█        █████████   █████                  ",
			"               ▐         ███████████████                    ",
			"               ▐      █████████████████                     ",
			"                ███████████████████                         ",
			"                 ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
		},
		FgColors: map[string]string{
			"24,4": "c0",
			"25,4": "c0",
			"26,4": "c0",
			"27,4": "c0",
			"28,4": "c0",
			"29,4": "c0",
			"30,4": "c0",
			"31,4": "c0",
			"32,4": "c0",
			"33,4": "c0",
			"34,4": "c0",
			"35,4": "c0",
			"18,5": "c1",
			"19,5": "c94",
			"20,5": "c1",
			"21,5": "c1",
			"22,5": "c1",
			"23,5": "c1",
			"24,5": "c1",
			"25,5": "c2",
			"26,5": "c2",
			"27,5": "c2",
			"28,5": "c2",
			"29,5": "c2",
			"30,5": "c2",
			"31,5": "c2",
			"32,5": "c2",
			"33,5": "c2",
			"34,5": "c2",
			"35,5": "c2",
			"36,5": "c2",
			"37,5": "c2",
			"38,5": "c2",
			"39,5": "c2",
			"16,6": "c162",
			"17,6": "c163",
			"18,6": "c164",
			"22,6": "c165",
			"23,6": "c33",
			"24,6": "c33",
			"25,6": "c33",
			"26,6": "c12",
			"27,6": "c153",
			"28,6": "c153",
			"29,6": "c153",
			"30,6": "c153",
			"31,6": "c153",
			"32,6": "c153",
			"33,6": "c153",
			"34,6": "c153",
			"35,6": "c153",
			"36,6": "c153",
			"37,6": "c153",
			"38,6": "c153",
			"39,6": "c153",
			"40,6": "c153",
			"15,7": "c166",
			"16,7": "c34",
			"17,7": "c34",
			"22,7": "c34",
			"23,7": "c34",
			"24,7": "c34",
			"25,7": "c167",
			"26,7": "c12",
			"27,7": "c154",
			"28,7": "c154",
			"29,7": "c154",
			"30,7": "c154",
			"31,7": "c154",
			"32,7": "c154",
			"33,7": "c154",
			"34,7": "c154",
			"35,7": "c154",
			"36,7": "c154",
			"37,7": "c154",
			"38,7": "c154",
			"39,7": "c154",
			"40,7": "c154",
			"41,7": "c154",
			"15,8": "c35",
			"16,8": "c35",
			"21,8": "c35",
			"22,8": "c35",
			"23,8": "c168",
			"24,8": "c169",
			"25,8": "c12",
			"26,8": "c155",
			"27,8": "c155",
			"28,8": "c155",
			"29,8": "c155",
			"30,8": "c155",
			"31,8": "c155",
			"32,8": "c155",
			"33,8": "c155",
			"34,8": "c155",
			"35,8": "c155",
			"36,8": "c155",
			"37,8": "c155",
			"38,8": "c155",
			"39,8": "c155",
			"40,8": "c155",
			"41,8": "c155",
			"42,8": "c155",
			"14,9": "c8",
			"15,9": "c36",
			"20,9": "c8",
			"21,9": "c36",
			"22,9": "c8",
			"23,9": "c8",
			"24,9": "c12",
			"25,9": "c43",
			"26,9": "c43",
			"27,9": "c43",
			"28,9": "c43",
			"29,9": "c43",
			"30,9": "c43",
			"31,9": "c43",
			"32,9": "c43",
			"33,9": "c43",
			"34,9": "c43",
			"35,9": "c43",
			"36,9": "c43",
			"37,9": "c43",
			"38,9": "c43",
			"39,9": "c43",
			"40,9": "c43",
			"41,9": "c43",
			"42,9": "c43",
			"43,9": "c43",
			"14,10": "c8",
			"15,10": "c8",
			"16,10": "c8",
			"17,10": "c8",
			"18,10": "c8",
			"19,10": "c8",
			"20,10": "c8",
			"21,10": "c8",
			"25,10": "c11",
			"26,10": "c11",
			"27,10": "c11",
			"28,10": "c11",
			"29,10": "c11",
			"30,10": "c11",
			"31,10": "c11",
			"32,10": "c11",
			"33,10": "c11",
			"34,10": "c11",
			"35,10": "c11",
			"36,10": "c11",
			"37,10": "c11",
			"38,10": "c11",
			"39,10": "c11",
			"40,10": "c11",
			"41,10": "c11",
			"42,10": "c11",
			"43,10": "c11",
			"14,11": "c8",
			"15,11": "c8",
			"16,11": "c8",
			"17,11": "c8",
			"18,11": "c8",
			"25,11": "c14",
			"26,11": "c14",
			"27,11": "c14",
			"28,11": "c14",
			"29,11": "c14",
			"30,11": "c14",
			"31,11": "c14",
			"32,11": "c14",
			"33,11": "c14",
			"34,11": "c170",
			"35,11": "c170",
			"36,11": "c170",
			"37,11": "c14",
			"38,11": "c14",
			"39,11": "c14",
			"40,11": "c14",
			"41,11": "c14",
			"42,11": "c14",
			"43,11": "c14",
			"15,12": "c17",
			"16,12": "c18",
			"25,12": "c16",
			"26,12": "c16",
			"27,12": "c16",
			"28,12": "c16",
			"29,12": "c16",
			"30,12": "c16",
			"31,12": "c16",
			"32,12": "c16",
			"38,12": "c16",
			"39,12": "c16",
			"40,12": "c16",
			"41,12": "c16",
			"42,12": "c16",
			"43,12": "c17",
			"15,13": "c171",
			"16,13": "c18",
			"25,13": "c20",
			"26,13": "c20",
			"27,13": "c171",
			"28,13": "c20",
			"29,13": "c20",
			"30,13": "c20",
			"31,13": "c20",
			"32,13": "c171",
			"38,13": "c20",
			"39,13": "c20",
			"40,13": "c171",
			"41,13": "c171",
			"42,13": "c171",
			"15,14": "c172",
			"16,14": "c18",
			"25,14": "c22",
			"26,14": "c22",
			"27,14": "c172",
			"28,14": "c172",
			"29,14": "c22",
			"30,14": "c172",
			"31,14": "c172",
			"32,14": "c172",
			"33,14": "c172",
			"37,14": "c172",
			"38,14": "c22",
			"39,14": "c172",
			"40,14": "c172",
			"41,14": "c172",
			"15,15": "c21",
			"25,15": "c24",
			"26,15": "c24",
			"27,15": "c21",
			"28,15": "c21",
			"29,15": "c21",
			"30,15": "c21",
			"31,15": "c21",
			"32,15": "c21",
			"33,15": "c21",
			"34,15": "c21",
			"35,15": "c21",
			"36,15": "c21",
			"37,15": "c21",
			"38,15": "c21",
			"39,15": "c21",
			"15,16": "c173",
			"22,16": "c173",
			"23,16": "c26",
			"24,16": "c26",
			"25,16": "c26",
			"26,16": "c26",
			"27,16": "c173",
			"28,16": "c173",
			"29,16": "c173",
			"30,16": "c173",
			"31,16": "c173",
			"32,16": "c173",
			"33,16": "c173",
			"34,16": "c173",
			"35,16": "c173",
			"36,16": "c173",
			"37,16": "c173",
			"38,16": "c173",
			"16,17": "c174",
			"17,17": "c174",
			"18,17": "c174",
			"19,17": "c174",
			"20,17": "c174",
			"21,17": "c174",
			"22,17": "c27",
			"23,17": "c27",
			"24,17": "c27",
			"25,17": "c27",
			"26,17": "c174",
			"27,17": "c174",
			"28,17": "c174",
			"29,17": "c174",
			"30,17": "c174",
			"31,17": "c174",
			"32,17": "c174",
			"33,17": "c174",
			"34,17": "c174",
			"17,18": "c25",
			"18,18": "c25",
			"19,18": "c25",
			"20,18": "c25",
			"21,18": "c25",
			"22,18": "c25",
			"23,18": "c25",
			"24,18": "c25",
			"25,18": "c25",
			"26,18": "c25",
			"27,18": "c25",
			"28,18": "c25",
			"29,18": "c25",
			"30,18": "c25",
			"31,18": "c25",
		},
		BgColors: nil,
	},
	{
		Duration: 125 * time.Millisecond,
		Content: []string{
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                         ▄████████▄                         ",
			"                  ████████████████████▄                     ",
			"                ██  █████████████████████                   ",
			"               ██  ███████████████████████                  ",
			"              ██  █████████████████████████                 ",
			"             ▐█  ███████████████████████████                ",
			"             ▐██████  ██████████████████████                ",
			"              ████    ████████▀▀▀▀██████████                ",
			"               ▄      ███████      █████████                ",
			"               █      ███████      ████████                 ",
			"               █      ████████    ████████                  ",
			"               ▌      ███████████████████                   ",
			"               ▐    ███████████████████                     ",
			"                ██████████████████                          ",
			"                 ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
		},
		FgColors: map[string]string{
			"25,4": "c0",
			"26,4": "c0",
			"27,4": "c0",
			"28,4": "c0",
			"29,4": "c0",
			"30,4": "c0",
			"31,4": "c0",
			"32,4": "c0",
			"33,4": "c0",
			"34,4": "c0",
			"18,5": "c94",
			"19,5": "c94",
			"20,5": "c1",
			"21,5": "c1",
			"22,5": "c1",
			"23,5": "c2",
			"24,5": "c2",
			"25,5": "c2",
			"26,5": "c2",
			"27,5": "c2",
			"28,5": "c2",
			"29,5": "c2",
			"30,5": "c2",
			"31,5": "c2",
			"32,5": "c2",
			"33,5": "c2",
			"34,5": "c2",
			"35,5": "c2",
			"36,5": "c2",
			"37,5": "c2",
			"38,5": "c2",
			"16,6": "c164",
			"17,6": "c167",
			"20,6": "c33",
			"21,6": "c33",
			"22,6": "c33",
			"23,6": "c33",
			"24,6": "c12",
			"25,6": "c153",
			"26,6": "c153",
			"27,6": "c153",
			"28,6": "c153",
			"29,6": "c153",
			"30,6": "c153",
			"31,6": "c153",
			"32,6": "c153",
			"33,6": "c153",
			"34,6": "c153",
			"35,6": "c153",
			"36,6": "c153",
			"37,6": "c153",
			"38,6": "c153",
			"39,6": "c153",
			"40,6": "c12",
			"15,7": "c34",
			"16,7": "c34",
			"19,7": "c175",
			"20,7": "c34",
			"21,7": "c34",
			"22,7": "c164",
			"23,7": "c12",
			"24,7": "c154",
			"25,7": "c154",
			"26,7": "c154",
			"27,7": "c154",
			"28,7": "c154",
			"29,7": "c154",
			"30,7": "c154",
			"31,7": "c154",
			"32,7": "c154",
			"33,7": "c154",
			"34,7": "c154",
			"35,7": "c154",
			"36,7": "c154",
			"37,7": "c154",
			"38,7": "c154",
			"39,7": "c154",
			"40,7": "c154",
			"41,7": "c154",
			"14,8": "c8",
			"15,8": "c35",
			"18,8": "c176",
			"19,8": "c166",
			"20,8": "c35",
			"21,8": "c168",
			"22,8": "c12",
			"23,8": "c155",
			"24,8": "c155",
			"25,8": "c155",
			"26,8": "c155",
			"27,8": "c155",
			"28,8": "c155",
			"29,8": "c155",
			"30,8": "c155",
			"31,8": "c155",
			"32,8": "c155",
			"33,8": "c155",
			"34,8": "c155",
			"35,8": "c155",
			"36,8": "c155",
			"37,8": "c155",
			"38,8": "c155",
			"39,8": "c155",
			"40,8": "c155",
			"41,8": "c155",
			"42,8": "c155",
			"13,9": "c8",
			"14,9": "c36",
			"17,9": "c8",
			"18,9": "c8",
			"19,9": "c8",
			"20,9": "c8",
			"21,9": "c12",
			"22,9": "c43",
			"23,9": "c43",
			"24,9": "c43",
			"25,9": "c43",
			"26,9": "c43",
			"27,9": "c43",
			"28,9": "c43",
			"29,9": "c43",
			"30,9": "c43",
			"31,9": "c43",
			"32,9": "c43",
			"33,9": "c43",
			"34,9": "c43",
			"35,9": "c43",
			"36,9": "c43",
			"37,9": "c43",
			"38,9": "c43",
			"39,9": "c43",
			"40,9": "c43",
			"41,9": "c43",
			"42,9": "c43",
			"43,9": "c43",
			"13,10": "c8",
			"14,10": "c8",
			"15,10": "c8",
			"16,10": "c8",
			"17,10": "c8",
			"18,10": "c8",
			"19,10": "c8",
			"22,10": "c11",
			"23,10": "c11",
			"24,10": "c11",
			"25,10": "c11",
			"26,10": "c11",
			"27,10": "c11",
			"28,10": "c11",
			"29,10": "c11",
			"30,10": "c11",
			"31,10": "c11",
			"32,10": "c11",
			"33,10": "c11",
			"34,10": "c11",
			"35,10": "c11",
			"36,10": "c11",
			"37,10": "c11",
			"38,10": "c11",
			"39,10": "c11",
			"40,10": "c11",
			"41,10": "c11",
			"42,10": "c11",
			"43,10": "c11",
			"14,11": "c8",
			"15,11": "c8",
			"16,11": "c8",
			"17,11": "c8",
			"22,11": "c14",
			"23,11": "c14",
			"24,11": "c14",
			"25,11": "c14",
			"26,11": "c14",
			"27,11": "c14",
			"28,11": "c14",
			"29,11": "c14",
			"30,11": "c170",
			"31,11": "c170",
			"32,11": "c170",
			"33,11": "c170",
			"34,11": "c14",
			"35,11": "c14",
			"36,11": "c14",
			"37,11": "c14",
			"38,11": "c14",
			"39,11": "c14",
			"40,11": "c14",
			"41,11": "c14",
			"42,11": "c14",
			"43,11": "c14",
			"15,12": "c18",
			"22,12": "c16",
			"23,12": "c16",
			"24,12": "c16",
			"25,12": "c16",
			"26,12": "c16",
			"27,12": "c16",
			"28,12": "c16",
			"35,12": "c16",
			"36,12": "c16",
			"37,12": "c16",
			"38,12": "c16",
			"39,12": "c16",
			"40,12": "c16",
			"41,12": "c16",
			"42,12": "c16",
			"43,12": "c17",
			"15,13": "c18",
			"22,13": "c20",
			"23,13": "c20",
			"24,13": "c171",
			"25,13": "c171",
			"26,13": "c20",
			"27,13": "c20",
			"28,13": "c20",
			"35,13": "c20",
			"36,13": "c20",
			"37,13": "c20",
			"38,13": "c20",
			"39,13": "c20",
			"40,13": "c20",
			"41,13": "c20",
			"42,13": "c171",
			"15,14": "c18",
			"22,14": "c22",
			"23,14": "c22",
			"24,14": "c172",
			"25,14": "c172",
			"26,14": "c172",
			"27,14": "c172",
			"28,14": "c22",
			"29,14": "c22",
			"34,14": "c22",
			"35,14": "c22",
			"36,14": "c22",
			"37,14": "c172",
			"38,14": "c22",
			"39,14": "c22",
			"40,14": "c22",
			"41,14": "c172",
			"15,15": "c21",
			"22,15": "c24",
			"23,15": "c24",
			"24,15": "c21",
			"25,15": "c21",
			"26,15": "c21",
			"27,15": "c21",
			"28,15": "c21",
			"29,15": "c21",
			"30,15": "c21",
			"31,15": "c21",
			"32,15": "c21",
			"33,15": "c21",
			"34,15": "c21",
			"35,15": "c21",
			"36,15": "c21",
			"37,15": "c24",
			"38,15": "c24",
			"39,15": "c21",
			"40,15": "c21",
			"15,16": "c173",
			"20,16": "c173",
			"21,16": "c173",
			"22,16": "c26",
			"23,16": "c26",
			"24,16": "c173",
			"25,16": "c173",
			"26,16": "c173",
			"27,16": "c173",
			"28,16": "c173",
			"29,16": "c173",
			"30,16": "c173",
			"31,16": "c173",
			"32,16": "c173",
			"33,16": "c173",
			"34,16": "c173",
			"35,16": "c173",
			"36,16": "c173",
			"37,16": "c173",
			"38,16": "c173",
			"16,17": "c27",
			"17,17": "c174",
			"18,17": "c174",
			"19,17": "c174",
			"20,17": "c174",
			"21,17": "c27",
			"22,17": "c27",
			"23,17": "c174",
			"24,17": "c174",
			"25,17": "c174",
			"26,17": "c174",
			"27,17": "c174",
			"28,17": "c174",
			"29,17": "c174",
			"30,17": "c174",
			"31,17": "c174",
			"32,17": "c174",
			"33,17": "c174",
			"17,18": "c25",
			"18,18": "c25",
			"19,18": "c25",
			"20,18": "c25",
			"21,18": "c25",
			"22,18": "c25",
			"23,18": "c25",
			"24,18": "c25",
			"25,18": "c25",
			"26,18": "c25",
			"27,18": "c25",
			"28,18": "c25",
			"29,18": "c25",
			"30,18": "c25",
			"31,18": "c25",
		},
		BgColors: nil,
	},
	{
		Duration: 125 * time.Millisecond,
		Content: []string{
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                        ▄▄████████▄                         ",
			"                  ████████████████████▄                     ",
			"                 ████████████████████████                   ",
			"                ██████████████████████████                  ",
			"               ████████████████████████████                 ",
			"              ██████████████████████████████                ",
			"              ██████████████████████████████                ",
			"              ███ █████▀▀▀██████████████████                ",
			"                ▌ ████     █████████████████                ",
			"                ▌█████     ███████████████                  ",
			"                ▌██████   ███████████████                   ",
			"                ▌███████████████████████                    ",
			"                ▌███████████████████████                    ",
			"                ███████████████████                         ",
			"                 ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
		},
		FgColors: map[string]string{
			"24,4": "c0",
			"25,4": "c0",
			"26,4": "c0",
			"27,4": "c0",
			"28,4": "c0",
			"29,4": "c0",
			"30,4": "c0",
			"31,4": "c0",
			"32,4": "c0",
			"33,4": "c0",
			"34,4": "c0",
			"18,5": "c177",
			"19,5": "c1",
			"20,5": "c1",
			"21,5": "c1",
			"22,5": "c2",
			"23,5": "c2",
			"24,5": "c2",
			"25,5": "c2",
			"26,5": "c2",
			"27,5": "c2",
			"28,5": "c2",
			"29,5": "c2",
			"30,5": "c2",
			"31,5": "c2",
			"32,5": "c2",
			"33,5": "c2",
			"34,5": "c2",
			"35,5": "c2",
			"36,5": "c2",
			"37,5": "c2",
			"38,5": "c2",
			"17,6": "c178",
			"18,6": "c179",
			"19,6": "c179",
			"20,6": "c12",
			"21,6": "c153",
			"22,6": "c153",
			"23,6": "c153",
			"24,6": "c153",
			"25,6": "c153",
			"26,6": "c153",
			"27,6": "c153",
			"28,6": "c153",
			"29,6": "c153",
			"30,6": "c153",
			"31,6": "c153",
			"32,6": "c153",
			"33,6": "c153",
			"34,6": "c153",
			"35,6": "c153",
			"36,6": "c153",
			"37,6": "c153",
			"38,6": "c153",
			"39,6": "c153",
			"40,6": "c153",
			"16,7": "c180",
			"17,7": "c181",
			"18,7": "c181",
			"19,7": "c180",
			"20,7": "c12",
			"21,7": "c154",
			"22,7": "c154",
			"23,7": "c154",
			"24,7": "c154",
			"25,7": "c154",
			"26,7": "c154",
			"27,7": "c154",
			"28,7": "c154",
			"29,7": "c154",
			"30,7": "c154",
			"31,7": "c154",
			"32,7": "c154",
			"33,7": "c154",
			"34,7": "c154",
			"35,7": "c154",
			"36,7": "c154",
			"37,7": "c154",
			"38,7": "c154",
			"39,7": "c154",
			"40,7": "c154",
			"41,7": "c154",
			"15,8": "c8",
			"16,8": "c8",
			"17,8": "c8",
			"18,8": "c12",
			"19,8": "c12",
			"20,8": "c155",
			"21,8": "c155",
			"22,8": "c155",
			"23,8": "c155",
			"24,8": "c155",
			"25,8": "c155",
			"26,8": "c155",
			"27,8": "c155",
			"28,8": "c155",
			"29,8": "c155",
			"30,8": "c155",
			"31,8": "c155",
			"32,8": "c155",
			"33,8": "c155",
			"34,8": "c155",
			"35,8": "c155",
			"36,8": "c155",
			"37,8": "c155",
			"38,8": "c155",
			"39,8": "c155",
			"40,8": "c155",
			"41,8": "c155",
			"42,8": "c155",
			"14,9": "c8",
			"15,9": "c8",
			"16,9": "c8",
			"17,9": "c12",
			"18,9": "c43",
			"19,9": "c43",
			"20,9": "c43",
			"21,9": "c43",
			"22,9": "c43",
			"23,9": "c43",
			"24,9": "c43",
			"25,9": "c43",
			"26,9": "c43",
			"27,9": "c43",
			"28,9": "c43",
			"29,9": "c43",
			"30,9": "c43",
			"31,9": "c43",
			"32,9": "c43",
			"33,9": "c43",
			"34,9": "c43",
			"35,9": "c43",
			"36,9": "c43",
			"37,9": "c43",
			"38,9": "c43",
			"39,9": "c43",
			"40,9": "c43",
			"41,9": "c43",
			"42,9": "c43",
			"43,9": "c43",
			"14,10": "c8",
			"15,10": "c8",
			"16,10": "c8",
			"17,10": "c12",
			"18,10": "c11",
			"19,10": "c11",
			"20,10": "c11",
			"21,10": "c11",
			"22,10": "c11",
			"23,10": "c11",
			"24,10": "c11",
			"25,10": "c11",
			"26,10": "c11",
			"27,10": "c11",
			"28,10": "c11",
			"29,10": "c11",
			"30,10": "c11",
			"31,10": "c11",
			"32,10": "c11",
			"33,10": "c11",
			"34,10": "c11",
			"35,10": "c11",
			"36,10": "c11",
			"37,10": "c11",
			"38,10": "c11",
			"39,10": "c11",
			"40,10": "c11",
			"41,10": "c11",
			"42,10": "c11",
			"43,10": "c11",
			"14,11": "c8",
			"15,11": "c8",
			"16,11": "c156",
			"18,11": "c14",
			"19,11": "c14",
			"20,11": "c14",
			"21,11": "c14",
			"22,11": "c14",
			"23,11": "c156",
			"24,11": "c156",
			"25,11": "c156",
			"26,11": "c14",
			"27,11": "c14",
			"28,11": "c14",
			"29,11": "c14",
			"30,11": "c14",
			"31,11": "c14",
			"32,11": "c14",
			"33,11": "c14",
			"34,11": "c14",
			"35,11": "c14",
			"36,11": "c14",
			"37,11": "c14",
			"38,11": "c14",
			"39,11": "c14",
			"40,11": "c14",
			"41,11": "c14",
			"42,11": "c182",
			"43,11": "c14",
			"16,12": "c157",
			"18,12": "c157",
			"19,12": "c157",
			"20,12": "c16",
			"21,12": "c157",
			"27,12": "c16",
			"28,12": "c16",
			"29,12": "c16",
			"30,12": "c16",
			"31,12": "c16",
			"32,12": "c16",
			"33,12": "c16",
			"34,12": "c16",
			"35,12": "c16",
			"36,12": "c16",
			"37,12": "c16",
			"38,12": "c16",
			"39,12": "c16",
			"40,12": "c16",
			"41,12": "c16",
			"42,12": "c8",
			"43,12": "c16",
			"16,13": "c158",
			"17,13": "c158",
			"18,13": "c158",
			"19,13": "c158",
			"20,13": "c158",
			"21,13": "c158",
			"27,13": "c20",
			"28,13": "c20",
			"29,13": "c20",
			"30,13": "c20",
			"31,13": "c20",
			"32,13": "c20",
			"33,13": "c20",
			"34,13": "c20",
			"35,13": "c20",
			"36,13": "c20",
			"37,13": "c20",
			"38,13": "c20",
			"39,13": "c20",
			"40,13": "c20",
			"41,13": "c8",
			"16,14": "c19",
			"17,14": "c19",
			"18,14": "c19",
			"19,14": "c19",
			"20,14": "c19",
			"21,14": "c19",
			"22,14": "c19",
			"26,14": "c19",
			"27,14": "c19",
			"28,14": "c22",
			"29,14": "c22",
			"30,14": "c22",
			"31,14": "c22",
			"32,14": "c19",
			"33,14": "c22",
			"34,14": "c22",
			"35,14": "c22",
			"36,14": "c22",
			"37,14": "c22",
			"38,14": "c22",
			"39,14": "c22",
			"40,14": "c8",
			"16,15": "c159",
			"17,15": "c159",
			"18,15": "c159",
			"19,15": "c159",
			"20,15": "c159",
			"21,15": "c159",
			"22,15": "c159",
			"23,15": "c159",
			"24,15": "c159",
			"25,15": "c159",
			"26,15": "c159",
			"27,15": "c159",
			"28,15": "c159",
			"29,15": "c159",
			"30,15": "c159",
			"31,15": "c159",
			"32,15": "c159",
			"33,15": "c159",
			"34,15": "c24",
			"35,15": "c24",
			"36,15": "c24",
			"37,15": "c159",
			"38,15": "c159",
			"39,15": "c8",
			"16,16": "c160",
			"17,16": "c160",
			"18,16": "c160",
			"19,16": "c160",
			"20,16": "c160",
			"21,16": "c160",
			"22,16": "c160",
			"23,16": "c160",
			"24,16": "c160",
			"25,16": "c160",
			"26,16": "c160",
			"27,16": "c160",
			"28,16": "c160",
			"29,16": "c160",
			"30,16": "c160",
			"31,16": "c160",
			"32,16": "c160",
			"33,16": "c160",
			"34,16": "c160",
			"35,16": "c160",
			"36,16": "c160",
			"37,16": "c160",
			"38,16": "c160",
			"39,16": "c160",
			"16,17": "c161",
			"17,17": "c161",
			"18,17": "c161",
			"19,17": "c161",
			"20,17": "c161",
			"21,17": "c161",
			"22,17": "c161",
			"23,17": "c161",
			"24,17": "c161",
			"25,17": "c161",
			"26,17": "c161",
			"27,17": "c161",
			"28,17": "c161",
			"29,17": "c161",
			"30,17": "c161",
			"31,17": "c161",
			"32,17": "c161",
			"33,17": "c8",
			"34,17": "c161",
			"17,18": "c25",
			"18,18": "c25",
			"19,18": "c25",
			"20,18": "c25",
			"21,18": "c25",
			"22,18": "c25",
			"23,18": "c25",
			"24,18": "c25",
			"25,18": "c25",
			"26,18": "c25",
			"27,18": "c25",
			"28,18": "c25",
			"29,18": "c25",
			"30,18": "c25",
			"31,18": "c25",
		},
		BgColors: nil,
	},
	{
		Duration: 125 * time.Millisecond,
		Content: []string{
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                        ▄▄████████▄▄                        ",
			"                  ████████████████████▄                     ",
			"                ████████████████████████▄                   ",
			"               ███████████████████████████                  ",
			"              █████████████████████████████                 ",
			"              ██████████████████████████████                ",
			"             ▐██████████████████████████████                ",
			"              ██████████████████████████████                ",
			"               ▐███    █████████████████████                ",
			"               ▐██     ████████████████████                 ",
			"               ▐███   ████████████████████                  ",
			"               ▐█████████████████████████                   ",
			"               ▐████████████████████████                    ",
			"                ████████████████████                        ",
			"                 ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀                           ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
		},
		FgColors: map[string]string{
			"24,4": "c93",
			"25,4": "c28",
			"26,4": "c29",
			"27,4": "c30",
			"28,4": "c30",
			"29,4": "c31",
			"30,4": "c0",
			"31,4": "c0",
			"32,4": "c0",
			"33,4": "c0",
			"34,4": "c0",
			"35,4": "c0",
			"18,5": "c1",
			"19,5": "c1",
			"20,5": "c1",
			"21,5": "c1",
			"22,5": "c99",
			"23,5": "c100",
			"24,5": "c101",
			"25,5": "c102",
			"26,5": "c102",
			"27,5": "c183",
			"28,5": "c32",
			"29,5": "c184",
			"30,5": "c2",
			"31,5": "c185",
			"32,5": "c185",
			"33,5": "c186",
			"34,5": "c95",
			"35,5": "c96",
			"36,5": "c97",
			"37,5": "c98",
			"38,5": "c2",
			"16,6": "c187",
			"17,6": "c33",
			"18,6": "c33",
			"19,6": "c33",
			"20,6": "c12",
			"21,6": "c188",
			"22,6": "c103",
			"23,6": "c104",
			"24,6": "c105",
			"25,6": "c106",
			"26,6": "c107",
			"27,6": "c108",
			"28,6": "c189",
			"29,6": "c153",
			"30,6": "c153",
			"31,6": "c190",
			"32,6": "c191",
			"33,6": "c192",
			"34,6": "c193",
			"35,6": "c193",
			"36,6": "c99",
			"37,6": "c100",
			"38,6": "c101",
			"39,6": "c102",
			"40,6": "c2",
			"15,7": "c187",
			"16,7": "c34",
			"17,7": "c34",
			"18,7": "c12",
			"19,7": "c12",
			"20,7": "c194",
			"21,7": "c195",
			"22,7": "c109",
			"23,7": "c109",
			"24,7": "c110",
			"25,7": "c111",
			"26,7": "c112",
			"27,7": "c113",
			"28,7": "c113",
			"29,7": "c196",
			"30,7": "c154",
			"31,7": "c197",
			"32,7": "c198",
			"33,7": "c199",
			"34,7": "c199",
			"35,7": "c188",
			"36,7": "c103",
			"37,7": "c104",
			"38,7": "c105",
			"39,7": "c106",
			"40,7": "c107",
			"41,7": "c108",
			"14,8": "c187",
			"15,8": "c187",
			"16,8": "c187",
			"17,8": "c12",
			"18,8": "c200",
			"19,8": "c201",
			"20,8": "c202",
			"21,8": "c114",
			"22,8": "c114",
			"23,8": "c115",
			"24,8": "c116",
			"25,8": "c117",
			"26,8": "c37",
			"27,8": "c37",
			"28,8": "c38",
			"29,8": "c203",
			"30,8": "c155",
			"31,8": "c204",
			"32,8": "c205",
			"33,8": "c206",
			"34,8": "c194",
			"35,8": "c195",
			"36,8": "c109",
			"37,8": "c109",
			"38,8": "c110",
			"39,8": "c111",
			"40,8": "c112",
			"41,8": "c113",
			"42,8": "c113",
			"14,9": "c187",
			"15,9": "c187",
			"16,9": "c12",
			"17,9": "c51",
			"18,9": "c52",
			"19,9": "c53",
			"20,9": "c118",
			"21,9": "c119",
			"22,9": "c120",
			"23,9": "c121",
			"24,9": "c122",
			"25,9": "c122",
			"26,9": "c40",
			"27,9": "c41",
			"28,9": "c42",
			"29,9": "c43",
			"30,9": "c44",
			"31,9": "c45",
			"32,9": "c200",
			"33,9": "c201",
			"34,9": "c202",
			"35,9": "c114",
			"36,9": "c114",
			"37,9": "c115",
			"38,9": "c116",
			"39,9": "c117",
			"40,9": "c37",
			"41,9": "c37",
			"42,9": "c38",
			"43,9": "c203",
			"13,10": "c187",
			"14,10": "c187",
			"15,10": "c187",
			"16,10": "c12",
			"17,10": "c60",
			"18,10": "c61",
			"19,10": "c207",
			"20,10": "c208",
			"21,10": "c123",
			"22,10": "c124",
			"23,10": "c125",
			"24,10": "c125",
			"25,10": "c126",
			"26,10": "c48",
			"27,10": "c49",
			"28,10": "c50",
			"29,10": "c50",
			"30,10": "c11",
			"31,10": "c51",
			"32,10": "c52",
			"33,10": "c53",
			"34,10": "c118",
			"35,10": "c119",
			"36,10": "c120",
			"37,10": "c121",
			"38,10": "c122",
			"39,10": "c122",
			"40,10": "c40",
			"41,10": "c41",
			"42,10": "c42",
			"43,10": "c43",
			"14,11": "c187",
			"15,11": "c187",
			"16,11": "c156",
			"17,11": "c47",
			"18,11": "c66",
			"19,11": "c209",
			"20,11": "c210",
			"21,11": "c127",
			"22,11": "c127",
			"23,11": "c128",
			"24,11": "c129",
			"25,11": "c130",
			"26,11": "c55",
			"27,11": "c56",
			"28,11": "c57",
			"29,11": "c58",
			"30,11": "c59",
			"31,11": "c60",
			"32,11": "c61",
			"33,11": "c207",
			"34,11": "c208",
			"35,11": "c123",
			"36,11": "c124",
			"37,11": "c125",
			"38,11": "c125",
			"39,11": "c126",
			"40,11": "c48",
			"41,11": "c13",
			"42,11": "c187",
			"43,11": "c50",
			"15,12": "c157",
			"16,12": "c157",
			"17,12": "c157",
			"18,12": "c157",
			"23,12": "c133",
			"24,12": "c134",
			"25,12": "c135",
			"26,12": "c64",
			"27,12": "c65",
			"28,12": "c46",
			"29,12": "c16",
			"30,12": "c47",
			"31,12": "c47",
			"32,12": "c66",
			"33,12": "c209",
			"34,12": "c210",
			"35,12": "c127",
			"36,12": "c127",
			"37,12": "c128",
			"38,12": "c129",
			"39,12": "c130",
			"40,12": "c13",
			"41,12": "c13",
			"42,12": "c157",
			"43,12": "c157",
			"15,13": "c158",
			"16,13": "c158",
			"17,13": "c158",
			"23,13": "c138",
			"24,13": "c138",
			"25,13": "c139",
			"26,13": "c68",
			"27,13": "c211",
			"28,13": "c54",
			"29,13": "c69",
			"30,13": "c20",
			"31,13": "c70",
			"32,13": "c71",
			"33,13": "c212",
			"34,13": "c131",
			"35,13": "c131",
			"36,13": "c132",
			"37,13": "c133",
			"38,13": "c134",
			"39,13": "c135",
			"40,13": "c187",
			"41,13": "c187",
			"42,13": "c158",
			"15,14": "c19",
			"16,14": "c19",
			"17,14": "c19",
			"18,14": "c19",
			"22,14": "c142",
			"23,14": "c142",
			"24,14": "c213",
			"25,14": "c143",
			"26,14": "c19",
			"27,14": "c19",
			"28,14": "c62",
			"29,14": "c22",
			"30,14": "c63",
			"31,14": "c214",
			"32,14": "c215",
			"33,14": "c215",
			"34,14": "c216",
			"35,14": "c136",
			"36,14": "c137",
			"37,14": "c138",
			"38,14": "c138",
			"39,14": "c187",
			"40,14": "c187",
			"41,14": "c19",
			"15,15": "c159",
			"16,15": "c159",
			"17,15": "c159",
			"18,15": "c159",
			"19,15": "c159",
			"20,15": "c146",
			"21,15": "c147",
			"22,15": "c148",
			"23,15": "c77",
			"24,15": "c159",
			"25,15": "c159",
			"26,15": "c159",
			"27,15": "c159",
			"28,15": "c159",
			"29,15": "c24",
			"30,15": "c67",
			"31,15": "c217",
			"32,15": "c217",
			"33,15": "c218",
			"34,15": "c140",
			"35,15": "c141",
			"36,15": "c159",
			"37,15": "c159",
			"38,15": "c187",
			"39,15": "c187",
			"40,15": "c159",
			"15,16": "c160",
			"16,16": "c160",
			"17,16": "c160",
			"18,16": "c160",
			"19,16": "c160",
			"20,16": "c160",
			"21,16": "c160",
			"22,16": "c160",
			"23,16": "c160",
			"24,16": "c160",
			"25,16": "c160",
			"26,16": "c160",
			"27,16": "c160",
			"28,16": "c160",
			"29,16": "c160",
			"30,16": "c160",
			"31,16": "c160",
			"32,16": "c160",
			"33,16": "c160",
			"34,16": "c160",
			"35,16": "c160",
			"36,16": "c160",
			"37,16": "c160",
			"38,16": "c160",
			"39,16": "c160",
			"16,17": "c161",
			"17,17": "c161",
			"18,17": "c161",
			"19,17": "c161",
			"20,17": "c161",
			"21,17": "c161",
			"22,17": "c161",
			"23,17": "c161",
			"24,17": "c161",
			"25,17": "c161",
			"26,17": "c161",
			"27,17": "c161",
			"28,17": "c161",
			"29,17": "c161",
			"30,17": "c161",
			"31,17": "c161",
			"32,17": "c13",
			"33,17": "c187",
			"34,17": "c187",
			"35,17": "c89",
			"17,18": "c25",
			"18,18": "c25",
			"19,18": "c25",
			"20,18": "c25",
			"21,18": "c25",
			"22,18": "c25",
			"23,18": "c25",
			"24,18": "c25",
			"25,18": "c25",
			"26,18": "c25",
			"27,18": "c25",
			"28,18": "c25",
			"29,18": "c25",
			"30,18": "c25",
			"31,18": "c25",
			"32,18": "c25",
		},
		BgColors: nil,
	},
	{
		Duration: 125 * time.Millisecond,
		Content: []string{
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                        ▄▄████████▄▄                        ",
			"                   ███████████████████▄                     ",
			"                ████████████████████████▄                   ",
			"               ███████████████████████████                  ",
			"              █████████████████████████████                 ",
			"              █████████████████████████████                 ",
			"              ██████████████████████████████                ",
			"             ▐███████████████████████████████               ",
			"             ▐  █████████████████████████████               ",
			"             █   █████████████████████████████              ",
			"             ▐  ██████████████████████████████              ",
			"              ██████████████████████████████                ",
			"               ████████████████████████████                 ",
			"                ██████████████████████                      ",
			"                  ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀                          ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
		},
		FgColors: map[string]string{
			"24,4": "c0",
			"25,4": "c0",
			"26,4": "c0",
			"27,4": "c0",
			"28,4": "c0",
			"29,4": "c0",
			"30,4": "c0",
			"31,4": "c0",
			"32,4": "c0",
			"33,4": "c0",
			"34,4": "c0",
			"35,4": "c0",
			"19,5": "c1",
			"20,5": "c1",
			"21,5": "c1",
			"22,5": "c2",
			"23,5": "c2",
			"24,5": "c2",
			"25,5": "c2",
			"26,5": "c2",
			"27,5": "c2",
			"28,5": "c2",
			"29,5": "c2",
			"30,5": "c2",
			"31,5": "c2",
			"32,5": "c2",
			"33,5": "c2",
			"34,5": "c2",
			"35,5": "c2",
			"36,5": "c2",
			"37,5": "c2",
			"38,5": "c2",
			"16,6": "c4",
			"17,6": "c4",
			"18,6": "c4",
			"19,6": "c187",
			"20,6": "c153",
			"21,6": "c153",
			"22,6": "c153",
			"23,6": "c153",
			"24,6": "c153",
			"25,6": "c153",
			"26,6": "c153",
			"27,6": "c153",
			"28,6": "c153",
			"29,6": "c153",
			"30,6": "c153",
			"31,6": "c153",
			"32,6": "c153",
			"33,6": "c153",
			"34,6": "c153",
			"35,6": "c153",
			"36,6": "c153",
			"37,6": "c153",
			"38,6": "c153",
			"39,6": "c153",
			"40,6": "c2",
			"15,7": "c187",
			"16,7": "c7",
			"17,7": "c7",
			"18,7": "c12",
			"19,7": "c154",
			"20,7": "c154",
			"21,7": "c154",
			"22,7": "c154",
			"23,7": "c154",
			"24,7": "c154",
			"25,7": "c154",
			"26,7": "c154",
			"27,7": "c154",
			"28,7": "c154",
			"29,7": "c154",
			"30,7": "c154",
			"31,7": "c154",
			"32,7": "c154",
			"33,7": "c154",
			"34,7": "c154",
			"35,7": "c154",
			"36,7": "c154",
			"37,7": "c154",
			"38,7": "c154",
			"39,7": "c154",
			"40,7": "c154",
			"41,7": "c154",
			"14,8": "c187",
			"15,8": "c187",
			"16,8": "c187",
			"17,8": "c12",
			"18,8": "c155",
			"19,8": "c155",
			"20,8": "c155",
			"21,8": "c155",
			"22,8": "c155",
			"23,8": "c155",
			"24,8": "c155",
			"25,8": "c155",
			"26,8": "c155",
			"27,8": "c155",
			"28,8": "c155",
			"29,8": "c155",
			"30,8": "c155",
			"31,8": "c155",
			"32,8": "c155",
			"33,8": "c155",
			"34,8": "c155",
			"35,8": "c155",
			"36,8": "c155",
			"37,8": "c155",
			"38,8": "c155",
			"39,8": "c155",
			"40,8": "c155",
			"41,8": "c155",
			"42,8": "c155",
			"14,9": "c187",
			"15,9": "c12",
			"16,9": "c43",
			"17,9": "c43",
			"18,9": "c43",
			"19,9": "c43",
			"20,9": "c43",
			"21,9": "c43",
			"22,9": "c43",
			"23,9": "c43",
			"24,9": "c43",
			"25,9": "c43",
			"26,9": "c43",
			"27,9": "c43",
			"28,9": "c43",
			"29,9": "c43",
			"30,9": "c43",
			"31,9": "c43",
			"32,9": "c43",
			"33,9": "c43",
			"34,9": "c43",
			"35,9": "c43",
			"36,9": "c43",
			"37,9": "c43",
			"38,9": "c43",
			"39,9": "c43",
			"40,9": "c43",
			"41,9": "c43",
			"42,9": "c43",
			"14,10": "c219",
			"15,10": "c11",
			"16,10": "c11",
			"17,10": "c11",
			"18,10": "c11",
			"19,10": "c11",
			"20,10": "c11",
			"21,10": "c11",
			"22,10": "c11",
			"23,10": "c11",
			"24,10": "c11",
			"25,10": "c11",
			"26,10": "c11",
			"27,10": "c11",
			"28,10": "c11",
			"29,10": "c11",
			"30,10": "c11",
			"31,10": "c11",
			"32,10": "c11",
			"33,10": "c11",
			"34,10": "c11",
			"35,10": "c11",
			"36,10": "c11",
			"37,10": "c11",
			"38,10": "c11",
			"39,10": "c11",
			"40,10": "c11",
			"41,10": "c11",
			"42,10": "c11",
			"43,10": "c11",
			"13,11": "c170",
			"14,11": "c170",
			"15,11": "c14",
			"16,11": "c14",
			"17,11": "c14",
			"18,11": "c14",
			"19,11": "c14",
			"20,11": "c14",
			"21,11": "c14",
			"22,11": "c14",
			"23,11": "c14",
			"24,11": "c14",
			"25,11": "c14",
			"26,11": "c14",
			"27,11": "c14",
			"28,11": "c14",
			"29,11": "c14",
			"30,11": "c14",
			"31,11": "c14",
			"32,11": "c14",
			"33,11": "c14",
			"34,11": "c14",
			"35,11": "c170",
			"36,11": "c13",
			"37,11": "c13",
			"38,11": "c13",
			"39,11": "c13",
			"40,11": "c14",
			"41,11": "c14",
			"42,11": "c14",
			"43,11": "c14",
			"44,11": "c170",
			"13,12": "c17",
			"16,12": "c17",
			"17,12": "c16",
			"18,12": "c16",
			"19,12": "c16",
			"20,12": "c16",
			"21,12": "c16",
			"22,12": "c16",
			"23,12": "c16",
			"24,12": "c16",
			"25,12": "c16",
			"26,12": "c16",
			"27,12": "c16",
			"28,12": "c16",
			"29,12": "c16",
			"30,12": "c16",
			"31,12": "c16",
			"32,12": "c16",
			"33,12": "c16",
			"34,12": "c16",
			"35,12": "c17",
			"36,12": "c13",
			"37,12": "c13",
			"38,12": "c13",
			"39,12": "c13",
			"40,12": "c16",
			"41,12": "c16",
			"42,12": "c16",
			"43,12": "c17",
			"44,12": "c16",
			"13,13": "c171",
			"17,13": "c20",
			"18,13": "c20",
			"19,13": "c20",
			"20,13": "c20",
			"21,13": "c20",
			"22,13": "c20",
			"23,13": "c20",
			"24,13": "c20",
			"25,13": "c20",
			"26,13": "c20",
			"27,13": "c20",
			"28,13": "c20",
			"29,13": "c20",
			"30,13": "c20",
			"31,13": "c20",
			"32,13": "c20",
			"33,13": "c20",
			"34,13": "c171",
			"35,13": "c187",
			"36,13": "c187",
			"37,13": "c187",
			"38,13": "c187",
			"39,13": "c187",
			"40,13": "c20",
			"41,13": "c20",
			"42,13": "c171",
			"43,13": "c20",
			"44,13": "c20",
			"45,13": "c20",
			"13,14": "c172",
			"16,14": "c22",
			"17,14": "c22",
			"18,14": "c22",
			"19,14": "c22",
			"20,14": "c22",
			"21,14": "c22",
			"22,14": "c172",
			"23,14": "c22",
			"24,14": "c22",
			"25,14": "c22",
			"26,14": "c22",
			"27,14": "c22",
			"28,14": "c22",
			"29,14": "c22",
			"30,14": "c22",
			"31,14": "c22",
			"32,14": "c22",
			"33,14": "c22",
			"34,14": "c172",
			"35,14": "c13",
			"36,14": "c13",
			"37,14": "c187",
			"38,14": "c187",
			"39,14": "c172",
			"40,14": "c172",
			"41,14": "c172",
			"42,14": "c172",
			"43,14": "c22",
			"44,14": "c22",
			"45,14": "c172",
			"14,15": "c21",
			"15,15": "c21",
			"16,15": "c21",
			"17,15": "c21",
			"18,15": "c21",
			"19,15": "c24",
			"20,15": "c24",
			"21,15": "c21",
			"22,15": "c21",
			"23,15": "c21",
			"24,15": "c24",
			"25,15": "c24",
			"26,15": "c24",
			"27,15": "c24",
			"28,15": "c24",
			"29,15": "c24",
			"30,15": "c24",
			"31,15": "c24",
			"32,15": "c24",
			"33,15": "c21",
			"34,15": "c187",
			"35,15": "c187",
			"36,15": "c187",
			"37,15": "c187",
			"38,15": "c21",
			"39,15": "c21",
			"40,15": "c21",
			"41,15": "c21",
			"42,15": "c21",
			"43,15": "c21",
			"15,16": "c173",
			"16,16": "c173",
			"17,16": "c173",
			"18,16": "c173",
			"19,16": "c173",
			"20,16": "c173",
			"21,16": "c173",
			"22,16": "c173",
			"23,16": "c173",
			"24,16": "c173",
			"25,16": "c173",
			"26,16": "c173",
			"27,16": "c26",
			"28,16": "c26",
			"29,16": "c173",
			"30,16": "c173",
			"31,16": "c173",
			"32,16": "c173",
			"33,16": "c173",
			"34,16": "c173",
			"35,16": "c173",
			"36,16": "c173",
			"37,16": "c173",
			"38,16": "c173",
			"39,16": "c173",
			"40,16": "c173",
			"41,16": "c173",
			"42,16": "c173",
			"16,17": "c174",
			"17,17": "c174",
			"18,17": "c174",
			"19,17": "c174",
			"20,17": "c174",
			"21,17": "c174",
			"22,17": "c174",
			"23,17": "c174",
			"24,17": "c174",
			"25,17": "c174",
			"26,17": "c174",
			"27,17": "c174",
			"28,17": "c174",
			"29,17": "c174",
			"30,17": "c174",
			"31,17": "c187",
			"32,17": "c187",
			"33,17": "c187",
			"34,17": "c174",
			"35,17": "c174",
			"36,17": "c174",
			"37,17": "c174",
			"18,18": "c25",
			"19,18": "c25",
			"20,18": "c25",
			"21,18": "c25",
			"22,18": "c25",
			"23,18": "c25",
			"24,18": "c25",
			"25,18": "c25",
			"26,18": "c25",
			"27,18": "c25",
			"28,18": "c25",
			"29,18": "c25",
			"30,18": "c25",
			"31,18": "c25",
			"32,18": "c25",
			"33,18": "c25",
		},
		BgColors: nil,
	},
	{
		Duration: 125 * time.Millisecond,
		Content: []string{
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                        ▄▄████████▄▄                        ",
			"                     █████████████████▄                     ",
			"                 ███████████████████████▄                   ",
			"                ██████████████████████████                  ",
			"               ████████████████████████████                 ",
			"               ████████████████████████████                 ",
			"              ██████████████████████████████                ",
			"             █████████████████████████████████              ",
			"            █ █████████████████████████████████             ",
			"            █ █████████████████████████████████             ",
			"            █ █████████████████████████████████             ",
			"             █████████████████████████████████              ",
			"              ▀█████████████████████████████                ",
			"                ▀██████████████████████                     ",
			"                   ▀████████▀▀▀▀▀▀                          ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
		},
		FgColors: map[string]string{
			"24,4": "c0",
			"25,4": "c0",
			"26,4": "c0",
			"27,4": "c0",
			"28,4": "c0",
			"29,4": "c0",
			"30,4": "c0",
			"31,4": "c0",
			"32,4": "c0",
			"33,4": "c0",
			"34,4": "c0",
			"35,4": "c0",
			"21,5": "c1",
			"22,5": "c2",
			"23,5": "c2",
			"24,5": "c2",
			"25,5": "c2",
			"26,5": "c2",
			"27,5": "c2",
			"28,5": "c2",
			"29,5": "c2",
			"30,5": "c2",
			"31,5": "c2",
			"32,5": "c2",
			"33,5": "c2",
			"34,5": "c2",
			"35,5": "c2",
			"36,5": "c2",
			"37,5": "c2",
			"38,5": "c2",
			"17,6": "c33",
			"18,6": "c33",
			"19,6": "c33",
			"20,6": "c153",
			"21,6": "c153",
			"22,6": "c153",
			"23,6": "c153",
			"24,6": "c153",
			"25,6": "c153",
			"26,6": "c153",
			"27,6": "c153",
			"28,6": "c153",
			"29,6": "c153",
			"30,6": "c153",
			"31,6": "c153",
			"32,6": "c153",
			"33,6": "c153",
			"34,6": "c153",
			"35,6": "c153",
			"36,6": "c153",
			"37,6": "c153",
			"38,6": "c153",
			"39,6": "c153",
			"40,6": "c2",
			"16,7": "c187",
			"17,7": "c34",
			"18,7": "c154",
			"19,7": "c154",
			"20,7": "c154",
			"21,7": "c154",
			"22,7": "c154",
			"23,7": "c154",
			"24,7": "c154",
			"25,7": "c154",
			"26,7": "c154",
			"27,7": "c154",
			"28,7": "c154",
			"29,7": "c154",
			"30,7": "c154",
			"31,7": "c154",
			"32,7": "c154",
			"33,7": "c154",
			"34,7": "c154",
			"35,7": "c154",
			"36,7": "c154",
			"37,7": "c154",
			"38,7": "c154",
			"39,7": "c154",
			"40,7": "c154",
			"41,7": "c154",
			"15,8": "c187",
			"16,8": "c187",
			"17,8": "c12",
			"18,8": "c155",
			"19,8": "c155",
			"20,8": "c155",
			"21,8": "c155",
			"22,8": "c155",
			"23,8": "c155",
			"24,8": "c155",
			"25,8": "c155",
			"26,8": "c155",
			"27,8": "c155",
			"28,8": "c155",
			"29,8": "c155",
			"30,8": "c155",
			"31,8": "c155",
			"32,8": "c155",
			"33,8": "c155",
			"34,8": "c155",
			"35,8": "c155",
			"36,8": "c155",
			"37,8": "c155",
			"38,8": "c155",
			"39,8": "c155",
			"40,8": "c155",
			"41,8": "c155",
			"42,8": "c155",
			"15,9": "c187",
			"16,9": "c12",
			"17,9": "c12",
			"18,9": "c43",
			"19,9": "c43",
			"20,9": "c43",
			"21,9": "c43",
			"22,9": "c43",
			"23,9": "c43",
			"24,9": "c43",
			"25,9": "c43",
			"26,9": "c43",
			"27,9": "c43",
			"28,9": "c43",
			"29,9": "c43",
			"30,9": "c43",
			"31,9": "c43",
			"32,9": "c43",
			"33,9": "c43",
			"34,9": "c43",
			"35,9": "c43",
			"36,9": "c43",
			"37,9": "c43",
			"38,9": "c43",
			"39,9": "c43",
			"40,9": "c43",
			"41,9": "c43",
			"42,9": "c43",
			"14,10": "c219",
			"15,10": "c11",
			"16,10": "c11",
			"17,10": "c11",
			"18,10": "c11",
			"19,10": "c11",
			"20,10": "c11",
			"21,10": "c11",
			"22,10": "c11",
			"23,10": "c11",
			"24,10": "c11",
			"25,10": "c11",
			"26,10": "c11",
			"27,10": "c11",
			"28,10": "c11",
			"29,10": "c11",
			"30,10": "c11",
			"31,10": "c11",
			"32,10": "c11",
			"33,10": "c11",
			"34,10": "c11",
			"35,10": "c11",
			"36,10": "c11",
			"37,10": "c11",
			"38,10": "c11",
			"39,10": "c11",
			"40,10": "c11",
			"41,10": "c11",
			"42,10": "c11",
			"43,10": "c11",
			"13,11": "c170",
			"14,11": "c14",
			"15,11": "c14",
			"16,11": "c14",
			"17,11": "c14",
			"18,11": "c14",
			"19,11": "c14",
			"20,11": "c14",
			"21,11": "c14",
			"22,11": "c14",
			"23,11": "c14",
			"24,11": "c14",
			"25,11": "c14",
			"26,11": "c14",
			"27,11": "c14",
			"28,11": "c14",
			"29,11": "c14",
			"30,11": "c14",
			"31,11": "c14",
			"32,11": "c14",
			"33,11": "c13",
			"34,11": "c13",
			"35,11": "c13",
			"36,11": "c13",
			"37,11": "c13",
			"38,11": "c14",
			"39,11": "c14",
			"40,11": "c14",
			"41,11": "c14",
			"42,11": "c14",
			"43,11": "c14",
			"44,11": "c14",
			"45,11": "c14",
			"12,12": "c17",
			"14,12": "c16",
			"15,12": "c16",
			"16,12": "c16",
			"17,12": "c16",
			"18,12": "c16",
			"19,12": "c17",
			"20,12": "c16",
			"21,12": "c16",
			"22,12": "c16",
			"23,12": "c16",
			"24,12": "c16",
			"25,12": "c16",
			"26,12": "c16",
			"27,12": "c16",
			"28,12": "c16",
			"29,12": "c16",
			"30,12": "c16",
			"31,12": "c16",
			"32,12": "c16",
			"33,12": "c13",
			"34,12": "c13",
			"35,12": "c13",
			"36,12": "c13",
			"37,12": "c13",
			"38,12": "c16",
			"39,12": "c16",
			"40,12": "c16",
			"41,12": "c16",
			"42,12": "c16",
			"43,12": "c16",
			"44,12": "c16",
			"45,12": "c16",
			"46,12": "c16",
			"12,13": "c171",
			"14,13": "c20",
			"15,13": "c20",
			"16,13": "c20",
			"17,13": "c20",
			"18,13": "c20",
			"19,13": "c20",
			"20,13": "c171",
			"21,13": "c20",
			"22,13": "c20",
			"23,13": "c20",
			"24,13": "c20",
			"25,13": "c20",
			"26,13": "c20",
			"27,13": "c20",
			"28,13": "c20",
			"29,13": "c20",
			"30,13": "c20",
			"31,13": "c20",
			"32,13": "c20",
			"33,13": "c13",
			"34,13": "c13",
			"35,13": "c13",
			"36,13": "c187",
			"37,13": "c171",
			"38,13": "c20",
			"39,13": "c20",
			"40,13": "c20",
			"41,13": "c20",
			"42,13": "c171",
			"43,13": "c20",
			"44,13": "c20",
			"45,13": "c20",
			"46,13": "c20",
			"12,14": "c172",
			"14,14": "c22",
			"15,14": "c22",
			"16,14": "c22",
			"17,14": "c22",
			"18,14": "c22",
			"19,14": "c22",
			"20,14": "c172",
			"21,14": "c172",
			"22,14": "c22",
			"23,14": "c22",
			"24,14": "c22",
			"25,14": "c22",
			"26,14": "c22",
			"27,14": "c22",
			"28,14": "c22",
			"29,14": "c22",
			"30,14": "c22",
			"31,14": "c22",
			"32,14": "c172",
			"33,14": "c13",
			"34,14": "c13",
			"35,14": "c13",
			"36,14": "c187",
			"37,14": "c22",
			"38,14": "c22",
			"39,14": "c22",
			"40,14": "c22",
			"41,14": "c22",
			"42,14": "c172",
			"43,14": "c172",
			"44,14": "c22",
			"45,14": "c22",
			"46,14": "c172",
			"13,15": "c21",
			"14,15": "c21",
			"15,15": "c24",
			"16,15": "c24",
			"17,15": "c24",
			"18,15": "c24",
			"19,15": "c21",
			"20,15": "c21",
			"21,15": "c21",
			"22,15": "c21",
			"23,15": "c24",
			"24,15": "c24",
			"25,15": "c24",
			"26,15": "c24",
			"27,15": "c24",
			"28,15": "c24",
			"29,15": "c24",
			"30,15": "c24",
			"31,15": "c24",
			"32,15": "c187",
			"33,15": "c187",
			"34,15": "c187",
			"35,15": "c187",
			"36,15": "c21",
			"37,15": "c21",
			"38,15": "c21",
			"39,15": "c21",
			"40,15": "c21",
			"41,15": "c21",
			"42,15": "c21",
			"43,15": "c21",
			"44,15": "c21",
			"45,15": "c21",
			"14,16": "c173",
			"15,16": "c173",
			"16,16": "c173",
			"17,16": "c173",
			"18,16": "c173",
			"19,16": "c173",
			"20,16": "c173",
			"21,16": "c173",
			"22,16": "c173",
			"23,16": "c173",
			"24,16": "c173",
			"25,16": "c26",
			"26,16": "c173",
			"27,16": "c173",
			"28,16": "c173",
			"29,16": "c173",
			"30,16": "c173",
			"31,16": "c173",
			"32,16": "c173",
			"33,16": "c173",
			"34,16": "c173",
			"35,16": "c173",
			"36,16": "c173",
			"37,16": "c173",
			"38,16": "c173",
			"39,16": "c173",
			"40,16": "c173",
			"41,16": "c173",
			"42,16": "c173",
			"43,16": "c173",
			"16,17": "c174",
			"17,17": "c174",
			"18,17": "c174",
			"19,17": "c174",
			"20,17": "c174",
			"21,17": "c174",
			"22,17": "c174",
			"23,17": "c174",
			"24,17": "c174",
			"25,17": "c174",
			"26,17": "c174",
			"27,17": "c174",
			"28,17": "c174",
			"29,17": "c174",
			"30,17": "c174",
			"31,17": "c187",
			"32,17": "c187",
			"33,17": "c187",
			"34,17": "c174",
			"35,17": "c174",
			"36,17": "c174",
			"37,17": "c174",
			"38,17": "c174",
			"19,18": "c25",
			"20,18": "c25",
			"21,18": "c25",
			"22,18": "c25",
			"23,18": "c25",
			"24,18": "c25",
			"25,18": "c25",
			"26,18": "c25",
			"27,18": "c25",
			"28,18": "c25",
			"29,18": "c25",
			"30,18": "c25",
			"31,18": "c25",
			"32,18": "c25",
			"33,18": "c25",
		},
		BgColors: nil,
	},
	{
		Duration: 125 * time.Millisecond,
		Content: []string{
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                        ▄▄████████▄▄                        ",
			"                      ████████████████▄                     ",
			"                    █████████████████████                   ",
			"                  ████████████████████████                  ",
			"                 ██████████████████████████                 ",
			"                 ██████████████████████████                 ",
			"               ▄█████████████████████████████               ",
			"             ██████████████████████████████████             ",
			"            ████████████████████████████████████            ",
			"            ████████████████████████████████████            ",
			"            ████████████████████████████████████            ",
			"             ██████████████████████████████████             ",
			"               ▀█████████████████████████████               ",
			"                  ▀██████████████████████▀                  ",
			"                      ▀██████████████▀                      ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
		},
		FgColors: map[string]string{
			"24,4": "c0",
			"25,4": "c0",
			"26,4": "c0",
			"27,4": "c0",
			"28,4": "c0",
			"29,4": "c0",
			"30,4": "c0",
			"31,4": "c0",
			"32,4": "c0",
			"33,4": "c0",
			"34,4": "c0",
			"35,4": "c0",
			"22,5": "c2",
			"23,5": "c2",
			"24,5": "c2",
			"25,5": "c2",
			"26,5": "c2",
			"27,5": "c2",
			"28,5": "c2",
			"29,5": "c2",
			"30,5": "c2",
			"31,5": "c2",
			"32,5": "c2",
			"33,5": "c2",
			"34,5": "c2",
			"35,5": "c2",
			"36,5": "c2",
			"37,5": "c2",
			"38,5": "c2",
			"20,6": "c153",
			"21,6": "c153",
			"22,6": "c153",
			"23,6": "c153",
			"24,6": "c153",
			"25,6": "c153",
			"26,6": "c153",
			"27,6": "c153",
			"28,6": "c153",
			"29,6": "c153",
			"30,6": "c153",
			"31,6": "c153",
			"32,6": "c153",
			"33,6": "c153",
			"34,6": "c153",
			"35,6": "c153",
			"36,6": "c153",
			"37,6": "c153",
			"38,6": "c153",
			"39,6": "c153",
			"40,6": "c1",
			"18,7": "c12",
			"19,7": "c154",
			"20,7": "c154",
			"21,7": "c154",
			"22,7": "c154",
			"23,7": "c154",
			"24,7": "c154",
			"25,7": "c154",
			"26,7": "c154",
			"27,7": "c154",
			"28,7": "c154",
			"29,7": "c154",
			"30,7": "c154",
			"31,7": "c154",
			"32,7": "c154",
			"33,7": "c154",
			"34,7": "c154",
			"35,7": "c154",
			"36,7": "c154",
			"37,7": "c154",
			"38,7": "c154",
			"39,7": "c154",
			"40,7": "c154",
			"41,7": "c154",
			"17,8": "c12",
			"18,8": "c12",
			"19,8": "c155",
			"20,8": "c155",
			"21,8": "c155",
			"22,8": "c155",
			"23,8": "c155",
			"24,8": "c155",
			"25,8": "c155",
			"26,8": "c155",
			"27,8": "c155",
			"28,8": "c155",
			"29,8": "c155",
			"30,8": "c155",
			"31,8": "c155",
			"32,8": "c155",
			"33,8": "c155",
			"34,8": "c155",
			"35,8": "c155",
			"36,8": "c155",
			"37,8": "c155",
			"38,8": "c155",
			"39,8": "c155",
			"40,8": "c155",
			"41,8": "c155",
			"42,8": "c155",
			"17,9": "c12",
			"18,9": "c43",
			"19,9": "c43",
			"20,9": "c43",
			"21,9": "c43",
			"22,9": "c43",
			"23,9": "c43",
			"24,9": "c43",
			"25,9": "c43",
			"26,9": "c43",
			"27,9": "c43",
			"28,9": "c43",
			"29,9": "c43",
			"30,9": "c43",
			"31,9": "c43",
			"32,9": "c43",
			"33,9": "c43",
			"34,9": "c43",
			"35,9": "c43",
			"36,9": "c43",
			"37,9": "c43",
			"38,9": "c43",
			"39,9": "c43",
			"40,9": "c43",
			"41,9": "c43",
			"42,9": "c43",
			"15,10": "c11",
			"16,10": "c11",
			"17,10": "c12",
			"18,10": "c12",
			"19,10": "c11",
			"20,10": "c11",
			"21,10": "c11",
			"22,10": "c11",
			"23,10": "c11",
			"24,10": "c11",
			"25,10": "c11",
			"26,10": "c11",
			"27,10": "c11",
			"28,10": "c11",
			"29,10": "c11",
			"30,10": "c11",
			"31,10": "c11",
			"32,10": "c11",
			"33,10": "c11",
			"34,10": "c11",
			"35,10": "c11",
			"36,10": "c11",
			"37,10": "c11",
			"38,10": "c11",
			"39,10": "c11",
			"40,10": "c11",
			"41,10": "c11",
			"42,10": "c11",
			"43,10": "c11",
			"44,10": "c11",
			"13,11": "c14",
			"14,11": "c14",
			"15,11": "c14",
			"16,11": "c14",
			"17,11": "c156",
			"18,11": "c156",
			"19,11": "c14",
			"20,11": "c14",
			"21,11": "c14",
			"22,11": "c14",
			"23,11": "c14",
			"24,11": "c14",
			"25,11": "c14",
			"26,11": "c14",
			"27,11": "c187",
			"28,11": "c39",
			"29,11": "c39",
			"30,11": "c39",
			"31,11": "c39",
			"32,11": "c39",
			"33,11": "c156",
			"34,11": "c14",
			"35,11": "c14",
			"36,11": "c14",
			"37,11": "c14",
			"38,11": "c14",
			"39,11": "c14",
			"40,11": "c14",
			"41,11": "c14",
			"42,11": "c14",
			"43,11": "c14",
			"44,11": "c14",
			"45,11": "c14",
			"46,11": "c14",
			"12,12": "c16",
			"13,12": "c16",
			"14,12": "c16",
			"15,12": "c16",
			"16,12": "c16",
			"17,12": "c157",
			"18,12": "c157",
			"19,12": "c157",
			"20,12": "c16",
			"21,12": "c16",
			"22,12": "c16",
			"23,12": "c16",
			"24,12": "c16",
			"25,12": "c16",
			"26,12": "c16",
			"27,12": "c187",
			"28,12": "c13",
			"29,12": "c13",
			"30,12": "c13",
			"31,12": "c13",
			"32,12": "c13",
			"33,12": "c157",
			"34,12": "c16",
			"35,12": "c16",
			"36,12": "c16",
			"37,12": "c16",
			"38,12": "c16",
			"39,12": "c16",
			"40,12": "c16",
			"41,12": "c16",
			"42,12": "c16",
			"43,12": "c16",
			"44,12": "c16",
			"45,12": "c16",
			"46,12": "c16",
			"47,12": "c16",
			"12,13": "c20",
			"13,13": "c20",
			"14,13": "c20",
			"15,13": "c20",
			"16,13": "c20",
			"17,13": "c158",
			"18,13": "c158",
			"19,13": "c158",
			"20,13": "c158",
			"21,13": "c158",
			"22,13": "c20",
			"23,13": "c20",
			"24,13": "c20",
			"25,13": "c20",
			"26,13": "c20",
			"27,13": "c187",
			"28,13": "c13",
			"29,13": "c13",
			"30,13": "c13",
			"31,13": "c13",
			"32,13": "c13",
			"33,13": "c158",
			"34,13": "c20",
			"35,13": "c20",
			"36,13": "c20",
			"37,13": "c20",
			"38,13": "c20",
			"39,13": "c20",
			"40,13": "c20",
			"41,13": "c20",
			"42,13": "c20",
			"43,13": "c20",
			"44,13": "c20",
			"45,13": "c20",
			"46,13": "c20",
			"47,13": "c20",
			"12,14": "c19",
			"13,14": "c19",
			"14,14": "c19",
			"15,14": "c22",
			"16,14": "c22",
			"17,14": "c22",
			"18,14": "c19",
			"19,14": "c19",
			"20,14": "c19",
			"21,14": "c19",
			"22,14": "c19",
			"23,14": "c22",
			"24,14": "c22",
			"25,14": "c22",
			"26,14": "c22",
			"27,14": "c187",
			"28,14": "c187",
			"29,14": "c187",
			"30,14": "c13",
			"31,14": "c13",
			"32,14": "c13",
			"33,14": "c19",
			"34,14": "c22",
			"35,14": "c22",
			"36,14": "c22",
			"37,14": "c22",
			"38,14": "c22",
			"39,14": "c22",
			"40,14": "c22",
			"41,14": "c22",
			"42,14": "c22",
			"43,14": "c22",
			"44,14": "c22",
			"45,14": "c22",
			"46,14": "c22",
			"47,14": "c22",
			"13,15": "c159",
			"14,15": "c159",
			"15,15": "c159",
			"16,15": "c159",
			"17,15": "c159",
			"18,15": "c159",
			"19,15": "c159",
			"20,15": "c159",
			"21,15": "c159",
			"22,15": "c159",
			"23,15": "c159",
			"24,15": "c24",
			"25,15": "c24",
			"26,15": "c24",
			"27,15": "c187",
			"28,15": "c187",
			"29,15": "c187",
			"30,15": "c187",
			"31,15": "c187",
			"32,15": "c187",
			"33,15": "c159",
			"34,15": "c24",
			"35,15": "c24",
			"36,15": "c24",
			"37,15": "c24",
			"38,15": "c24",
			"39,15": "c24",
			"40,15": "c24",
			"41,15": "c159",
			"42,15": "c24",
			"43,15": "c24",
			"44,15": "c159",
			"45,15": "c159",
			"46,15": "c159",
			"15,16": "c160",
			"16,16": "c160",
			"17,16": "c160",
			"18,16": "c160",
			"19,16": "c160",
			"20,16": "c160",
			"21,16": "c160",
			"22,16": "c160",
			"23,16": "c160",
			"24,16": "c160",
			"25,16": "c160",
			"26,16": "c160",
			"27,16": "c160",
			"28,16": "c160",
			"29,16": "c160",
			"30,16": "c160",
			"31,16": "c160",
			"32,16": "c160",
			"33,16": "c160",
			"34,16": "c26",
			"35,16": "c26",
			"36,16": "c26",
			"37,16": "c26",
			"38,16": "c26",
			"39,16": "c26",
			"40,16": "c26",
			"41,16": "c160",
			"42,16": "c160",
			"43,16": "c160",
			"44,16": "c160",
			"18,17": "c161",
			"19,17": "c161",
			"20,17": "c161",
			"21,17": "c161",
			"22,17": "c161",
			"23,17": "c161",
			"24,17": "c161",
			"25,17": "c161",
			"26,17": "c161",
			"27,17": "c187",
			"28,17": "c187",
			"29,17": "c187",
			"30,17": "c187",
			"31,17": "c187",
			"32,17": "c187",
			"33,17": "c161",
			"34,17": "c161",
			"35,17": "c27",
			"36,17": "c27",
			"37,17": "c27",
			"38,17": "c161",
			"39,17": "c161",
			"40,17": "c161",
			"41,17": "c161",
			"22,18": "c25",
			"23,18": "c25",
			"24,18": "c25",
			"25,18": "c25",
			"26,18": "c25",
			"27,18": "c25",
			"28,18": "c25",
			"29,18": "c25",
			"30,18": "c25",
			"31,18": "c25",
			"32,18": "c25",
			"33,18": "c25",
			"34,18": "c25",
			"35,18": "c25",
			"36,18": "c25",
			"37,18": "c25",
		},
		BgColors: nil,
	},
	{
		Duration: 125 * time.Millisecond,
		Content: []string{
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                         ▄████████▄                         ",
			"                      ████████████████▄                     ",
			"                    ██████████████████████                  ",
			"                  ██████████████████████████                ",
			"                 ███████████████████████████                ",
			"                 ███████████████████████████                ",
			"               ▄█████████████████████████████               ",
			"             ██████████████████████████████████▌            ",
			"            ███████████████████████████████████▐            ",
			"            ███████████████████████████████████▐            ",
			"            ███████████████████████████████████▐            ",
			"             ██████████████████████████████████▌            ",
			"               ▀█████████████████████████████               ",
			"                   ▀███████████████████████▀                ",
			"                          ▀▀▀██████████▀                    ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
		},
		FgColors: map[string]string{
			"25,4": "c0",
			"26,4": "c0",
			"27,4": "c0",
			"28,4": "c0",
			"29,4": "c0",
			"30,4": "c0",
			"31,4": "c0",
			"32,4": "c0",
			"33,4": "c0",
			"34,4": "c0",
			"22,5": "c220",
			"23,5": "c220",
			"24,5": "c220",
			"25,5": "c220",
			"26,5": "c220",
			"27,5": "c220",
			"28,5": "c220",
			"29,5": "c220",
			"30,5": "c220",
			"31,5": "c220",
			"32,5": "c220",
			"33,5": "c220",
			"34,5": "c220",
			"35,5": "c220",
			"36,5": "c220",
			"37,5": "c220",
			"38,5": "c2",
			"20,6": "c191",
			"21,6": "c191",
			"22,6": "c191",
			"23,6": "c191",
			"24,6": "c191",
			"25,6": "c191",
			"26,6": "c191",
			"27,6": "c191",
			"28,6": "c191",
			"29,6": "c191",
			"30,6": "c191",
			"31,6": "c191",
			"32,6": "c191",
			"33,6": "c191",
			"34,6": "c191",
			"35,6": "c191",
			"36,6": "c191",
			"37,6": "c191",
			"38,6": "c191",
			"39,6": "c191",
			"40,6": "c1",
			"41,6": "c1",
			"18,7": "c12",
			"19,7": "c221",
			"20,7": "c221",
			"21,7": "c221",
			"22,7": "c221",
			"23,7": "c221",
			"24,7": "c221",
			"25,7": "c221",
			"26,7": "c221",
			"27,7": "c221",
			"28,7": "c221",
			"29,7": "c221",
			"30,7": "c221",
			"31,7": "c221",
			"32,7": "c221",
			"33,7": "c221",
			"34,7": "c221",
			"35,7": "c221",
			"36,7": "c221",
			"37,7": "c221",
			"38,7": "c221",
			"39,7": "c221",
			"40,7": "c221",
			"41,7": "c221",
			"42,7": "c33",
			"43,7": "c187",
			"17,8": "c12",
			"18,8": "c194",
			"19,8": "c194",
			"20,8": "c194",
			"21,8": "c194",
			"22,8": "c194",
			"23,8": "c194",
			"24,8": "c194",
			"25,8": "c194",
			"26,8": "c194",
			"27,8": "c194",
			"28,8": "c194",
			"29,8": "c194",
			"30,8": "c194",
			"31,8": "c194",
			"32,8": "c194",
			"33,8": "c194",
			"34,8": "c194",
			"35,8": "c194",
			"36,8": "c194",
			"37,8": "c194",
			"38,8": "c194",
			"39,8": "c194",
			"40,8": "c194",
			"41,8": "c194",
			"42,8": "c194",
			"43,8": "c187",
			"17,9": "c222",
			"18,9": "c202",
			"19,9": "c202",
			"20,9": "c202",
			"21,9": "c202",
			"22,9": "c202",
			"23,9": "c202",
			"24,9": "c202",
			"25,9": "c202",
			"26,9": "c202",
			"27,9": "c202",
			"28,9": "c202",
			"29,9": "c202",
			"30,9": "c202",
			"31,9": "c202",
			"32,9": "c202",
			"33,9": "c202",
			"34,9": "c202",
			"35,9": "c202",
			"36,9": "c202",
			"37,9": "c202",
			"38,9": "c202",
			"39,9": "c202",
			"40,9": "c202",
			"41,9": "c202",
			"42,9": "c202",
			"43,9": "c202",
			"15,10": "c119",
			"16,10": "c119",
			"17,10": "c223",
			"18,10": "c119",
			"19,10": "c119",
			"20,10": "c119",
			"21,10": "c119",
			"22,10": "c119",
			"23,10": "c119",
			"24,10": "c119",
			"25,10": "c119",
			"26,10": "c119",
			"27,10": "c119",
			"28,10": "c119",
			"29,10": "c119",
			"30,10": "c119",
			"31,10": "c119",
			"32,10": "c119",
			"33,10": "c119",
			"34,10": "c119",
			"35,10": "c119",
			"36,10": "c119",
			"37,10": "c119",
			"38,10": "c119",
			"39,10": "c119",
			"40,10": "c119",
			"41,10": "c119",
			"42,10": "c119",
			"43,10": "c119",
			"44,10": "c119",
			"13,11": "c124",
			"14,11": "c124",
			"15,11": "c124",
			"16,11": "c124",
			"17,11": "c124",
			"18,11": "c124",
			"19,11": "c224",
			"20,11": "c124",
			"21,11": "c124",
			"22,11": "c124",
			"23,11": "c124",
			"24,11": "c187",
			"25,11": "c187",
			"26,11": "c39",
			"27,11": "c39",
			"28,11": "c39",
			"29,11": "c39",
			"30,11": "c224",
			"31,11": "c124",
			"32,11": "c124",
			"33,11": "c124",
			"34,11": "c124",
			"35,11": "c124",
			"36,11": "c124",
			"37,11": "c124",
			"38,11": "c124",
			"39,11": "c124",
			"40,11": "c124",
			"41,11": "c124",
			"42,11": "c124",
			"43,11": "c124",
			"44,11": "c124",
			"45,11": "c124",
			"46,11": "c124",
			"47,11": "c124",
			"12,12": "c225",
			"13,12": "c128",
			"14,12": "c128",
			"15,12": "c128",
			"16,12": "c128",
			"17,12": "c225",
			"18,12": "c225",
			"19,12": "c225",
			"20,12": "c225",
			"21,12": "c128",
			"22,12": "c128",
			"23,12": "c128",
			"24,12": "c128",
			"25,12": "c187",
			"26,12": "c13",
			"27,12": "c13",
			"28,12": "c13",
			"29,12": "c13",
			"30,12": "c225",
			"31,12": "c128",
			"32,12": "c128",
			"33,12": "c128",
			"34,12": "c128",
			"35,12": "c128",
			"36,12": "c128",
			"37,12": "c128",
			"38,12": "c128",
			"39,12": "c128",
			"40,12": "c128",
			"41,12": "c128",
			"42,12": "c128",
			"43,12": "c128",
			"44,12": "c128",
			"45,12": "c128",
			"46,12": "c128",
			"47,12": "c128",
			"12,13": "c19",
			"13,13": "c134",
			"14,13": "c134",
			"15,13": "c134",
			"16,13": "c19",
			"17,13": "c19",
			"18,13": "c19",
			"19,13": "c19",
			"20,13": "c19",
			"21,13": "c19",
			"22,13": "c19",
			"23,13": "c19",
			"24,13": "c134",
			"25,13": "c187",
			"26,13": "c187",
			"27,13": "c13",
			"28,13": "c13",
			"29,13": "c13",
			"30,13": "c19",
			"31,13": "c134",
			"32,13": "c134",
			"33,13": "c134",
			"34,13": "c134",
			"35,13": "c134",
			"36,13": "c134",
			"37,13": "c134",
			"38,13": "c134",
			"39,13": "c134",
			"40,13": "c134",
			"41,13": "c134",
			"42,13": "c134",
			"43,13": "c134",
			"44,13": "c134",
			"45,13": "c134",
			"46,13": "c134",
			"47,13": "c134",
			"12,14": "c226",
			"13,14": "c226",
			"14,14": "c226",
			"15,14": "c226",
			"16,14": "c226",
			"17,14": "c226",
			"18,14": "c226",
			"19,14": "c226",
			"20,14": "c226",
			"21,14": "c226",
			"22,14": "c226",
			"23,14": "c226",
			"24,14": "c139",
			"25,14": "c187",
			"26,14": "c187",
			"27,14": "c187",
			"28,14": "c187",
			"29,14": "c13",
			"30,14": "c226",
			"31,14": "c139",
			"32,14": "c139",
			"33,14": "c139",
			"34,14": "c139",
			"35,14": "c139",
			"36,14": "c139",
			"37,14": "c139",
			"38,14": "c139",
			"39,14": "c139",
			"40,14": "c139",
			"41,14": "c139",
			"42,14": "c139",
			"43,14": "c139",
			"44,14": "c139",
			"45,14": "c139",
			"46,14": "c139",
			"47,14": "c139",
			"13,15": "c227",
			"14,15": "c227",
			"15,15": "c227",
			"16,15": "c227",
			"17,15": "c227",
			"18,15": "c227",
			"19,15": "c227",
			"20,15": "c227",
			"21,15": "c227",
			"22,15": "c227",
			"23,15": "c227",
			"24,15": "c227",
			"25,15": "c187",
			"26,15": "c187",
			"27,15": "c187",
			"28,15": "c187",
			"29,15": "c187",
			"30,15": "c227",
			"31,15": "c143",
			"32,15": "c143",
			"33,15": "c143",
			"34,15": "c143",
			"35,15": "c143",
			"36,15": "c143",
			"37,15": "c143",
			"38,15": "c143",
			"39,15": "c143",
			"40,15": "c227",
			"41,15": "c143",
			"42,15": "c143",
			"43,15": "c227",
			"44,15": "c227",
			"45,15": "c227",
			"46,15": "c227",
			"47,15": "c143",
			"15,16": "c228",
			"16,16": "c228",
			"17,16": "c228",
			"18,16": "c228",
			"19,16": "c228",
			"20,16": "c228",
			"21,16": "c228",
			"22,16": "c228",
			"23,16": "c228",
			"24,16": "c228",
			"25,16": "c228",
			"26,16": "c228",
			"27,16": "c228",
			"28,16": "c228",
			"29,16": "c228",
			"30,16": "c228",
			"31,16": "c228",
			"32,16": "c229",
			"33,16": "c229",
			"34,16": "c229",
			"35,16": "c229",
			"36,16": "c229",
			"37,16": "c229",
			"38,16": "c229",
			"39,16": "c229",
			"40,16": "c228",
			"41,16": "c228",
			"42,16": "c228",
			"43,16": "c228",
			"44,16": "c228",
			"19,17": "c230",
			"20,17": "c230",
			"21,17": "c230",
			"22,17": "c230",
			"23,17": "c230",
			"24,17": "c230",
			"25,17": "c230",
			"26,17": "c230",
			"27,17": "c187",
			"28,17": "c187",
			"29,17": "c187",
			"30,17": "c187",
			"31,17": "c13",
			"32,17": "c187",
			"33,17": "c230",
			"34,17": "c231",
			"35,17": "c231",
			"36,17": "c231",
			"37,17": "c231",
			"38,17": "c231",
			"39,17": "c231",
			"40,17": "c230",
			"41,17": "c230",
			"42,17": "c230",
			"43,17": "c230",
			"26,18": "c25",
			"27,18": "c25",
			"28,18": "c25",
			"29,18": "c25",
			"30,18": "c25",
			"31,18": "c25",
			"32,18": "c25",
			"33,18": "c25",
			"34,18": "c25",
			"35,18": "c25",
			"36,18": "c25",
			"37,18": "c25",
			"38,18": "c25",
			"39,18": "c25",
		},
		BgColors: nil,
	},
	{
		Duration: 125 * time.Millisecond,
		Content: []string{
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                         ▄████████▄                         ",
			"                      ███████████████████                   ",
			"                   █████████████████████████                ",
			"                  ███████████████████████████               ",
			"                 █████████████████████████████              ",
			"                 ██████████████████████████████             ",
			"                 ██████████████████████████████             ",
			"                ██████████████████████████████              ",
			"               █████████████████████████████  ▌             ",
			"              █████████████████████████████   ▐             ",
			"              ██████████████████████████████  █             ",
			"               ███████████████████████████████▌             ",
			"                ▀████████████████████████████               ",
			"                     ▀██████████████████████                ",
			"                           ▀▀▀▀▀██████████                  ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
		},
		FgColors: map[string]string{
			"25,4": "c0",
			"26,4": "c0",
			"27,4": "c0",
			"28,4": "c0",
			"29,4": "c0",
			"30,4": "c0",
			"31,4": "c0",
			"32,4": "c0",
			"33,4": "c0",
			"34,4": "c0",
			"22,5": "c2",
			"23,5": "c2",
			"24,5": "c2",
			"25,5": "c2",
			"26,5": "c2",
			"27,5": "c2",
			"28,5": "c2",
			"29,5": "c2",
			"30,5": "c2",
			"31,5": "c2",
			"32,5": "c2",
			"33,5": "c2",
			"34,5": "c2",
			"35,5": "c2",
			"36,5": "c2",
			"37,5": "c2",
			"38,5": "c1",
			"39,5": "c1",
			"40,5": "c1",
			"19,6": "c153",
			"20,6": "c153",
			"21,6": "c153",
			"22,6": "c153",
			"23,6": "c153",
			"24,6": "c153",
			"25,6": "c153",
			"26,6": "c153",
			"27,6": "c153",
			"28,6": "c153",
			"29,6": "c153",
			"30,6": "c153",
			"31,6": "c153",
			"32,6": "c153",
			"33,6": "c153",
			"34,6": "c153",
			"35,6": "c153",
			"36,6": "c153",
			"37,6": "c153",
			"38,6": "c153",
			"39,6": "c153",
			"40,6": "c187",
			"41,6": "c179",
			"42,6": "c179",
			"43,6": "c179",
			"18,7": "c12",
			"19,7": "c154",
			"20,7": "c154",
			"21,7": "c154",
			"22,7": "c154",
			"23,7": "c154",
			"24,7": "c154",
			"25,7": "c154",
			"26,7": "c154",
			"27,7": "c154",
			"28,7": "c154",
			"29,7": "c154",
			"30,7": "c154",
			"31,7": "c154",
			"32,7": "c154",
			"33,7": "c154",
			"34,7": "c154",
			"35,7": "c154",
			"36,7": "c154",
			"37,7": "c154",
			"38,7": "c154",
			"39,7": "c154",
			"40,7": "c154",
			"41,7": "c154",
			"42,7": "c187",
			"43,7": "c181",
			"44,7": "c181",
			"17,8": "c12",
			"18,8": "c155",
			"19,8": "c155",
			"20,8": "c155",
			"21,8": "c155",
			"22,8": "c155",
			"23,8": "c155",
			"24,8": "c155",
			"25,8": "c155",
			"26,8": "c155",
			"27,8": "c155",
			"28,8": "c155",
			"29,8": "c155",
			"30,8": "c155",
			"31,8": "c155",
			"32,8": "c155",
			"33,8": "c155",
			"34,8": "c155",
			"35,8": "c155",
			"36,8": "c155",
			"37,8": "c155",
			"38,8": "c155",
			"39,8": "c155",
			"40,8": "c155",
			"41,8": "c155",
			"42,8": "c155",
			"43,8": "c187",
			"44,8": "c187",
			"45,8": "c187",
			"17,9": "c222",
			"18,9": "c43",
			"19,9": "c43",
			"20,9": "c43",
			"21,9": "c43",
			"22,9": "c43",
			"23,9": "c43",
			"24,9": "c43",
			"25,9": "c43",
			"26,9": "c43",
			"27,9": "c43",
			"28,9": "c43",
			"29,9": "c43",
			"30,9": "c43",
			"31,9": "c43",
			"32,9": "c43",
			"33,9": "c43",
			"34,9": "c43",
			"35,9": "c43",
			"36,9": "c43",
			"37,9": "c43",
			"38,9": "c43",
			"39,9": "c43",
			"40,9": "c43",
			"41,9": "c43",
			"42,9": "c43",
			"43,9": "c43",
			"44,9": "c222",
			"45,9": "c187",
			"46,9": "c187",
			"17,10": "c223",
			"18,10": "c11",
			"19,10": "c11",
			"20,10": "c11",
			"21,10": "c11",
			"22,10": "c11",
			"23,10": "c11",
			"24,10": "c11",
			"25,10": "c11",
			"26,10": "c11",
			"27,10": "c11",
			"28,10": "c11",
			"29,10": "c11",
			"30,10": "c11",
			"31,10": "c11",
			"32,10": "c11",
			"33,10": "c11",
			"34,10": "c11",
			"35,10": "c11",
			"36,10": "c11",
			"37,10": "c11",
			"38,10": "c11",
			"39,10": "c11",
			"40,10": "c11",
			"41,10": "c11",
			"42,10": "c11",
			"43,10": "c11",
			"44,10": "c11",
			"45,10": "c223",
			"46,10": "c187",
			"16,11": "c224",
			"17,11": "c224",
			"18,11": "c224",
			"19,11": "c14",
			"20,11": "c187",
			"21,11": "c187",
			"22,11": "c187",
			"23,11": "c182",
			"24,11": "c14",
			"25,11": "c14",
			"26,11": "c14",
			"27,11": "c14",
			"28,11": "c14",
			"29,11": "c14",
			"30,11": "c14",
			"31,11": "c14",
			"32,11": "c14",
			"33,11": "c14",
			"34,11": "c14",
			"35,11": "c14",
			"36,11": "c14",
			"37,11": "c14",
			"38,11": "c14",
			"39,11": "c14",
			"40,11": "c14",
			"41,11": "c14",
			"42,11": "c14",
			"43,11": "c14",
			"44,11": "c14",
			"45,11": "c14",
			"15,12": "c225",
			"16,12": "c225",
			"17,12": "c225",
			"18,12": "c225",
			"19,12": "c225",
			"20,12": "c187",
			"21,12": "c187",
			"22,12": "c187",
			"23,12": "c13",
			"24,12": "c16",
			"25,12": "c16",
			"26,12": "c16",
			"27,12": "c16",
			"28,12": "c16",
			"29,12": "c16",
			"30,12": "c16",
			"31,12": "c16",
			"32,12": "c16",
			"33,12": "c16",
			"34,12": "c16",
			"35,12": "c16",
			"36,12": "c16",
			"37,12": "c16",
			"38,12": "c16",
			"39,12": "c16",
			"40,12": "c16",
			"41,12": "c16",
			"42,12": "c16",
			"43,12": "c225",
			"46,12": "c16",
			"14,13": "c19",
			"15,13": "c19",
			"16,13": "c19",
			"17,13": "c19",
			"18,13": "c19",
			"19,13": "c19",
			"20,13": "c187",
			"21,13": "c187",
			"22,13": "c187",
			"23,13": "c187",
			"24,13": "c187",
			"25,13": "c20",
			"26,13": "c20",
			"27,13": "c20",
			"28,13": "c20",
			"29,13": "c20",
			"30,13": "c20",
			"31,13": "c20",
			"32,13": "c20",
			"33,13": "c20",
			"34,13": "c20",
			"35,13": "c20",
			"36,13": "c20",
			"37,13": "c20",
			"38,13": "c20",
			"39,13": "c20",
			"40,13": "c20",
			"41,13": "c20",
			"42,13": "c20",
			"46,13": "c20",
			"14,14": "c226",
			"15,14": "c226",
			"16,14": "c226",
			"17,14": "c226",
			"18,14": "c226",
			"19,14": "c226",
			"20,14": "c226",
			"21,14": "c187",
			"22,14": "c187",
			"23,14": "c187",
			"24,14": "c187",
			"25,14": "c22",
			"26,14": "c22",
			"27,14": "c22",
			"28,14": "c22",
			"29,14": "c22",
			"30,14": "c22",
			"31,14": "c22",
			"32,14": "c22",
			"33,14": "c22",
			"34,14": "c22",
			"35,14": "c22",
			"36,14": "c22",
			"37,14": "c22",
			"38,14": "c22",
			"39,14": "c22",
			"40,14": "c22",
			"41,14": "c22",
			"42,14": "c22",
			"43,14": "c22",
			"46,14": "c22",
			"15,15": "c227",
			"16,15": "c227",
			"17,15": "c227",
			"18,15": "c227",
			"19,15": "c227",
			"20,15": "c227",
			"21,15": "c227",
			"22,15": "c187",
			"23,15": "c187",
			"24,15": "c187",
			"25,15": "c187",
			"26,15": "c24",
			"27,15": "c24",
			"28,15": "c24",
			"29,15": "c24",
			"30,15": "c24",
			"31,15": "c24",
			"32,15": "c24",
			"33,15": "c24",
			"34,15": "c24",
			"35,15": "c24",
			"36,15": "c24",
			"37,15": "c227",
			"38,15": "c227",
			"39,15": "c24",
			"40,15": "c24",
			"41,15": "c24",
			"42,15": "c227",
			"43,15": "c227",
			"44,15": "c227",
			"45,15": "c227",
			"46,15": "c227",
			"16,16": "c228",
			"17,16": "c228",
			"18,16": "c228",
			"19,16": "c228",
			"20,16": "c228",
			"21,16": "c228",
			"22,16": "c228",
			"23,16": "c228",
			"24,16": "c228",
			"25,16": "c228",
			"26,16": "c228",
			"27,16": "c228",
			"28,16": "c228",
			"29,16": "c228",
			"30,16": "c228",
			"31,16": "c26",
			"32,16": "c26",
			"33,16": "c26",
			"34,16": "c26",
			"35,16": "c26",
			"36,16": "c228",
			"37,16": "c228",
			"38,16": "c228",
			"39,16": "c228",
			"40,16": "c228",
			"41,16": "c228",
			"42,16": "c228",
			"43,16": "c228",
			"44,16": "c228",
			"21,17": "c230",
			"22,17": "c230",
			"23,17": "c230",
			"24,17": "c230",
			"25,17": "c230",
			"26,17": "c187",
			"27,17": "c187",
			"28,17": "c187",
			"29,17": "c187",
			"30,17": "c187",
			"31,17": "c230",
			"32,17": "c230",
			"33,17": "c230",
			"34,17": "c230",
			"35,17": "c230",
			"36,17": "c230",
			"37,17": "c230",
			"38,17": "c230",
			"39,17": "c230",
			"40,17": "c230",
			"41,17": "c230",
			"42,17": "c230",
			"43,17": "c230",
			"27,18": "c25",
			"28,18": "c25",
			"29,18": "c25",
			"30,18": "c25",
			"31,18": "c25",
			"32,18": "c25",
			"33,18": "c25",
			"34,18": "c25",
			"35,18": "c25",
			"36,18": "c25",
			"37,18": "c25",
			"38,18": "c25",
			"39,18": "c25",
			"40,18": "c25",
			"41,18": "c25",
		},
		BgColors: nil,
	},
	{
		Duration: 125 * time.Millisecond,
		Content: []string{
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                         ▄████████▄                         ",
			"                     ▄███████████████▄ ███                  ",
			"                   █████████████████████████                ",
			"                  ███████████████████████████               ",
			"                 █████████████████████████████              ",
			"                 ██████████████████████████████             ",
			"                 ██████████████████████████████             ",
			"                ███████████████████████████████             ",
			"                █████████████████████████   ██              ",
			"                ████████████████████████     █              ",
			"                █████████████████████████   ██              ",
			"                 ████████████████████████████               ",
			"                  ███████████████████████████               ",
			"                       █████████████████████                ",
			"                           ▀▀▀▀▀▀▀█████████                 ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
		},
		FgColors: map[string]string{
			"25,4": "c28",
			"26,4": "c29",
			"27,4": "c30",
			"28,4": "c30",
			"29,4": "c31",
			"30,4": "c0",
			"31,4": "c0",
			"32,4": "c0",
			"33,4": "c0",
			"34,4": "c0",
			"21,5": "c193",
			"22,5": "c99",
			"23,5": "c100",
			"24,5": "c101",
			"25,5": "c102",
			"26,5": "c102",
			"27,5": "c183",
			"28,5": "c32",
			"29,5": "c184",
			"30,5": "c2",
			"31,5": "c185",
			"32,5": "c185",
			"33,5": "c186",
			"34,5": "c95",
			"35,5": "c96",
			"36,5": "c97",
			"37,5": "c2",
			"39,5": "c187",
			"40,5": "c232",
			"41,5": "c1",
			"19,6": "c199",
			"20,6": "c199",
			"21,6": "c188",
			"22,6": "c103",
			"23,6": "c104",
			"24,6": "c105",
			"25,6": "c106",
			"26,6": "c107",
			"27,6": "c108",
			"28,6": "c189",
			"29,6": "c153",
			"30,6": "c153",
			"31,6": "c190",
			"32,6": "c191",
			"33,6": "c192",
			"34,6": "c193",
			"35,6": "c193",
			"36,6": "c99",
			"37,6": "c100",
			"38,6": "c101",
			"39,6": "c102",
			"40,6": "c12",
			"41,6": "c233",
			"42,6": "c234",
			"43,6": "c235",
			"18,7": "c205",
			"19,7": "c206",
			"20,7": "c194",
			"21,7": "c195",
			"22,7": "c109",
			"23,7": "c109",
			"24,7": "c110",
			"25,7": "c111",
			"26,7": "c112",
			"27,7": "c113",
			"28,7": "c113",
			"29,7": "c196",
			"30,7": "c154",
			"31,7": "c197",
			"32,7": "c198",
			"33,7": "c199",
			"34,7": "c199",
			"35,7": "c188",
			"36,7": "c103",
			"37,7": "c104",
			"38,7": "c105",
			"39,7": "c106",
			"40,7": "c107",
			"41,7": "c12",
			"42,7": "c187",
			"43,7": "c236",
			"44,7": "c237",
			"17,8": "c12",
			"18,8": "c200",
			"19,8": "c201",
			"20,8": "c202",
			"21,8": "c114",
			"22,8": "c114",
			"23,8": "c115",
			"24,8": "c116",
			"25,8": "c117",
			"26,8": "c37",
			"27,8": "c37",
			"28,8": "c38",
			"29,8": "c203",
			"30,8": "c155",
			"31,8": "c204",
			"32,8": "c205",
			"33,8": "c206",
			"34,8": "c194",
			"35,8": "c195",
			"36,8": "c109",
			"37,8": "c109",
			"38,8": "c110",
			"39,8": "c111",
			"40,8": "c112",
			"41,8": "c113",
			"42,8": "c12",
			"43,8": "c187",
			"44,8": "c187",
			"45,8": "c187",
			"17,9": "c222",
			"18,9": "c52",
			"19,9": "c53",
			"20,9": "c118",
			"21,9": "c119",
			"22,9": "c120",
			"23,9": "c121",
			"24,9": "c122",
			"25,9": "c122",
			"26,9": "c40",
			"27,9": "c41",
			"28,9": "c42",
			"29,9": "c43",
			"30,9": "c44",
			"31,9": "c45",
			"32,9": "c200",
			"33,9": "c201",
			"34,9": "c202",
			"35,9": "c114",
			"36,9": "c114",
			"37,9": "c115",
			"38,9": "c116",
			"39,9": "c117",
			"40,9": "c37",
			"41,9": "c37",
			"42,9": "c38",
			"43,9": "c222",
			"44,9": "c187",
			"45,9": "c187",
			"46,9": "c187",
			"17,10": "c223",
			"18,10": "c61",
			"19,10": "c207",
			"20,10": "c208",
			"21,10": "c123",
			"22,10": "c124",
			"23,10": "c125",
			"24,10": "c125",
			"25,10": "c126",
			"26,10": "c48",
			"27,10": "c49",
			"28,10": "c50",
			"29,10": "c50",
			"30,10": "c11",
			"31,10": "c51",
			"32,10": "c52",
			"33,10": "c53",
			"34,10": "c118",
			"35,10": "c119",
			"36,10": "c120",
			"37,10": "c121",
			"38,10": "c122",
			"39,10": "c122",
			"40,10": "c40",
			"41,10": "c41",
			"42,10": "c42",
			"43,10": "c43",
			"44,10": "c223",
			"45,10": "c187",
			"46,10": "c187",
			"16,11": "c224",
			"17,11": "c224",
			"18,11": "c187",
			"19,11": "c187",
			"20,11": "c187",
			"21,11": "c187",
			"22,11": "c127",
			"23,11": "c128",
			"24,11": "c129",
			"25,11": "c130",
			"26,11": "c55",
			"27,11": "c56",
			"28,11": "c57",
			"29,11": "c58",
			"30,11": "c59",
			"31,11": "c60",
			"32,11": "c61",
			"33,11": "c207",
			"34,11": "c208",
			"35,11": "c123",
			"36,11": "c124",
			"37,11": "c125",
			"38,11": "c125",
			"39,11": "c126",
			"40,11": "c48",
			"41,11": "c49",
			"42,11": "c50",
			"43,11": "c50",
			"44,11": "c224",
			"45,11": "c187",
			"46,11": "c187",
			"16,12": "c225",
			"17,12": "c225",
			"18,12": "c225",
			"19,12": "c187",
			"20,12": "c187",
			"21,12": "c187",
			"22,12": "c132",
			"23,12": "c133",
			"24,12": "c134",
			"25,12": "c135",
			"26,12": "c64",
			"27,12": "c65",
			"28,12": "c46",
			"29,12": "c16",
			"30,12": "c47",
			"31,12": "c47",
			"32,12": "c66",
			"33,12": "c209",
			"34,12": "c210",
			"35,12": "c127",
			"36,12": "c127",
			"37,12": "c128",
			"38,12": "c129",
			"39,12": "c130",
			"40,12": "c55",
			"44,12": "c59",
			"45,12": "c225",
			"16,13": "c19",
			"17,13": "c19",
			"18,13": "c19",
			"19,13": "c187",
			"20,13": "c187",
			"21,13": "c187",
			"22,13": "c137",
			"23,13": "c138",
			"24,13": "c138",
			"25,13": "c139",
			"26,13": "c68",
			"27,13": "c211",
			"28,13": "c54",
			"29,13": "c69",
			"30,13": "c20",
			"31,13": "c70",
			"32,13": "c71",
			"33,13": "c212",
			"34,13": "c131",
			"35,13": "c131",
			"36,13": "c132",
			"37,13": "c133",
			"38,13": "c134",
			"39,13": "c135",
			"45,13": "c47",
			"16,14": "c226",
			"17,14": "c226",
			"18,14": "c226",
			"19,14": "c226",
			"20,14": "c187",
			"21,14": "c187",
			"22,14": "c187",
			"23,14": "c142",
			"24,14": "c213",
			"25,14": "c143",
			"26,14": "c73",
			"27,14": "c238",
			"28,14": "c62",
			"29,14": "c22",
			"30,14": "c63",
			"31,14": "c214",
			"32,14": "c215",
			"33,14": "c226",
			"34,14": "c226",
			"35,14": "c136",
			"36,14": "c137",
			"37,14": "c138",
			"38,14": "c138",
			"39,14": "c139",
			"40,14": "c68",
			"44,14": "c20",
			"45,14": "c70",
			"17,15": "c227",
			"18,15": "c227",
			"19,15": "c227",
			"20,15": "c227",
			"21,15": "c187",
			"22,15": "c187",
			"23,15": "c187",
			"24,15": "c78",
			"25,15": "c79",
			"26,15": "c79",
			"27,15": "c239",
			"28,15": "c227",
			"29,15": "c227",
			"30,15": "c227",
			"31,15": "c227",
			"32,15": "c227",
			"33,15": "c227",
			"34,15": "c227",
			"35,15": "c227",
			"36,15": "c142",
			"37,15": "c142",
			"38,15": "c213",
			"39,15": "c143",
			"40,15": "c73",
			"41,15": "c227",
			"42,15": "c227",
			"43,15": "c22",
			"44,15": "c63",
			"18,16": "c228",
			"19,16": "c228",
			"20,16": "c228",
			"21,16": "c228",
			"22,16": "c228",
			"23,16": "c228",
			"24,16": "c228",
			"25,16": "c228",
			"26,16": "c228",
			"27,16": "c228",
			"28,16": "c228",
			"29,16": "c228",
			"30,16": "c228",
			"31,16": "c228",
			"32,16": "c228",
			"33,16": "c228",
			"34,16": "c228",
			"35,16": "c228",
			"36,16": "c228",
			"37,16": "c228",
			"38,16": "c78",
			"39,16": "c79",
			"40,16": "c79",
			"41,16": "c239",
			"42,16": "c240",
			"43,16": "c24",
			"44,16": "c67",
			"23,17": "c230",
			"24,17": "c230",
			"25,17": "c230",
			"26,17": "c187",
			"27,17": "c187",
			"28,17": "c187",
			"29,17": "c230",
			"30,17": "c230",
			"31,17": "c230",
			"32,17": "c230",
			"33,17": "c230",
			"34,17": "c230",
			"35,17": "c230",
			"36,17": "c230",
			"37,17": "c230",
			"38,17": "c230",
			"39,17": "c230",
			"40,17": "c230",
			"41,17": "c231",
			"42,17": "c241",
			"43,17": "c230",
			"27,18": "c25",
			"28,18": "c25",
			"29,18": "c25",
			"30,18": "c25",
			"31,18": "c25",
			"32,18": "c25",
			"33,18": "c25",
			"34,18": "c25",
			"35,18": "c25",
			"36,18": "c25",
			"37,18": "c25",
			"38,18": "c25",
			"39,18": "c25",
			"40,18": "c25",
			"41,18": "c25",
			"42,18": "c25",
		},
		BgColors: nil,
	},
	{
		Duration: 125 * time.Millisecond,
		Content: []string{
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                         ▄████████▄▄                        ",
			"                     ▄████████████████ ███                  ",
			"                   █████████████████████████                ",
			"                  ███████████████████████████               ",
			"                 ████████████████████████████               ",
			"                 █████████████████████████████              ",
			"                 ████████████████████████ █████             ",
			"                █████████████████████████   ███             ",
			"                ██████████████    ███████   ▐               ",
			"                 ████████████      ██████   ▌               ",
			"                  ████████████    ███████   ▌               ",
			"                   ██████████████████████   ▌               ",
			"                     █████████████████████  ▌               ",
			"                         ███████████████████                ",
			"                            ▀▀▀▀▀▀▀▀▀▀▀████                 ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
			"                                                            ",
		},
		FgColors: map[string]string{
			"25,4": "c0",
			"26,4": "c0",
			"27,4": "c0",
			"28,4": "c0",
			"29,4": "c0",
			"30,4": "c31",
			"31,4": "c242",
			"32,4": "c30",
			"33,4": "c29",
			"34,4": "c243",
			"35,4": "c28",
			"21,5": "c93",
			"22,5": "c98",
			"23,5": "c97",
			"24,5": "c96",
			"25,5": "c95",
			"26,5": "c244",
			"27,5": "c186",
			"28,5": "c185",
			"29,5": "c220",
			"30,5": "c2",
			"31,5": "c184",
			"32,5": "c32",
			"33,5": "c245",
			"34,5": "c183",
			"35,5": "c102",
			"36,5": "c246",
			"37,5": "c101",
			"39,5": "c1",
			"40,5": "c1",
			"41,5": "c1",
			"19,6": "c183",
			"20,6": "c102",
			"21,6": "c246",
			"22,6": "c101",
			"23,6": "c100",
			"24,6": "c99",
			"25,6": "c247",
			"26,6": "c193",
			"27,6": "c248",
			"28,6": "c192",
			"29,6": "c191",
			"30,6": "c190",
			"31,6": "c249",
			"32,6": "c153",
			"33,6": "c189",
			"34,6": "c250",
			"35,6": "c108",
			"36,6": "c107",
			"37,6": "c12",
			"38,6": "c187",
			"39,6": "c187",
			"40,6": "c179",
			"41,6": "c179",
			"42,6": "c187",
			"43,6": "c187",
			"18,7": "c189",
			"19,7": "c250",
			"20,7": "c108",
			"21,7": "c107",
			"22,7": "c106",
			"23,7": "c105",
			"24,7": "c104",
			"25,7": "c103",
			"26,7": "c251",
			"27,7": "c188",
			"28,7": "c199",
			"29,7": "c221",
			"30,7": "c198",
			"31,7": "c197",
			"32,7": "c154",
			"33,7": "c252",
			"34,7": "c196",
			"35,7": "c113",
			"36,7": "c253",
			"37,7": "c12",
			"38,7": "c12",
			"39,7": "c187",
			"40,7": "c187",
			"41,7": "c181",
			"42,7": "c181",
			"43,7": "c181",
			"44,7": "c181",
			"17,8": "c12",
			"18,8": "c252",
			"19,8": "c196",
			"20,8": "c113",
			"21,8": "c253",
			"22,8": "c112",
			"23,8": "c111",
			"24,8": "c110",
			"25,8": "c254",
			"26,8": "c109",
			"27,8": "c195",
			"28,8": "c255",
			"29,8": "c194",
			"30,8": "c206",
			"31,8": "c205",
			"32,8": "c204",
			"33,8": "c155",
			"34,8": "c203",
			"35,8": "c256",
			"36,8": "c38",
			"37,8": "c37",
			"38,8": "c12",
			"39,8": "c12",
			"40,8": "c187",
			"41,8": "c187",
			"42,8": "c257",
			"43,8": "c257",
			"44,8": "c257",
			"17,9": "c222",
			"18,9": "c155",
			"19,9": "c203",
			"20,9": "c256",
			"21,9": "c38",
			"22,9": "c37",
			"23,9": "c258",
			"24,9": "c117",
			"25,9": "c116",
			"26,9": "c115",
			"27,9": "c259",
			"28,9": "c114",
			"29,9": "c202",
			"30,9": "c260",
			"31,9": "c201",
			"32,9": "c200",
			"33,9": "c45",
			"34,9": "c44",
			"35,9": "c43",
			"36,9": "c42",
			"37,9": "c261",
			"38,9": "c41",
			"39,9": "c222",
			"40,9": "c222",
			"41,9": "c187",
			"42,9": "c187",
			"43,9": "c262",
			"44,9": "c262",
			"45,9": "c262",
			"17,10": "c223",
			"18,10": "c45",
			"19,10": "c44",
			"20,10": "c43",
			"21,10": "c42",
			"22,10": "c261",
			"23,10": "c41",
			"24,10": "c40",
			"25,10": "c263",
			"26,10": "c122",
			"27,10": "c121",
			"28,10": "c264",
			"29,10": "c120",
			"30,10": "c119",
			"31,10": "c118",
			"32,10": "c53",
			"33,10": "c52",
			"34,10": "c51",
			"35,10": "c265",
			"36,10": "c11",
			"37,10": "c50",
			"38,10": "c266",
			"39,10": "c49",
			"40,10": "c223",
			"42,10": "c187",
			"43,10": "c187",
			"44,10": "c187",
			"45,10": "c187",
			"46,10": "c267",
			"16,11": "c224",
			"17,11": "c224",
			"18,11": "c224",
			"19,11": "c51",
			"20,11": "c265",
			"21,11": "c11",
			"22,11": "c50",
			"23,11": "c266",
			"24,11": "c49",
			"25,11": "c48",
			"26,11": "c126",
			"27,11": "c268",
			"28,11": "c125",
			"29,11": "c124",
			"30,11": "c269",
			"31,11": "c123",
			"32,11": "c208",
			"33,11": "c207",
			"34,11": "c61",
			"35,11": "c60",
			"36,11": "c59",
			"37,11": "c14",
			"38,11": "c58",
			"39,11": "c57",
			"40,11": "c56",
			"44,11": "c187",
			"45,11": "c187",
			"46,11": "c187",
			"16,12": "c225",
			"17,12": "c225",
			"18,12": "c225",
			"19,12": "c225",
			"20,12": "c60",
			"21,12": "c59",
			"22,12": "c14",
			"23,12": "c58",
			"24,12": "c225",
			"25,12": "c225",
			"26,12": "c55",
			"27,12": "c130",
			"28,12": "c129",
			"29,12": "c270",
			"34,12": "c209",
			"35,12": "c66",
			"36,12": "c271",
			"37,12": "c47",
			"38,12": "c16",
			"39,12": "c272",
			"40,12": "c46",
			"44,12": "c134",
			"17,13": "c19",
			"18,13": "c19",
			"19,13": "c19",
			"20,13": "c19",
			"21,13": "c19",
			"22,13": "c19",
			"23,13": "c19",
			"24,13": "c19",
			"25,13": "c19",
			"26,13": "c19",
			"27,13": "c19",
			"28,13": "c135",
			"35,13": "c212",
			"36,13": "c71",
			"37,13": "c273",
			"38,13": "c70",
			"39,13": "c20",
			"40,13": "c69",
			"44,13": "c274",
			"18,14": "c226",
			"19,14": "c226",
			"20,14": "c226",
			"21,14": "c226",
			"22,14": "c226",
			"23,14": "c226",
			"24,14": "c226",
			"25,14": "c226",
			"26,14": "c226",
			"27,14": "c226",
			"28,14": "c226",
			"29,14": "c226",
			"34,14": "c136",
			"35,14": "c216",
			"36,14": "c275",
			"37,14": "c215",
			"38,14": "c214",
			"39,14": "c276",
			"40,14": "c63",
			"44,14": "c73",
			"19,15": "c227",
			"20,15": "c227",
			"21,15": "c227",
			"22,15": "c227",
			"23,15": "c227",
			"24,15": "c227",
			"25,15": "c227",
			"26,15": "c227",
			"27,15": "c227",
			"28,15": "c227",
			"29,15": "c227",
			"30,15": "c227",
			"31,15": "c227",
			"32,15": "c227",
			"33,15": "c227",
			"34,15": "c277",
			"35,15": "c141",
			"36,15": "c140",
			"37,15": "c218",
			"38,15": "c278",
			"39,15": "c217",
			"40,15": "c67",
			"44,15": "c239",
			"21,16": "c228",
			"22,16": "c228",
			"23,16": "c228",
			"24,16": "c228",
			"25,16": "c228",
			"26,16": "c228",
			"27,16": "c228",
			"28,16": "c228",
			"29,16": "c228",
			"30,16": "c228",
			"31,16": "c228",
			"32,16": "c228",
			"33,16": "c228",
			"34,16": "c228",
			"35,16": "c148",
			"36,16": "c147",
			"37,16": "c146",
			"38,16": "c145",
			"39,16": "c144",
			"40,16": "c279",
			"41,16": "c72",
			"44,16": "c241",
			"25,17": "c230",
			"26,17": "c230",
			"27,17": "c230",
			"28,17": "c230",
			"29,17": "c230",
			"30,17": "c230",
			"31,17": "c230",
			"32,17": "c230",
			"33,17": "c230",
			"34,17": "c230",
			"35,17": "c230",
			"36,17": "c90",
			"37,17": "c89",
			"38,17": "c280",
			"39,17": "c76",
			"40,17": "c75",
			"41,17": "c281",
			"42,17": "c74",
			"43,17": "c230",
			"28,18": "c25",
			"29,18": "c25",
			"30,18": "c25",
			"31,18": "c25",
			"32,18": "c25",
			"33,18": "c25",
			"34,18": "c25",
			"35,18": "c25",
			"36,18": "c25",
			"37,18": "c25",
			"38,18": "c25",
Download .txt
gitextract_bzvznlar/

├── .gitignore
├── .gitmodules
├── CONTRIBUTING.md
├── COPILOT_INSTRUCTIONS.md
├── LICENSE-MIT
├── LICENSE-PREMIUM
├── README.md
├── api/
│   └── og.ts
├── components.json
├── dev-tools/
│   ├── README.md
│   ├── bubbletea-test-cli/
│   │   ├── README.md
│   │   ├── animations/
│   │   │   ├── ascii_motion_anim.go
│   │   │   ├── copilotspin/
│   │   │   │   └── copilot_spin.go
│   │   │   ├── effects/
│   │   │   │   └── ascii_motion_anim_effects.go
│   │   │   ├── effects2/
│   │   │   │   └── ascii_motion_anim_effects2.go
│   │   │   ├── effects3/
│   │   │   │   └── ascii_motion_anim_effects3.go
│   │   │   └── newtest/
│   │   │       └── ascii_motion_anim_new.go
│   │   ├── go.mod
│   │   ├── go.sum
│   │   └── main.go
│   ├── clipboard-test.js
│   ├── debug-video-export.js
│   ├── font-test.html
│   ├── gridColorTest.ts
│   ├── ink-test-cli/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── ascii-motion-cli-effects.tsx
│   │   │   ├── ascii-motion-cli_256.tsx
│   │   │   └── cli.tsx
│   │   └── tsconfig.json
│   ├── opentui-test-cli/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── ascii-motion-opentui-hex.tsx
│   │   │   ├── ascii-motion-tui-ansi2.tsx
│   │   │   ├── ascii-motion-tui-effects.tsx
│   │   │   ├── ascii-motion-tui-semantic.tsx
│   │   │   ├── ascii-motion-tui.tsx
│   │   │   ├── ascii-motion-tui2.tsx
│   │   │   ├── cli.tsx
│   │   │   ├── fish-animation-256.tsx
│   │   │   └── fish-animation.tsx
│   │   └── tsconfig.json
│   ├── react-export-test/
│   │   ├── README.md
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── App.tsx
│   │   │   ├── ascii-motion-animation-effects.tsx
│   │   │   ├── ascii-motion-animation-new.tsx
│   │   │   ├── ascii-motion-animation.tsx
│   │   │   ├── main.tsx
│   │   │   ├── shader-test-01.tsx
│   │   │   ├── shader-test-02.tsx
│   │   │   └── vite-env.d.ts
│   │   ├── tsconfig.json
│   │   └── vite.config.ts
│   ├── sample-json-export.json
│   ├── test-frame-timing.js
│   ├── test-ibm-vga-font.html
│   ├── test-json-html-export.js
│   ├── test-palette.json
│   ├── test-sf-mono.html
│   ├── test-video-export.js
│   └── test-video-loops.js
├── docs/
│   ├── ADDING_CUSTOM_FONTS.md
│   ├── ADDING_FEATURES_TO_PROJECT_SYSTEM.md
│   ├── ANIMATION_PLAYBACK_OPTIMIZATION.md
│   ├── ANIMATION_PLAYBACK_OPTIMIZATION_PLAN.md
│   ├── ANIMATION_SYSTEM_GUIDE.md
│   ├── ASCII_BOX_TOOL_IMPLEMENTATION_PLAN.md
│   ├── ASCII_TYPE_TOOL_IMPLEMENTATION_PLAN.md
│   ├── BEZIER_GRANULAR_UNDO_IMPLEMENTATION.md
│   ├── BEZIER_SHAPE_TOOL_IMPLEMENTATION_PLAN.md
│   ├── BRUSH_HOVER_PREVIEW_PLAN.md
│   ├── BRUSH_TOOL_USER_GUIDE.md
│   ├── BUBBLETEA_EXPORT_IMPLEMENTATION_PLAN.md
│   ├── BUILD_FIXES.md
│   ├── CANVAS_RENDERING_IMPROVEMENTS.md
│   ├── CANVAS_TEXT_RENDERING.md
│   ├── COEP_CONFIGURATION_GUIDE.md
│   ├── COEP_TROUBLESHOOTING_GUIDE.md
│   ├── COLOR_PALETTE_OVERHAUL_PLAN.md
│   ├── CROP_CANVAS_TO_SELECTION.md
│   ├── DIALOG_COMPONENT_AUDIT.md
│   ├── DIALOG_CONSISTENCY_UPDATE.md
│   ├── DIGITAL_RAIN_GENERATOR_IMPLEMENTATION.md
│   ├── DITHERING_ANALYSIS_AND_PLAN.md
│   ├── DITHERING_IMPLEMENTATION_SUMMARY.md
│   ├── DITHERING_QUICK_REFERENCE.md
│   ├── DRAGGABLE_PICKERS_IMPLEMENTATION.md
│   ├── DRAWING_GAP_FIX.md
│   ├── EFFECTS_DEVELOPER_GUIDE.md
│   ├── EFFECTS_IMPLEMENTATION_SUMMARY.md
│   ├── EFFECTS_SYSTEM_IMPLEMENTATION.md
│   ├── EFFECTS_SYSTEM_USER_GUIDE.md
│   ├── ELLIPSE_RADIAL_GRADIENTS.md
│   ├── EXPORT_METADATA_AUDIT_COMPLETE.md
│   ├── FIGMA_COMPONENT_RECREATION_GUIDE.md
│   ├── FIGMA_DESIGN_SYSTEM_SETUP.md
│   ├── FIGMA_MCP_WORKFLOW_GUIDE.md
│   ├── FIGMA_REACT_DIALOG_REDESIGN_MASTER_GUIDE.md
│   ├── FIGMA_WORKFLOW_IMPLEMENTATION_SUMMARY.md
│   ├── FIGMA_WORKFLOW_README.md
│   ├── FONT_QUICK_REFERENCE.md
│   ├── FONT_SELECTION_IMPLEMENTATION_PLAN.md
│   ├── FONT_SYSTEM_IMPLEMENTATION_PLAN.md
│   ├── FRAME_SYNCHRONIZATION_DEBUGGING_GUIDE.md
│   ├── GENERATORS_IMPLEMENTATION_PLAN.md
│   ├── GENERATOR_CANVAS_PREVIEW_OPTIMIZATION.md
│   ├── GENERATOR_PREVIEW_RACE_CONDITION_FIX.md
│   ├── GIT_SUBMODULE_SETUP.md
│   ├── GRADIENT_FILL_IMPLEMENTATION.md
│   ├── GRID_OPACITY_IMPROVEMENTS.md
│   ├── INK_COMPONENT_EXPORT_IMPLEMENTATION_PLAN.md
│   ├── LAYER_TIMELINE_OPTIMIZATIONS.md
│   ├── LAYER_TIMELINE_REFACTOR_PLAN.md
│   ├── LOGGING_CLEANUP_SUMMARY.md
│   ├── MCP_GUIDE_RESOURCE_CODE.ts
│   ├── MCP_LLM_USAGE_GUIDE.md
│   ├── MCP_SERVER_IMPLEMENTATION_PLAN.md
│   ├── MEDIA_IMPORT_ANALYSIS.md
│   ├── MEDIA_IMPORT_FIXES_COMPLETE.md
│   ├── MEDIA_IMPORT_HISTORY_INTEGRATION.md
│   ├── MONOREPO_QUICK_REFERENCE.md
│   ├── MONOREPO_SETUP_COMPLETE.md
│   ├── MONOREPO_SETUP_GUIDE.md
│   ├── MULTI_FRAME_SELECTION_IMPLEMENTATION_PLAN.md
│   ├── MULTI_FRAME_SELECTION_MANUAL_TEST_PLAN.md
│   ├── ONION_SKINNING_GUIDE.md
│   ├── OPENTUI_COMPONENT_EXPORT_IMPLEMENTATION_PLAN.md
│   ├── OPEN_SOURCE_SECURITY_STRATEGY.md
│   ├── OS_CLIPBOARD_TESTING.md
│   ├── PALETTE_REMAP_IMPLEMENTATION.md
│   ├── PASTE_FUNCTIONALITY_TEST.md
│   ├── PERFORMANCE_ANALYSIS_REPORT.md
│   ├── PERFORMANCE_OPTIMIZATION.md
│   ├── PERFORMANCE_OPTIMIZATION_ACTION_PLAN.md
│   ├── PERFORMANCE_OPTIMIZATION_PHASE1.md
│   ├── PERMANENT_DELETE_RLS_FIX.md
│   ├── PERSISTENT_SELECTION_IMPLEMENTATION_PLAN.md
│   ├── PHASE_4_ADVANCED_TOOLS_PLAN.md
│   ├── POST_EFFECTS_DEVELOPER_GUIDE.md
│   ├── POST_EFFECTS_USER_GUIDE.md
│   ├── PREMIUM_DOCS_MOVED.md
│   ├── PRIVACY_POLICY.md
│   ├── PROCEDURAL_EFFECTS_HANDOFF.md
│   ├── PROJECT_MANAGEMENT_ENHANCEMENT_PLAN.md
│   ├── REACT_COMPONENT_EXPORT_IMPLEMENTATION_PLAN.md
│   ├── README.md
│   ├── RESPONSIVE_TESTING_CHECKLIST.md
│   ├── SCATTER_BLEND_COLORS_FEATURE.md
│   ├── SCATTER_EFFECT_FINAL_IMPLEMENTATION.md
│   ├── SECURITY_HEADERS_INDEX.md
│   ├── SECURITY_REVIEW.md
│   ├── SHARED_UI_COMPONENTS_PATTERN.md
│   ├── SVG_EXPORT_IMPLEMENTATION_PLAN.md
│   ├── SVG_TEXT_TO_OUTLINES_IMPLEMENTATION_PLAN.md
│   ├── SVG_TEXT_TO_OUTLINES_IMPLEMENTATION_SUMMARY.md
│   ├── TAB_ORDER_STRATEGY.md
│   ├── TERMS_OF_SERVICE.md
│   ├── TIME_EFFECTS_IMPLEMENTATION_PLAN.md
│   ├── TOOL_BEHAVIOR_IMPLEMENTATION.md
│   ├── TYPOGRAPHY_IMPLEMENTATION.md
│   ├── UI_COMPONENTS_DESIGN_SYSTEM.md
│   ├── UNDO_REDO_BUG_FIXES.md
│   ├── VERCEL_JSON_REFERENCE.md
│   ├── WIDTH_HEIGHT_INPUT_FIX.md
│   └── timanthes.txt
├── eslint.config.js
├── index.html
├── package.json
├── packages/
│   └── core/
│       ├── package.json
│       ├── src/
│       │   ├── components/
│       │   │   ├── index.ts
│       │   │   └── ui/
│       │   │       ├── alert.tsx
│       │   │       ├── badge.tsx
│       │   │       ├── button.tsx
│       │   │       ├── card.tsx
│       │   │       ├── checkbox.tsx
│       │   │       ├── collapsible.tsx
│       │   │       ├── dialog.tsx
│       │   │       ├── dropdown-menu.tsx
│       │   │       ├── input.tsx
│       │   │       ├── label.tsx
│       │   │       ├── menubar.tsx
│       │   │       ├── popover.tsx
│       │   │       ├── progress.tsx
│       │   │       ├── scroll-area.tsx
│       │   │       ├── select.tsx
│       │   │       ├── separator.tsx
│       │   │       ├── sheet.tsx
│       │   │       ├── skeleton.tsx
│       │   │       ├── slider.tsx
│       │   │       ├── switch.tsx
│       │   │       ├── tabs.tsx
│       │   │       ├── textarea.tsx
│       │   │       ├── toggle.tsx
│       │   │       └── tooltip.tsx
│       │   ├── index.ts
│       │   └── lib/
│       │       └── utils.ts
│       └── tsconfig.json
├── postcss.config.js
├── public/
│   ├── ffmpeg/
│   │   ├── ffmpeg-core.js
│   │   └── ffmpeg-core.wasm
│   ├── fonts/
│   │   └── jetbrains-mono/
│   │       └── LICENSE.txt
│   └── site.webmanifest
├── scripts/
│   ├── check-licenses.js
│   ├── create_mcp_guide.py
│   ├── download-fonts.sh
│   ├── extract-logo-frames.js
│   ├── migrate-to-monorepo.js
│   ├── setup-premium-submodule.sh
│   ├── update_mcp_resources.py
│   └── version-bump.js
├── src/
│   ├── App.css
│   ├── App.tsx
│   ├── __tests__/
│   │   ├── canvasStoreLayerSync.test.ts
│   │   ├── easing.test.ts
│   │   ├── effectBlocks.test.ts
│   │   ├── effectRegistry.test.ts
│   │   ├── effectsPipeline.test.ts
│   │   ├── layerCompositing.test.ts
│   │   ├── layerLimits.test.ts
│   │   ├── phase5ExportMigration.test.ts
│   │   ├── phase6Integration.test.ts
│   │   ├── sessionMigration.test.ts
│   │   ├── timelineStore.test.ts
│   │   ├── timelineUI.test.ts
│   │   └── useTimelineHistory.test.ts
│   ├── components/
│   │   ├── common/
│   │   │   ├── AppReveal.tsx
│   │   │   ├── AsciiMotionLogo.tsx
│   │   │   ├── CellRenderer.tsx
│   │   │   ├── CollapsibleHeader.tsx
│   │   │   ├── CollapsiblePanel.tsx
│   │   │   ├── ColorSwatch.tsx
│   │   │   ├── DraggableDialogBar.tsx
│   │   │   ├── MouseCoordinates.tsx
│   │   │   ├── PanelSeparator.tsx
│   │   │   ├── PanelToggleButton.tsx
│   │   │   ├── PerformanceMonitor.tsx
│   │   │   ├── PerformanceOverlay.tsx
│   │   │   ├── Spinner.tsx
│   │   │   ├── ThemeToggle.tsx
│   │   │   └── VersionDisplay.tsx
│   │   ├── demos/
│   │   │   └── SimpleAsciiDemo.tsx
│   │   ├── features/
│   │   │   ├── AboutDialog.tsx
│   │   │   ├── AccountButton.tsx
│   │   │   ├── ActiveLayerIndicator.tsx
│   │   │   ├── ActiveStyleSection.tsx
│   │   │   ├── AnchorPointOverlay.tsx
│   │   │   ├── AsciiBoxPanel.tsx
│   │   │   ├── AsciiTypePanel.tsx
│   │   │   ├── AsciiTypePreviewDialog.tsx
│   │   │   ├── AuthButtons.tsx
│   │   │   ├── BackgroundColorMappingSection.tsx
│   │   │   ├── BezierActionButtons.tsx
│   │   │   ├── BrushControls.tsx
│   │   │   ├── BrushPreview.tsx
│   │   │   ├── BrushSizePreviewOverlay.tsx
│   │   │   ├── BubbleteaExportDialog.tsx
│   │   │   ├── CanvasActionButtons.tsx
│   │   │   ├── CanvasGrid.tsx
│   │   │   ├── CanvasOverlay.tsx
│   │   │   ├── CanvasRenderer.tsx
│   │   │   ├── CanvasResizeDialog.tsx
│   │   │   ├── CanvasSettings.tsx
│   │   │   ├── CanvasSizePicker.tsx
│   │   │   ├── CanvasWithShortcuts.tsx
│   │   │   ├── CharacterMappingControls.tsx
│   │   │   ├── CharacterMappingSection.tsx
│   │   │   ├── CharacterPalette.tsx
│   │   │   ├── CharacterPaletteEditor.tsx
│   │   │   ├── ColorPicker.tsx
│   │   │   ├── ColorPickerOverlay.tsx
│   │   │   ├── ColorPicker_new.tsx
│   │   │   ├── ColorReadout.tsx
│   │   │   ├── EffectsSection.tsx
│   │   │   ├── EnhancedCharacterPicker.tsx
│   │   │   ├── ExportCharacterPaletteDialog.tsx
│   │   │   ├── ExportImportButtons.tsx
│   │   │   ├── ExportPaletteDialog.tsx
│   │   │   ├── ForegroundBackgroundSelector.tsx
│   │   │   ├── FullscreenToggle.tsx
│   │   │   ├── GalleryMobileMenu.tsx
│   │   │   ├── GeneratorsPanel.tsx
│   │   │   ├── GeneratorsSection.tsx
│   │   │   ├── GradientPanel.tsx
│   │   │   ├── GradientPropertyPreview.tsx
│   │   │   ├── GradientStopPicker.tsx
│   │   │   ├── HamburgerMenu.tsx
│   │   │   ├── HtmlExportDialog.tsx
│   │   │   ├── ImageExportDialog.tsx
│   │   │   ├── ImportCharacterPaletteDialog.tsx
│   │   │   ├── ImportModal.tsx
│   │   │   ├── ImportPaletteDialog.tsx
│   │   │   ├── InkExportDialog.tsx
│   │   │   ├── InlineProjectNameEditor.tsx
│   │   │   ├── InteractiveBezierOverlay.tsx
│   │   │   ├── InteractiveGradientOverlay.tsx
│   │   │   ├── InteractiveVectorShapeOverlay.tsx
│   │   │   ├── JsonExportDialog.tsx
│   │   │   ├── KeyboardShortcutsDialog.tsx
│   │   │   ├── LayerTransformOverlay.tsx
│   │   │   ├── MCPConnectionDialog.tsx
│   │   │   ├── MainCharacterPaletteSection.tsx
│   │   │   ├── ManageCharacterPalettesDialog.tsx
│   │   │   ├── ManagePalettesDialog.tsx
│   │   │   ├── MediaImportPanel.tsx
│   │   │   ├── MobileDialog.tsx
│   │   │   ├── NewProjectDialog.tsx
│   │   │   ├── OnionSkinControls.tsx
│   │   │   ├── OpenTuiExportDialog.tsx
│   │   │   ├── PastePreviewOverlay.tsx
│   │   │   ├── PlaybackControls.tsx
│   │   │   ├── PlaybackOverlay.tsx
│   │   │   ├── PlaybackStatusBar.tsx
│   │   │   ├── PostEffectsSection.tsx
│   │   │   ├── PreprocessingSection.tsx
│   │   │   ├── ProjectCanvasPreview.tsx
│   │   │   ├── ProjectSettingsDialog.tsx
│   │   │   ├── ProjectsDialog.tsx
│   │   │   ├── PublishToGalleryDialogWrapper.tsx
│   │   │   ├── PublishedProjectSaveWarningDialog.tsx
│   │   │   ├── ReactExportDialog.tsx
│   │   │   ├── SaveToCloudDialog.tsx
│   │   │   ├── SessionExportDialog.tsx
│   │   │   ├── SilentSaveHandler.tsx
│   │   │   ├── TextColorMappingSection.tsx
│   │   │   ├── TextExportDialog.tsx
│   │   │   ├── TimelinePanel.tsx
│   │   │   ├── ToolBehaviorSettings.tsx
│   │   │   ├── ToolManager.tsx
│   │   │   ├── ToolPalette.tsx
│   │   │   ├── ToolPalette_backup.tsx
│   │   │   ├── ToolPalette_new.tsx
│   │   │   ├── ToolStatusManager.tsx
│   │   │   ├── TransparencySection.tsx
│   │   │   ├── UpgradeToProDialog.tsx
│   │   │   ├── VideoExportDialog.tsx
│   │   │   ├── WelcomeAsciiAnimation.tsx
│   │   │   ├── WelcomeAsciiAnimationData.tsx
│   │   │   ├── WelcomeDialog.tsx
│   │   │   ├── ZoomControls.tsx
│   │   │   ├── generators/
│   │   │   │   ├── DigitalRainSettings.tsx
│   │   │   │   ├── GeneratorsMappingTab.tsx
│   │   │   │   ├── ParticlePhysicsSettings.tsx
│   │   │   │   ├── PlaceholderGeneratorSettings.tsx
│   │   │   │   ├── RadioWavesSettings.tsx
│   │   │   │   ├── RainDropsSettings.tsx
│   │   │   │   └── TurbulentNoiseSettings.tsx
│   │   │   ├── preview/
│   │   │   │   └── GeneratorPreviewCanvas.tsx
│   │   │   └── timeline/
│   │   │       ├── ContentFrameBlock.tsx
│   │   │       ├── EasingCurveEditor.tsx
│   │   │       ├── EffectBlock.tsx
│   │   │       ├── EffectPropertiesPanel.tsx
│   │   │       ├── EffectTrackRow.tsx
│   │   │       ├── FrameRateControl.tsx
│   │   │       ├── GlobalEffectsTrackHeader.tsx
│   │   │       ├── GroupHeader.tsx
│   │   │       ├── GroupPropertiesPanel.tsx
│   │   │       ├── KeyframeDiamond.tsx
│   │   │       ├── KeyframeEditorPanel.tsx
│   │   │       ├── LayerContextMenu.tsx
│   │   │       ├── LayerList.tsx
│   │   │       ├── LayerListItem.tsx
│   │   │       ├── LayerMenu.tsx
│   │   │       ├── LayerPropertiesPanel.tsx
│   │   │       ├── PostEffectBlock.tsx
│   │   │       ├── PostEffectPropertiesPanel.tsx
│   │   │       ├── PostEffectsTrackHeader.tsx
│   │   │       ├── TimecodeDisplay.tsx
│   │   │       ├── TimelineContextMenu.tsx
│   │   │       ├── TimelineResizeHandle.tsx
│   │   │       ├── TimelineRuler.tsx
│   │   │       ├── TimelineToolbar.tsx
│   │   │       ├── TimelineTrackArea.tsx
│   │   │       ├── timecodeUtils.ts
│   │   │       └── timelineRulerUtils.ts
│   │   ├── icons/
│   │   │   ├── DiscordIcon.tsx
│   │   │   ├── GitHubIcon.tsx
│   │   │   ├── GradientIcon.tsx
│   │   │   ├── README.md
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   ├── tools/
│   │   │   ├── AsciiBoxTool.tsx
│   │   │   ├── AsciiTypeTool.tsx
│   │   │   ├── BezierShapeTool.tsx
│   │   │   ├── DrawingTool.tsx
│   │   │   ├── EllipseTool.tsx
│   │   │   ├── EyedropperTool.tsx
│   │   │   ├── FlipHorizontalTool.tsx
│   │   │   ├── FlipVerticalTool.tsx
│   │   │   ├── GradientFillTool.tsx
│   │   │   ├── LassoTool.tsx
│   │   │   ├── LayerTransformTool.tsx
│   │   │   ├── MagicWandTool.tsx
│   │   │   ├── PaintBucketTool.tsx
│   │   │   ├── RectangleTool.tsx
│   │   │   ├── SelectionTool.tsx
│   │   │   ├── TextTool.tsx
│   │   │   └── index.ts
│   │   └── ui/
│   │       ├── alert.tsx
│   │       ├── badge.tsx
│   │       ├── button.tsx
│   │       ├── card.tsx
│   │       ├── checkbox.tsx
│   │       ├── collapsible.tsx
│   │       ├── dialog.tsx
│   │       ├── dropdown-menu.tsx
│   │       ├── input.tsx
│   │       ├── label.tsx
│   │       ├── menubar.tsx
│   │       ├── popover.tsx
│   │       ├── progress.tsx
│   │       ├── scroll-area.tsx
│   │       ├── select.tsx
│   │       ├── separator.tsx
│   │       ├── sheet.tsx
│   │       ├── skeleton.tsx
│   │       ├── slider.tsx
│   │       ├── sonner.tsx
│   │       ├── switch.tsx
│   │       ├── tabs.tsx
│   │       ├── textarea.tsx
│   │       ├── toggle.tsx
│   │       └── tooltip.tsx
│   ├── constants/
│   │   ├── bezierAutofill/
│   │   │   ├── ansiCharacters.ts
│   │   │   ├── ansiCharacters_backup.ts
│   │   │   ├── blockCharacters.ts
│   │   │   ├── brailleCharacters.ts
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   ├── boxDrawingStyles.ts
│   │   ├── colors.ts
│   │   ├── defaultCharacterPalettes.ts
│   │   ├── defaultPalettes.ts
│   │   ├── effectsDefaults.ts
│   │   ├── features.ts
│   │   ├── figletFonts.ts
│   │   ├── fonts.d.ts
│   │   ├── fonts.ts
│   │   ├── generators.ts
│   │   ├── hotkeys.ts
│   │   ├── index.ts
│   │   ├── onionSkin.ts
│   │   ├── postEffectDefaults.ts
│   │   ├── shapeVectors.ts
│   │   └── version.ts
│   ├── contexts/
│   │   ├── CanvasContext/
│   │   │   ├── CanvasProvider.tsx
│   │   │   ├── context.ts
│   │   │   ├── index.ts
│   │   │   ├── useCanvasContext.ts
│   │   │   └── useCanvasDimensions.ts
│   │   ├── CanvasContext.ts
│   │   ├── CanvasContext.tsx
│   │   ├── ModalContext/
│   │   │   ├── ModalProvider.tsx
│   │   │   ├── context.ts
│   │   │   ├── index.ts
│   │   │   └── useModalContext.ts
│   │   ├── ModalContext.ts
│   │   ├── ModalContext.tsx
│   │   ├── ThemeContext/
│   │   │   ├── ThemeProvider.tsx
│   │   │   ├── context.ts
│   │   │   ├── index.ts
│   │   │   └── useTheme.ts
│   │   ├── ThemeContext.ts
│   │   └── ThemeContext.tsx
│   ├── hooks/
│   │   ├── useAdminProjectLoader.ts
│   │   ├── useAnimationHistory.ts
│   │   ├── useAsciiBoxTool.ts
│   │   ├── useAsciiTypePlacement.ts
│   │   ├── useAsciiTypeTool.ts
│   │   ├── useCanvasDragAndDrop.ts
│   │   ├── useCanvasLassoSelection.ts
│   │   ├── useCanvasMagicWandSelection.ts
│   │   ├── useCanvasMouseHandlers.ts
│   │   ├── useCanvasRenderer.ts
│   │   ├── useCanvasRenderer.ts.backup
│   │   ├── useCanvasResize.ts
│   │   ├── useCanvasSelection.ts
│   │   ├── useCanvasState.ts
│   │   ├── useCloudDialogState.ts
│   │   ├── useCloudProjectActions.ts
│   │   ├── useCompositedCanvas.ts
│   │   ├── useCropToSelection.ts
│   │   ├── useDrawingTool.ts
│   │   ├── useEffectBlockHistory.ts
│   │   ├── useFlipUtilities.ts
│   │   ├── useFrameNavigation.ts
│   │   ├── useFrameSynchronization.ts
│   │   ├── useGeneratorPreview.ts
│   │   ├── useGradientFillTool.ts
│   │   ├── useHoverPreview.ts
│   │   ├── useKeyboardShortcuts.ts
│   │   ├── useKeyframeableProperty.ts
│   │   ├── useLayerLimit.ts
│   │   ├── useLayerTransformTool.ts
│   │   ├── useLayoutState.ts
│   │   ├── useMemoizedGrid.ts
│   │   ├── useOnionSkinRenderer.ts
│   │   ├── useOptimizedPlayback.ts
│   │   ├── useOptimizedRender.ts
│   │   ├── usePasteMode.ts
│   │   ├── usePerformanceMonitor.ts
│   │   ├── usePlaybackFpsMonitor.ts
│   │   ├── usePlaybackOnlySnapshot.ts
│   │   ├── usePostEffectBlockHistory.ts
│   │   ├── usePostEffectsRenderer.ts
│   │   ├── useProjectDialogState.ts
│   │   ├── useProjectFileActions.ts
│   │   ├── useScrubInput.ts
│   │   ├── useSelectionSync.ts
│   │   ├── useTextTool.ts
│   │   ├── useTimelineHistory.ts
│   │   ├── useToolBehavior.ts
│   │   ├── useWelcomeDialog.ts
│   │   └── useZoomControls.ts
│   ├── index.css
│   ├── index.css.backup
│   ├── lib/
│   │   ├── figletClient.ts
│   │   ├── premium-stub.ts
│   │   └── utils.ts
│   ├── main.tsx
│   ├── mcp/
│   │   ├── client.ts
│   │   ├── index.ts
│   │   ├── store.ts
│   │   ├── types.ts
│   │   └── useMCPConnection.ts
│   ├── pages/
│   │   ├── CommunityPage.tsx
│   │   └── EditorPage.tsx
│   ├── registry/
│   │   ├── effectRegistry.ts
│   │   ├── effects/
│   │   │   ├── hueSaturation.ts
│   │   │   ├── index.ts
│   │   │   ├── levels.ts
│   │   │   ├── motionTrails.ts
│   │   │   ├── remapCharacters.ts
│   │   │   ├── remapColors.ts
│   │   │   ├── scatter.ts
│   │   │   ├── waveWarp.ts
│   │   │   └── wiggle.ts
│   │   ├── postEffectRegistry.ts
│   │   └── postEffects/
│   │       ├── blur.ts
│   │       ├── chromaticAberration.ts
│   │       ├── glow.ts
│   │       ├── index.ts
│   │       ├── pixelate.ts
│   │       └── screenDistortion.ts
│   ├── stores/
│   │   ├── animationStore.ts
│   │   ├── animationStoreAdapter.ts
│   │   ├── asciiBoxStore.ts
│   │   ├── asciiTypeStore.ts
│   │   ├── bezierStore.ts
│   │   ├── canvasStore.ts
│   │   ├── characterPaletteStore.ts
│   │   ├── exportStore.ts
│   │   ├── generatorsStore.ts
│   │   ├── gradientStore.ts
│   │   ├── importStore.ts
│   │   ├── paletteStore.ts
│   │   ├── playbackOnlyStore.ts
│   │   ├── previewStore.ts
│   │   ├── projectMetadataStore.ts
│   │   ├── selectionStore.ts
│   │   ├── timelineStore.ts
│   │   └── toolStore.ts
│   ├── styles/
│   │   └── bundled-fonts.css
│   ├── types/
│   │   ├── easing.ts
│   │   ├── effectBlock.ts
│   │   ├── effects.ts
│   │   ├── export.ts
│   │   ├── generators.ts
│   │   ├── index.ts
│   │   ├── mp4box.d.ts
│   │   ├── palette.ts
│   │   ├── postEffect.ts
│   │   ├── timeEffects.ts
│   │   ├── timeline.ts
│   │   └── welcomeDialog.ts
│   ├── utils/
│   │   ├── asciiConverter.ts
│   │   ├── bezierAutofillUtils.ts
│   │   ├── bezierFillUtils.ts
│   │   ├── bezierPathUtils.ts
│   │   ├── bezierStrokeUtils.ts
│   │   ├── boxDrawingEngine.ts
│   │   ├── brushUtils.ts
│   │   ├── canvasAnalysis.ts
│   │   ├── canvasDPI.ts
│   │   ├── canvasResizeUtils.ts
│   │   ├── canvasSizeConversion.ts
│   │   ├── canvasTextRendering.ts
│   │   ├── characterPaletteValidation.ts
│   │   ├── clipboardUtils.ts
│   │   ├── colorConversion.ts
│   │   ├── cropUtils.ts
│   │   ├── directCanvasRenderer.ts
│   │   ├── dirtyTracker.ts
│   │   ├── effectKeyframeInterpolation.ts
│   │   ├── effectsPipeline.ts
│   │   ├── effectsProcessing.ts
│   │   ├── exportDataCollector.ts
│   │   ├── exportPixelCalculator.ts
│   │   ├── exportRenderer.ts
│   │   ├── fillArea.ts
│   │   ├── flipUtils.ts
│   │   ├── font/
│   │   │   ├── fontLoader.ts
│   │   │   ├── fontRegistry.ts
│   │   │   ├── index.ts
│   │   │   ├── opentypePathConverter.ts
│   │   │   └── types.ts
│   │   ├── fontDetection.ts
│   │   ├── fontLoader.ts
│   │   ├── fontMetrics.ts
│   │   ├── frameUtils.ts
│   │   ├── generators/
│   │   │   ├── digitalRain.ts
│   │   │   ├── generatorEngine.ts
│   │   │   ├── particlePhysics.ts
│   │   │   ├── radioWaves.ts
│   │   │   ├── rainDrops.ts
│   │   │   └── turbulentNoise.ts
│   │   ├── gradientEngine.ts
│   │   ├── gridColor.ts
│   │   ├── kdTree.ts
│   │   ├── layerCompositing.ts
│   │   ├── layerLimits.ts
│   │   ├── layerTransformUtils.ts
│   │   ├── lineArtConverter.ts
│   │   ├── mediaProcessor.ts
│   │   ├── paletteValidation.ts
│   │   ├── performance.ts
│   │   ├── polygon.ts
│   │   ├── postEffectsPipeline.ts
│   │   ├── projectUtils.ts
│   │   ├── renderScheduler.ts
│   │   ├── selectionConstraint.ts
│   │   ├── selectionUtils.ts
│   │   ├── sessionImporter.ts
│   │   ├── sessionMigration.ts
│   │   ├── shapeBasedConverter.ts
│   │   ├── svgExportUtils.ts
│   │   ├── timeEffectsProcessing.ts
│   │   ├── vectorShapeGeometry.ts
│   │   └── webgl/
│   │       ├── WebGLPostProcessor.ts
│   │       ├── commonShaders.ts
│   │       ├── index.ts
│   │       └── shaderCompiler.ts
│   └── vite-env.d.ts
├── supabase/
│   ├── .gitignore
│   └── config.toml
├── tailwind.config.js
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
├── vercel.json
├── vite.config.ts
└── vitest.config.ts
Download .txt
SYMBOL INDEX (1941 symbols across 338 files)

FILE: api/og.ts
  type _ProjectData (line 8) | type _ProjectData = {
  type _UserProfile (line 17) | type _UserProfile = {
  function handler (line 25) | async function handler(req: Request) {
  function escapeHtml (line 163) | function escapeHtml(unsafe: string): string {
  function sanitizeUrl (line 173) | function sanitizeUrl(url: string | null): string {

FILE: dev-tools/bubbletea-test-cli/animations/ascii_motion_anim.go
  type Frame (line 676) | type Frame struct
  type Model (line 684) | type Model struct
    method Init (line 716) | func (m Model) Init() tea.Cmd {
    method tick (line 720) | func (m Model) tick() tea.Cmd {
    method Update (line 730) | func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method getColor (line 756) | func (m Model) getColor(colorKey string) lipgloss.TerminalColor {
    method View (line 764) | func (m Model) View() string {
    method Play (line 793) | func (m *Model) Play() tea.Cmd {
    method Pause (line 799) | func (m *Model) Pause() {
    method Restart (line 804) | func (m *Model) Restart() tea.Cmd {
    method IsPlaying (line 810) | func (m Model) IsPlaying() bool {
    method CurrentFrame (line 815) | func (m Model) CurrentFrame() int {
    method TotalFrames (line 820) | func (m Model) TotalFrames() int {
  type tickMsg (line 694) | type tickMsg
  function New (line 698) | func New(hasDarkBackground bool) Model {
  function NewWithDefaults (line 711) | func NewWithDefaults() Model {

FILE: dev-tools/bubbletea-test-cli/animations/copilotspin/copilot_spin.go
  type Frame (line 40) | type Frame struct
  type Model (line 48) | type Model struct
    method Init (line 80) | func (m Model) Init() tea.Cmd {
    method tick (line 84) | func (m Model) tick() tea.Cmd {
    method Update (line 94) | func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method getColor (line 120) | func (m Model) getColor(colorKey string) lipgloss.TerminalColor {
    method View (line 128) | func (m Model) View() string {
    method Play (line 157) | func (m *Model) Play() tea.Cmd {
    method Pause (line 163) | func (m *Model) Pause() {
    method Restart (line 168) | func (m *Model) Restart() tea.Cmd {
    method IsPlaying (line 174) | func (m Model) IsPlaying() bool {
    method CurrentFrame (line 179) | func (m Model) CurrentFrame() int {
    method TotalFrames (line 184) | func (m Model) TotalFrames() int {
  type tickMsg (line 58) | type tickMsg
  function New (line 62) | func New(hasDarkBackground bool) Model {
  function NewWithDefaults (line 75) | func NewWithDefaults() Model {

FILE: dev-tools/bubbletea-test-cli/animations/effects/ascii_motion_anim_effects.go
  type Frame (line 874) | type Frame struct
  type Model (line 882) | type Model struct
    method Init (line 914) | func (m Model) Init() tea.Cmd {
    method tick (line 918) | func (m Model) tick() tea.Cmd {
    method Update (line 928) | func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method getColor (line 954) | func (m Model) getColor(colorKey string) lipgloss.TerminalColor {
    method View (line 962) | func (m Model) View() string {
    method Play (line 991) | func (m *Model) Play() tea.Cmd {
    method Pause (line 997) | func (m *Model) Pause() {
    method Restart (line 1002) | func (m *Model) Restart() tea.Cmd {
    method IsPlaying (line 1008) | func (m Model) IsPlaying() bool {
    method CurrentFrame (line 1013) | func (m Model) CurrentFrame() int {
    method TotalFrames (line 1018) | func (m Model) TotalFrames() int {
  type tickMsg (line 892) | type tickMsg
  function New (line 896) | func New(hasDarkBackground bool) Model {
  function NewWithDefaults (line 909) | func NewWithDefaults() Model {

FILE: dev-tools/bubbletea-test-cli/animations/effects2/ascii_motion_anim_effects2.go
  type Frame (line 874) | type Frame struct
  type Model (line 882) | type Model struct
    method Init (line 914) | func (m Model) Init() tea.Cmd {
    method tick (line 918) | func (m Model) tick() tea.Cmd {
    method Update (line 928) | func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method getColor (line 954) | func (m Model) getColor(colorKey string) lipgloss.TerminalColor {
    method View (line 962) | func (m Model) View() string {
    method Play (line 991) | func (m *Model) Play() tea.Cmd {
    method Pause (line 997) | func (m *Model) Pause() {
    method Restart (line 1002) | func (m *Model) Restart() tea.Cmd {
    method IsPlaying (line 1008) | func (m Model) IsPlaying() bool {
    method CurrentFrame (line 1013) | func (m Model) CurrentFrame() int {
    method TotalFrames (line 1018) | func (m Model) TotalFrames() int {
  type tickMsg (line 892) | type tickMsg
  function New (line 896) | func New(hasDarkBackground bool) Model {
  function NewWithDefaults (line 909) | func NewWithDefaults() Model {

FILE: dev-tools/bubbletea-test-cli/animations/effects3/ascii_motion_anim_effects3.go
  type Frame (line 874) | type Frame struct
  type Model (line 882) | type Model struct
    method Init (line 914) | func (m Model) Init() tea.Cmd {
    method tick (line 918) | func (m Model) tick() tea.Cmd {
    method Update (line 928) | func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method getColor (line 954) | func (m Model) getColor(colorKey string) lipgloss.TerminalColor {
    method View (line 962) | func (m Model) View() string {
    method Play (line 991) | func (m *Model) Play() tea.Cmd {
    method Pause (line 997) | func (m *Model) Pause() {
    method Restart (line 1002) | func (m *Model) Restart() tea.Cmd {
    method IsPlaying (line 1008) | func (m Model) IsPlaying() bool {
    method CurrentFrame (line 1013) | func (m Model) CurrentFrame() int {
    method TotalFrames (line 1018) | func (m Model) TotalFrames() int {
  type tickMsg (line 892) | type tickMsg
  function New (line 896) | func New(hasDarkBackground bool) Model {
  function NewWithDefaults (line 909) | func NewWithDefaults() Model {

FILE: dev-tools/bubbletea-test-cli/animations/newtest/ascii_motion_anim_new.go
  type Frame (line 676) | type Frame struct
  type Model (line 684) | type Model struct
    method Init (line 716) | func (m Model) Init() tea.Cmd {
    method tick (line 720) | func (m Model) tick() tea.Cmd {
    method Update (line 730) | func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method getColor (line 756) | func (m Model) getColor(colorKey string) lipgloss.TerminalColor {
    method View (line 764) | func (m Model) View() string {
    method Play (line 793) | func (m *Model) Play() tea.Cmd {
    method Pause (line 799) | func (m *Model) Pause() {
    method Restart (line 804) | func (m *Model) Restart() tea.Cmd {
    method IsPlaying (line 810) | func (m Model) IsPlaying() bool {
    method CurrentFrame (line 815) | func (m Model) CurrentFrame() int {
    method TotalFrames (line 820) | func (m Model) TotalFrames() int {
  type tickMsg (line 694) | type tickMsg
  function New (line 698) | func New(hasDarkBackground bool) Model {
  function NewWithDefaults (line 711) | func NewWithDefaults() Model {

FILE: dev-tools/bubbletea-test-cli/main.go
  function main (line 12) | func main() {

FILE: dev-tools/debug-video-export.js
  function debugVideoExport (line 7) | function debugVideoExport() {

FILE: dev-tools/ink-test-cli/src/ascii-motion-cli-effects.tsx
  constant COLORS_DARK (line 7) | const COLORS_DARK: Record<string, string> = {
  constant COLORS_LIGHT (line 437) | const COLORS_LIGHT: Record<string, string> = {
  type FrameData (line 867) | type FrameData = {
  type PlaybackAPI (line 874) | type PlaybackAPI = {
  type AsciiMotionCliEffectsProps (line 880) | type AsciiMotionCliEffectsProps = {
  constant FRAMES (line 887) | const FRAMES: FrameData[] = [
  constant CANVAS_WIDTH (line 39192) | const CANVAS_WIDTH = 80;
  constant CANVAS_HEIGHT (line 39193) | const CANVAS_HEIGHT = 24;
  constant DEFAULT_LOOP (line 39194) | const DEFAULT_LOOP = true;

FILE: dev-tools/ink-test-cli/src/ascii-motion-cli_256.tsx
  constant COLORS_DARK (line 8) | const COLORS_DARK: Record<string, string> = {
  constant COLORS_LIGHT (line 21) | const COLORS_LIGHT: Record<string, string> = {
  type FrameData (line 34) | type FrameData = {
  type PlaybackAPI (line 41) | type PlaybackAPI = {
  type AsciiMotionCli256Props (line 47) | type AsciiMotionCli256Props = {
  constant FRAMES (line 54) | const FRAMES: FrameData[] = [
  constant CANVAS_WIDTH (line 12865) | const CANVAS_WIDTH = 30;
  constant CANVAS_HEIGHT (line 12866) | const CANVAS_HEIGHT = 14;
  constant DEFAULT_LOOP (line 12867) | const DEFAULT_LOOP = true;

FILE: dev-tools/opentui-test-cli/src/ascii-motion-opentui-hex.tsx
  constant COLORS_DARK (line 6) | const COLORS_DARK: Record<string, string> = {
  constant COLORS_LIGHT (line 337) | const COLORS_LIGHT: Record<string, string> = {
  type FrameData (line 668) | type FrameData = {
  type PlaybackAPI (line 675) | type PlaybackAPI = {
  type AsciiMotionOpentuiHexProps (line 681) | type AsciiMotionOpentuiHexProps = {
  constant FRAMES (line 688) | const FRAMES: FrameData[] = [
  constant CANVAS_WIDTH (line 7482) | const CANVAS_WIDTH = 60;
  constant CANVAS_HEIGHT (line 7483) | const CANVAS_HEIGHT = 24;
  constant DEFAULT_LOOP (line 7484) | const DEFAULT_LOOP = true;

FILE: dev-tools/opentui-test-cli/src/ascii-motion-tui-ansi2.tsx
  constant COLORS_DARK (line 6) | const COLORS_DARK: Record<string, string> = {
  constant COLORS_LIGHT (line 19) | const COLORS_LIGHT: Record<string, string> = {
  type FrameData (line 32) | type FrameData = {
  type PlaybackAPI (line 39) | type PlaybackAPI = {
  type AsciiMotionTuiAnsiProps (line 45) | type AsciiMotionTuiAnsiProps = {
  constant FRAMES (line 52) | const FRAMES: FrameData[] = [
  constant CANVAS_WIDTH (line 12863) | const CANVAS_WIDTH = 30;
  constant CANVAS_HEIGHT (line 12864) | const CANVAS_HEIGHT = 14;
  constant DEFAULT_LOOP (line 12865) | const DEFAULT_LOOP = true;

FILE: dev-tools/opentui-test-cli/src/ascii-motion-tui-effects.tsx
  constant COLORS_DARK (line 6) | const COLORS_DARK: Record<string, string> = {
  constant COLORS_LIGHT (line 436) | const COLORS_LIGHT: Record<string, string> = {
  type FrameData (line 866) | type FrameData = {
  type PlaybackAPI (line 873) | type PlaybackAPI = {
  type AsciiMotionTuiEffectsProps (line 879) | type AsciiMotionTuiEffectsProps = {
  constant FRAMES (line 886) | const FRAMES: FrameData[] = [
  constant CANVAS_WIDTH (line 39191) | const CANVAS_WIDTH = 80;
  constant CANVAS_HEIGHT (line 39192) | const CANVAS_HEIGHT = 24;
  constant DEFAULT_LOOP (line 39193) | const DEFAULT_LOOP = true;

FILE: dev-tools/opentui-test-cli/src/ascii-motion-tui-semantic.tsx
  constant THEME_DARK (line 6) | const THEME_DARK: Record<string, string> = {
  constant THEME_LIGHT (line 15) | const THEME_LIGHT: Record<string, string> = {
  type FrameData (line 24) | type FrameData = {
  type PlaybackAPI (line 31) | type PlaybackAPI = {
  type AsciiMotionTuiSemanticProps (line 37) | type AsciiMotionTuiSemanticProps = {
  constant FRAMES (line 44) | const FRAMES: FrameData[] = [
  constant CANVAS_WIDTH (line 6838) | const CANVAS_WIDTH = 60;
  constant CANVAS_HEIGHT (line 6839) | const CANVAS_HEIGHT = 24;
  constant DEFAULT_LOOP (line 6840) | const DEFAULT_LOOP = true;

FILE: dev-tools/opentui-test-cli/src/ascii-motion-tui.tsx
  constant COLORS_DARK (line 7) | const COLORS_DARK: Record<string, string> = {
  constant COLORS_LIGHT (line 31) | const COLORS_LIGHT: Record<string, string> = {
  type FrameData (line 55) | type FrameData = {
  type PlaybackAPI (line 62) | type PlaybackAPI = {
  type AsciiMotionTuiProps (line 68) | type AsciiMotionTuiProps = {
  constant FRAMES (line 75) | const FRAMES: FrameData[] = [
  constant CANVAS_WIDTH (line 17924) | const CANVAS_WIDTH = 72;
  constant CANVAS_HEIGHT (line 17925) | const CANVAS_HEIGHT = 23;
  constant DEFAULT_LOOP (line 17926) | const DEFAULT_LOOP = true;

FILE: dev-tools/opentui-test-cli/src/ascii-motion-tui2.tsx
  constant COLORS_DARK (line 6) | const COLORS_DARK: Record<string, string> = {
  constant COLORS_LIGHT (line 19) | const COLORS_LIGHT: Record<string, string> = {
  type FrameData (line 32) | type FrameData = {
  type PlaybackAPI (line 39) | type PlaybackAPI = {
  type AsciiMotionTuiProps (line 45) | type AsciiMotionTuiProps = {
  constant FRAMES (line 52) | const FRAMES: FrameData[] = [
  constant CANVAS_WIDTH (line 12863) | const CANVAS_WIDTH = 30;
  constant CANVAS_HEIGHT (line 12864) | const CANVAS_HEIGHT = 14;
  constant DEFAULT_LOOP (line 12865) | const DEFAULT_LOOP = true;

FILE: dev-tools/opentui-test-cli/src/cli.tsx
  function main (line 20) | async function main() {

FILE: dev-tools/opentui-test-cli/src/fish-animation-256.tsx
  constant COLORS_DARK (line 7) | const COLORS_DARK: Record<string, string> = {
  constant COLORS_LIGHT (line 23) | const COLORS_LIGHT: Record<string, string> = {
  type FrameData (line 39) | type FrameData = {
  type PlaybackAPI (line 46) | type PlaybackAPI = {
  type FishAnimation256Props (line 52) | type FishAnimation256Props = {
  constant FRAMES (line 59) | const FRAMES: FrameData[] = [
  constant CANVAS_WIDTH (line 2852) | const CANVAS_WIDTH = 60;
  constant CANVAS_HEIGHT (line 2853) | const CANVAS_HEIGHT = 30;
  constant DEFAULT_LOOP (line 2854) | const DEFAULT_LOOP = true;

FILE: dev-tools/opentui-test-cli/src/fish-animation.tsx
  constant COLORS_DARK (line 6) | const COLORS_DARK: Record<string, string> = {
  constant COLORS_LIGHT (line 22) | const COLORS_LIGHT: Record<string, string> = {
  type FrameData (line 38) | type FrameData = {
  type PlaybackAPI (line 45) | type PlaybackAPI = {
  type FishAnimationProps (line 51) | type FishAnimationProps = {
  constant FRAMES (line 58) | const FRAMES: FrameData[] = [
  constant CANVAS_WIDTH (line 2851) | const CANVAS_WIDTH = 60;
  constant CANVAS_HEIGHT (line 2852) | const CANVAS_HEIGHT = 30;
  constant DEFAULT_LOOP (line 2853) | const DEFAULT_LOOP = true;

FILE: dev-tools/react-export-test/src/App.tsx
  type PlaybackApi (line 22) | type PlaybackApi = {
  function MyPage (line 29) | function MyPage() {

FILE: dev-tools/react-export-test/src/ascii-motion-animation-effects.tsx
  type CellData (line 6) | type CellData = (number | string)[];
  type Frame (line 8) | type Frame = {
  type AsciiMotionComponentProps (line 13) | type AsciiMotionComponentProps = {
  constant COLORS (line 24) | const COLORS: string[] = ["#0002c7","#000ec7","#001ac7","#0026c7","#0032...
  constant FRAMES (line 26) | const FRAMES: Frame[] = [{"duration":33.333333333333336,"cells":[[14,0,"...
  constant CANVAS_WIDTH (line 28) | const CANVAS_WIDTH = 864;
  constant CANVAS_HEIGHT (line 29) | const CANVAS_HEIGHT = 432;
  constant CELL_WIDTH (line 30) | const CELL_WIDTH = 10.8;
  constant CELL_HEIGHT (line 31) | const CELL_HEIGHT = 18;
  constant FONT_SIZE (line 32) | const FONT_SIZE = 18;
  constant FONT_FAMILY (line 33) | const FONT_FAMILY = "SF Mono, Monaco, Cascadia Code, Consolas, JetBrains...
  constant BACKGROUND_COLOR (line 34) | const BACKGROUND_COLOR = "#000000";

FILE: dev-tools/react-export-test/src/ascii-motion-animation-new.tsx
  type CellData (line 6) | type CellData = (number | string)[];
  type Frame (line 8) | type Frame = {
  type AsciiMotionComponentProps (line 13) | type AsciiMotionComponentProps = {
  constant COLORS (line 24) | const COLORS: string[] = ["#001621","#002eb3","#0069a3","#007a1d","#0095...
  constant FRAMES (line 26) | const FRAMES: Frame[] = [{"duration":33.333333333333336,"cells":[[6,0,"*...
  constant CANVAS_WIDTH (line 28) | const CANVAS_WIDTH = 691.2;
  constant CANVAS_HEIGHT (line 29) | const CANVAS_HEIGHT = 368;
  constant CELL_WIDTH (line 30) | const CELL_WIDTH = 9.6;
  constant CELL_HEIGHT (line 31) | const CELL_HEIGHT = 16;
  constant FONT_SIZE (line 32) | const FONT_SIZE = 16;
  constant FONT_FAMILY (line 33) | const FONT_FAMILY = "SF Mono, Monaco, Cascadia Code, Consolas, JetBrains...
  constant BACKGROUND_COLOR (line 34) | const BACKGROUND_COLOR = null;

FILE: dev-tools/react-export-test/src/ascii-motion-animation.tsx
  type CellData (line 6) | type CellData = (number | string)[];
  type Frame (line 8) | type Frame = {
  type AsciiMotionComponentProps (line 13) | type AsciiMotionComponentProps = {
  constant COLORS (line 24) | const COLORS: string[] = ["#001621","#002eb3","#0069a3","#007a1d","#0095...
  constant FRAMES (line 26) | const FRAMES: Frame[] = [{"duration":33.333333333333336,"cells":[[6,0,"*...
  constant CANVAS_WIDTH (line 28) | const CANVAS_WIDTH = 691.2;
  constant CANVAS_HEIGHT (line 29) | const CANVAS_HEIGHT = 368;
  constant CELL_WIDTH (line 30) | const CELL_WIDTH = 9.6;
  constant CELL_HEIGHT (line 31) | const CELL_HEIGHT = 16;
  constant FONT_SIZE (line 32) | const FONT_SIZE = 16;
  constant FONT_FAMILY (line 33) | const FONT_FAMILY = "SF Mono, Monaco, Cascadia Code, Consolas, JetBrains...
  constant BACKGROUND_COLOR (line 34) | const BACKGROUND_COLOR = "#000000";

FILE: dev-tools/react-export-test/src/shader-test-01.tsx
  type CellData (line 6) | type CellData = (number | string)[];
  type Frame (line 8) | type Frame = {
  type AsciiMotionComponentProps (line 13) | type AsciiMotionComponentProps = {
  constant COLORS (line 24) | const COLORS: string[] = ["#088dff","#3181f8","#5a75f1","#8469eb","#FFFF...
  constant FRAMES (line 26) | const FRAMES: Frame[] = [{"duration":83.33333333333333,"cells":[[13,3,"....
  constant CANVAS_WIDTH (line 28) | const CANVAS_WIDTH = 864;
  constant CANVAS_HEIGHT (line 29) | const CANVAS_HEIGHT = 432;
  constant CELL_WIDTH (line 30) | const CELL_WIDTH = 10.8;
  constant CELL_HEIGHT (line 31) | const CELL_HEIGHT = 18;
  constant FONT_SIZE (line 32) | const FONT_SIZE = 18;
  constant FONT_FAMILY (line 33) | const FONT_FAMILY = "SF Mono, Monaco, Cascadia Code, Consolas, JetBrains...
  constant BACKGROUND_COLOR (line 34) | const BACKGROUND_COLOR = "#000000";
  function hexToRgb (line 79) | function hexToRgb(hex) {
  function initGL (line 84) | function initGL() {
  function getProgram (line 107) | function getProgram(fragSrc) {
  function uploadTex (line 125) | function uploadTex(tex, source) {
  function ensureFBs (line 136) | function ensureFBs(w, h) {
  function setUniformValue (line 159) | function setUniformValue(prog, name, value, prop) {

FILE: dev-tools/react-export-test/src/shader-test-02.tsx
  type CellData (line 6) | type CellData = (number | string)[];
  type Frame (line 8) | type Frame = {
  type AsciiMotionComponentProps (line 13) | type AsciiMotionComponentProps = {
  constant COLORS (line 24) | const COLORS: string[] = ["#088dff","#3181f8","#5a75f1","#8469eb","#FFFF...
  constant FRAMES (line 26) | const FRAMES: Frame[] = [{"duration":83.33333333333333,"cells":[[13,3,"....
  constant CANVAS_WIDTH (line 28) | const CANVAS_WIDTH = 864;
  constant CANVAS_HEIGHT (line 29) | const CANVAS_HEIGHT = 432;
  constant CELL_WIDTH (line 30) | const CELL_WIDTH = 10.8;
  constant CELL_HEIGHT (line 31) | const CELL_HEIGHT = 18;
  constant FONT_SIZE (line 32) | const FONT_SIZE = 18;
  constant FONT_FAMILY (line 33) | const FONT_FAMILY = "SF Mono, Monaco, Cascadia Code, Consolas, JetBrains...
  constant BACKGROUND_COLOR (line 34) | const BACKGROUND_COLOR = "#000000";
  function hexToRgb (line 80) | function hexToRgb(hex) {
  function initGL (line 85) | function initGL() {
  function getProgram (line 108) | function getProgram(fragSrc) {
  function uploadTex (line 126) | function uploadTex(tex, source) {
  function ensureFBs (line 137) | function ensureFBs(w, h) {
  function setUniformValue (line 161) | function setUniformValue(prog, name, value, prop) {

FILE: dev-tools/test-frame-timing.js
  function calculateVideoFramesForDuration (line 7) | function calculateVideoFramesForDuration(durationMs, videoFrameRate) {
  function testFrameTiming (line 14) | function testFrameTiming() {
  function testLoopTiming (line 62) | function testLoopTiming() {

FILE: dev-tools/test-json-html-export.js
  function testNewJsonExportFormat (line 7) | function testNewJsonExportFormat() {
  function testHtmlExportStructure (line 101) | function testHtmlExportStructure() {

FILE: dev-tools/test-video-export.js
  function testWebCodecsSupport (line 7) | function testWebCodecsSupport() {
  function testWebMMuxer (line 17) | async function testWebMMuxer() {
  function testVideoExportDialog (line 42) | function testVideoExportDialog() {
  function runVideoExportTests (line 53) | async function runVideoExportTests() {

FILE: dev-tools/test-video-loops.js
  function testLoopSettings (line 7) | function testLoopSettings() {
  function getLoopMultiplier (line 33) | function getLoopMultiplier(loops) {

FILE: docs/MCP_GUIDE_RESOURCE_CODE.ts
  constant LLM_BEST_PRACTICES_GUIDE (line 14) | const LLM_BEST_PRACTICES_GUIDE = `
  function registerGuideResources (line 72) | function registerGuideResources(server: McpServer): void {

FILE: packages/core/src/components/ui/badge.tsx
  type BadgeProps (line 26) | interface BadgeProps
  function Badge (line 30) | function Badge({ className, variant, ...props }: BadgeProps) {

FILE: packages/core/src/components/ui/button.tsx
  type ButtonProps (line 37) | interface ButtonProps

FILE: packages/core/src/components/ui/menubar.tsx
  function MenubarMenu (line 7) | function MenubarMenu({
  function MenubarGroup (line 13) | function MenubarGroup({
  function MenubarPortal (line 19) | function MenubarPortal({
  function MenubarRadioGroup (line 25) | function MenubarRadioGroup({
  function MenubarSub (line 31) | function MenubarSub({

FILE: packages/core/src/components/ui/sheet.tsx
  type SheetContentProps (line 52) | interface SheetContentProps

FILE: packages/core/src/components/ui/skeleton.tsx
  function Skeleton (line 3) | function Skeleton({

FILE: packages/core/src/components/ui/slider.tsx
  type SliderProps (line 4) | interface SliderProps extends Omit<React.InputHTMLAttributes<HTMLInputEl...

FILE: packages/core/src/lib/utils.ts
  function cn (line 11) | function cn(...inputs: ClassValue[]) {

FILE: public/ffmpeg/ffmpeg-core.js
  function stringToPtr (line 8) | function stringToPtr(str){const len=Module["lengthBytesUTF8"](str)+1;con...
  function stringsToPtr (line 8) | function stringsToPtr(strs){const len=strs.length;const ptr=Module["_mal...
  function print (line 8) | function print(message){Module["logger"]({type:"stdout",message:message})}
  function printErr (line 8) | function printErr(message){if(!message.startsWith("Aborted(native code c...
  function exec (line 8) | function exec(..._args){const args=[...Module["DEFAULT_ARGS"],..._args];...
  function ffprobe (line 8) | function ffprobe(..._args){const args=[...Module["DEFAULT_ARGS_FFPROBE"]...
  function setLogger (line 8) | function setLogger(logger){Module["logger"]=logger}
  function setTimeout (line 8) | function setTimeout(timeout){Module["timeout"]=timeout}
  function setProgress (line 8) | function setProgress(handler){Module["progress"]=handler}
  function receiveProgress (line 8) | function receiveProgress(progress,time){Module["progress"]({progress:pro...
  function reset (line 8) | function reset(){Module["ret"]=-1;Module["timeout"]=-1}
  function _locateFile (line 8) | function _locateFile(path,prefix){const mainScriptUrlOrBlob=Module["main...
  function locateFile (line 8) | function locateFile(path){if(Module["locateFile"]){return Module["locate...
  function assert (line 8) | function assert(condition,text){if(!condition){abort(text)}}
  function updateMemoryViews (line 8) | function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEA...
  function keepRuntimeAlive (line 8) | function keepRuntimeAlive(){return noExitRuntime||runtimeKeepaliveCounte...
  function preRun (line 8) | function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="func...
  function initRuntime (line 8) | function initRuntime(){runtimeInitialized=true;if(!Module["noFSInit"]&&!...
  function postRun (line 8) | function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="f...
  function addOnPreRun (line 8) | function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}
  function addOnInit (line 8) | function addOnInit(cb){__ATINIT__.unshift(cb)}
  function addOnPostRun (line 8) | function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}
  function getUniqueRunDependency (line 8) | function getUniqueRunDependency(id){return id}
  function addRunDependency (line 8) | function addRunDependency(id){runDependencies++;if(Module["monitorRunDep...
  function removeRunDependency (line 8) | function removeRunDependency(id){runDependencies--;if(Module["monitorRun...
  function abort (line 8) | function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what=...
  function isDataURI (line 8) | function isDataURI(filename){return filename.startsWith(dataURIPrefix)}
  function getBinary (line 8) | function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return...
  function getBinaryPromise (line 8) | function getBinaryPromise(binaryFile){if(!wasmBinary&&(ENVIRONMENT_IS_WE...
  function instantiateArrayBuffer (line 8) | function instantiateArrayBuffer(binaryFile,imports,receiver){return getB...
  function instantiateAsync (line 8) | function instantiateAsync(binary,binaryFile,imports,callback){if(!binary...
  function createWasm (line 8) | function createWasm(){var info={"a":wasmImports};function receiveInstanc...
  function send_progress (line 8) | function send_progress(progress,time){Module.receiveProgress(progress,ti...
  function is_timeout (line 8) | function is_timeout(diff){if(Module.timeout===-1)return 0;else{return Mo...
  function ExitStatus (line 8) | function ExitStatus(status){this.name="ExitStatus";this.message=`Program...
  function callRuntimeCallbacks (line 8) | function callRuntimeCallbacks(callbacks){while(callbacks.length>0){callb...
  function getWasmTableEntry (line 8) | function getWasmTableEntry(funcPtr){var func=wasmTableMirror[funcPtr];if...
  function getValue (line 8) | function getValue(ptr,type="i8"){if(type.endsWith("*"))type="*";switch(t...
  function setValue (line 8) | function setValue(ptr,value,type="i8"){if(type.endsWith("*"))type="*";sw...
  function UTF8ArrayToString (line 8) | function UTF8ArrayToString(heapOrArray,idx,maxBytesToRead){var endIdx=id...
  function UTF8ToString (line 8) | function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(H...
  function ___assert_fail (line 8) | function ___assert_fail(condition,filename,line,func){abort(`Assertion f...
  function ExceptionInfo (line 8) | function ExceptionInfo(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24;thi...
  function ___cxa_throw (line 8) | function ___cxa_throw(ptr,type,destructor){var info=new ExceptionInfo(pt...
  function ___dlsym (line 8) | function ___dlsym(handle,symbol){abort(dlopenMissingError)}
  function initRandomFill (line 8) | function initRandomFill(){if(typeof crypto=="object"&&typeof crypto["get...
  function randomFill (line 8) | function randomFill(view){return(randomFill=initRandomFill())(view)}
  function trim (line 8) | function trim(arr){var start=0;for(;start<arr.length;start++){if(arr[sta...
  function lengthBytesUTF8 (line 8) | function lengthBytesUTF8(str){var len=0;for(var i=0;i<str.length;++i){va...
  function stringToUTF8Array (line 8) | function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxByte...
  function intArrayFromString (line 8) | function intArrayFromString(stringy,dontAddNull,length){var len=length>0...
  function zeroMemory (line 8) | function zeroMemory(address,size){HEAPU8.fill(0,address,address+size);re...
  function alignMemory (line 8) | function alignMemory(size,alignment){return Math.ceil(size/alignment)*al...
  function mmapAlloc (line 8) | function mmapAlloc(size){size=alignMemory(size,65536);var ptr=_emscripte...
  function asyncLoad (line 8) | function asyncLoad(url,onload,onerror,noRunDep){var dep=!noRunDep?getUni...
  function FS_handledByPreloadPlugin (line 8) | function FS_handledByPreloadPlugin(byteArray,fullname,finish,onerror){if...
  function FS_createPreloadedFile (line 8) | function FS_createPreloadedFile(parent,name,url,canRead,canWrite,onload,...
  function FS_modeStringToFlags (line 8) | function FS_modeStringToFlags(str){var flagModes={"r":0,"r+":2,"w":512|6...
  function FS_getMode (line 8) | function FS_getMode(canRead,canWrite){var mode=0;if(canRead)mode|=292|73...
  function ensureParent (line 8) | function ensureParent(path){var parts=path.split("/");var parent=root;fo...
  function base (line 8) | function base(path){var parts=path.split("/");return parts[parts.length-1]}
  function doCallback (line 8) | function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}
  function done (line 8) | function done(errCode){if(errCode){if(!done.errored){done.errored=true;r...
  function LazyUint8Array (line 8) | function LazyUint8Array(){this.lengthKnown=false;this.chunks=[]}
  function writeChunks (line 8) | function writeChunks(stream,buffer,offset,length,position){var contents=...
  function ___syscall__newselect (line 8) | function ___syscall__newselect(nfds,readfds,writefds,exceptfds,timeout){...
  function handleMessage (line 8) | function handleMessage(data){if(typeof data=="string"){var encoder=new T...
  function getSocketFromFD (line 8) | function getSocketFromFD(fd){var socket=SOCKFS.getSocket(fd);if(!socket)...
  function setErrNo (line 8) | function setErrNo(value){HEAP32[___errno_location()>>2]=value;return value}
  function inetPton4 (line 8) | function inetPton4(str){var b=str.split(".");for(var i=0;i<4;i++){var tm...
  function jstoi_q (line 8) | function jstoi_q(str){return parseInt(str)}
  function inetPton6 (line 8) | function inetPton6(str){var words;var w,offset,z;var valid6regx=/^((?=.*...
  function writeSockaddr (line 8) | function writeSockaddr(sa,family,addr,port,addrlen){switch(family){case ...
  function ___syscall_accept4 (line 8) | function ___syscall_accept4(fd,addr,addrlen,flags,d1,d2){try{var sock=ge...
  function inetNtop4 (line 8) | function inetNtop4(addr){return(addr&255)+"."+(addr>>8&255)+"."+(addr>>1...
  function inetNtop6 (line 8) | function inetNtop6(ints){var str="";var word=0;var longest=0;var lastzer...
  function readSockaddr (line 8) | function readSockaddr(sa,salen){var family=HEAP16[sa>>1];var port=_ntohs...
  function getSocketAddress (line 8) | function getSocketAddress(addrp,addrlen,allowNull){if(allowNull&&addrp==...
  function ___syscall_bind (line 8) | function ___syscall_bind(fd,addr,addrlen,d1,d2,d3){try{var sock=getSocke...
  function ___syscall_connect (line 8) | function ___syscall_connect(fd,addr,addrlen,d1,d2,d3){try{var sock=getSo...
  function ___syscall_faccessat (line 8) | function ___syscall_faccessat(dirfd,path,amode,flags){try{path=SYSCALLS....
  function ___syscall_fcntl64 (line 8) | function ___syscall_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try...
  function ___syscall_fstat64 (line 8) | function ___syscall_fstat64(fd,buf){try{var stream=SYSCALLS.getStreamFro...
  function stringToUTF8 (line 8) | function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Arr...
  function ___syscall_getdents64 (line 8) | function ___syscall_getdents64(fd,dirp,count){try{var stream=SYSCALLS.ge...
  function ___syscall_getpeername (line 8) | function ___syscall_getpeername(fd,addr,addrlen,d1,d2,d3){try{var sock=g...
  function ___syscall_getsockname (line 8) | function ___syscall_getsockname(fd,addr,addrlen,d1,d2,d3){try{var sock=g...
  function ___syscall_getsockopt (line 8) | function ___syscall_getsockopt(fd,level,optname,optval,optlen,d1){try{va...
  function ___syscall_ioctl (line 8) | function ___syscall_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{va...
  function ___syscall_listen (line 8) | function ___syscall_listen(fd,backlog){try{var sock=getSocketFromFD(fd);...
  function ___syscall_lstat64 (line 8) | function ___syscall_lstat64(path,buf){try{path=SYSCALLS.getStr(path);ret...
  function ___syscall_mkdirat (line 8) | function ___syscall_mkdirat(dirfd,path,mode){try{path=SYSCALLS.getStr(pa...
  function ___syscall_newfstatat (line 8) | function ___syscall_newfstatat(dirfd,path,buf,flags){try{path=SYSCALLS.g...
  function ___syscall_openat (line 8) | function ___syscall_openat(dirfd,path,flags,varargs){SYSCALLS.varargs=va...
  function ___syscall_poll (line 8) | function ___syscall_poll(fds,nfds,timeout){try{var nonzero=0;for(var i=0...
  function ___syscall_recvfrom (line 8) | function ___syscall_recvfrom(fd,buf,len,flags,addr,addrlen){try{var sock...
  function ___syscall_renameat (line 8) | function ___syscall_renameat(olddirfd,oldpath,newdirfd,newpath){try{oldp...
  function ___syscall_rmdir (line 8) | function ___syscall_rmdir(path){try{path=SYSCALLS.getStr(path);FS.rmdir(...
  function ___syscall_sendto (line 8) | function ___syscall_sendto(fd,message,length,flags,addr,addr_len){try{va...
  function ___syscall_socket (line 8) | function ___syscall_socket(domain,type,protocol){try{var sock=SOCKFS.cre...
  function ___syscall_stat64 (line 8) | function ___syscall_stat64(path,buf){try{path=SYSCALLS.getStr(path);retu...
  function ___syscall_unlinkat (line 8) | function ___syscall_unlinkat(dirfd,path,flags){try{path=SYSCALLS.getStr(...
  function __emscripten_get_now_is_monotonic (line 8) | function __emscripten_get_now_is_monotonic(){return nowIsMonotonic}
  function __emscripten_throw_longjmp (line 8) | function __emscripten_throw_longjmp(){throw Infinity}
  function readI53FromI64 (line 8) | function readI53FromI64(ptr){return HEAPU32[ptr>>2]+HEAP32[ptr+4>>2]*429...
  function __gmtime_js (line 8) | function __gmtime_js(time,tmPtr){var date=new Date(readI53FromI64(time)*...
  function isLeapYear (line 8) | function isLeapYear(year){return year%4===0&&(year%100!==0||year%400===0)}
  function ydayFromDate (line 8) | function ydayFromDate(date){var leap=isLeapYear(date.getFullYear());var ...
  function __localtime_js (line 8) | function __localtime_js(time,tmPtr){var date=new Date(readI53FromI64(tim...
  function __mktime_js (line 8) | function __mktime_js(tmPtr){var date=new Date(HEAP32[tmPtr+20>>2]+1900,H...
  function __mmap_js (line 8) | function __mmap_js(len,prot,flags,fd,off,allocated,addr){try{var stream=...
  function __munmap_js (line 8) | function __munmap_js(addr,len,prot,flags,fd,offset){try{var stream=SYSCA...
  function stringToNewUTF8 (line 8) | function stringToNewUTF8(str){var size=lengthBytesUTF8(str)+1;var ret=_m...
  function __tzset_js (line 8) | function __tzset_js(timezone,daylight,tzname){var currentYear=(new Date)...
  function _abort (line 8) | function _abort(){abort("")}
  function _dlopen (line 8) | function _dlopen(handle){abort(dlopenMissingError)}
  function readEmAsmArgs (line 8) | function readEmAsmArgs(sigPtr,buf){readEmAsmArgsArray.length=0;var ch;bu...
  function runEmAsmFunction (line 8) | function runEmAsmFunction(code,sigPtr,argbuf){var args=readEmAsmArgs(sig...
  function _emscripten_asm_const_int (line 8) | function _emscripten_asm_const_int(code,sigPtr,argbuf){return runEmAsmFu...
  function _emscripten_date_now (line 8) | function _emscripten_date_now(){return Date.now()}
  function getHeapMax (line 8) | function getHeapMax(){return 2147483648}
  function _emscripten_get_heap_max (line 8) | function _emscripten_get_heap_max(){return getHeapMax()}
  function _emscripten_memcpy_big (line 8) | function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src...
  function emscripten_realloc_buffer (line 8) | function emscripten_realloc_buffer(size){var b=wasmMemory.buffer;try{was...
  function _emscripten_resize_heap (line 8) | function _emscripten_resize_heap(requestedSize){var oldSize=HEAPU8.lengt...
  function getExecutableName (line 8) | function getExecutableName(){return thisProgram||"./this.program"}
  function getEnvStrings (line 8) | function getEnvStrings(){if(!getEnvStrings.strings){var lang=(typeof nav...
  function stringToAscii (line 8) | function stringToAscii(str,buffer){for(var i=0;i<str.length;++i){HEAP8[b...
  function _environ_get (line 8) | function _environ_get(__environ,environ_buf){var bufSize=0;getEnvStrings...
  function _environ_sizes_get (line 8) | function _environ_sizes_get(penviron_count,penviron_buf_size){var string...
  function _proc_exit (line 8) | function _proc_exit(code){EXITSTATUS=code;if(!keepRuntimeAlive()){if(Mod...
  function exitJS (line 8) | function exitJS(status,implicit){EXITSTATUS=status;_proc_exit(status)}
  function _fd_close (line 8) | function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.cl...
  function _fd_fdstat_get (line 8) | function _fd_fdstat_get(fd,pbuf){try{var rightsBase=0;var rightsInheriti...
  function doReadv (line 8) | function doReadv(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i<iovcn...
  function _fd_read (line 8) | function _fd_read(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamF...
  function bigintToI53Checked (line 8) | function bigintToI53Checked(num){return num<MIN_INT53||num>MAX_INT53?NaN...
  function _fd_seek (line 8) | function _fd_seek(fd,offset,whence,newOffset){try{offset=bigintToI53Chec...
  function doWritev (line 8) | function doWritev(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i<iovc...
  function _fd_write (line 8) | function _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStream...
  function _getaddrinfo (line 8) | function _getaddrinfo(node,service,hint,out){var addr=0;var port=0;var f...
  function _getnameinfo (line 8) | function _getnameinfo(sa,salen,node,nodelen,serv,servlen,flags){var info...
  function arraySum (line 8) | function arraySum(array,index){var sum=0;for(var i=0;i<=index;sum+=array...
  function addDays (line 8) | function addDays(date,days){var newDate=new Date(date.getTime());while(d...
  function writeArrayToMemory (line 8) | function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}
  function _strftime (line 8) | function _strftime(s,maxsize,format,tm){var tm_zone=HEAP32[tm+40>>2];var...
  function invoke_iiiii (line 8) | function invoke_iiiii(index,a1,a2,a3,a4){var sp=stackSave();try{return g...
  function invoke_vii (line 8) | function invoke_vii(index,a1,a2){var sp=stackSave();try{getWasmTableEntr...
  function invoke_iii (line 8) | function invoke_iii(index,a1,a2){var sp=stackSave();try{return getWasmTa...
  function invoke_iiiijj (line 8) | function invoke_iiiijj(index,a1,a2,a3,a4,a5){var sp=stackSave();try{retu...
  function invoke_iiiiiiiii (line 8) | function invoke_iiiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8){var sp=stackSav...
  function invoke_vi (line 8) | function invoke_vi(index,a1){var sp=stackSave();try{getWasmTableEntry(in...
  function invoke_viiii (line 8) | function invoke_viiii(index,a1,a2,a3,a4){var sp=stackSave();try{getWasmT...
  function invoke_iiii (line 8) | function invoke_iiii(index,a1,a2,a3){var sp=stackSave();try{return getWa...
  function invoke_iij (line 8) | function invoke_iij(index,a1,a2){var sp=stackSave();try{return getWasmTa...
  function invoke_i (line 8) | function invoke_i(index){var sp=stackSave();try{return getWasmTableEntry...
  function invoke_ii (line 8) | function invoke_ii(index,a1){var sp=stackSave();try{return getWasmTableE...
  function invoke_viiiiiiii (line 8) | function invoke_viiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8){var sp=stackSav...
  function invoke_iiiiii (line 8) | function invoke_iiiiii(index,a1,a2,a3,a4,a5){var sp=stackSave();try{retu...
  function invoke_viiiiii (line 8) | function invoke_viiiiii(index,a1,a2,a3,a4,a5,a6){var sp=stackSave();try{...
  function run (line 8) | function run(){if(runDependencies>0){return}preRun();if(runDependencies>...

FILE: scripts/check-licenses.js
  constant MIT_HEADER (line 14) | const MIT_HEADER = '@license MIT';
  constant PROPRIETARY_HEADER (line 15) | const PROPRIETARY_HEADER = '@license Proprietary';
  constant COLORS (line 17) | const COLORS = {

FILE: scripts/migrate-to-monorepo.js
  constant COLORS (line 15) | const COLORS = {

FILE: scripts/version-bump.js
  constant VERSION_FILE (line 12) | const VERSION_FILE = path.join(__dirname, '../src/constants/version.ts');
  constant PACKAGE_FILE (line 13) | const PACKAGE_FILE = path.join(__dirname, '../package.json');
  function getCurrentGitHash (line 25) | function getCurrentGitHash() {
  function getCommitsSinceLastVersion (line 34) | function getCommitsSinceLastVersion(lastVersionTag) {
  function parseVersion (line 56) | function parseVersion(versionString) {
  function incrementVersion (line 68) | function incrementVersion(version, type) {
  function formatVersion (line 89) | function formatVersion(version) {
  function readCurrentVersion (line 93) | function readCurrentVersion() {
  function readVersionHistory (line 106) | function readVersionHistory() {
  function updatePackageJson (line 120) | function updatePackageJson(newVersion) {
  function generateVersionFile (line 131) | function generateVersionFile(newVersion, buildDate, buildHash, versionHi...
  function createGitTag (line 146) | function createGitTag(version) {
  function main (line 156) | function main() {

FILE: src/App.tsx
  function AuthRedirect (line 37) | function AuthRedirect({ type }: { type: 'signup' | 'login' }) {
  function AppContent (line 65) | function AppContent() {
  function App (line 390) | function App() {

FILE: src/__tests__/canvasStoreLayerSync.test.ts
  function resetCanvas (line 17) | function resetCanvas() {
  function cell (line 25) | function cell(char = 'X', color = '#FFFFFF', bgColor = 'transparent'): C...

FILE: src/__tests__/easing.test.ts
  function kf (line 20) | function kf(frame: number, value: number, easing?: EasingCurve): Keyframe {

FILE: src/__tests__/effectBlocks.test.ts
  function resetStore (line 12) | function resetStore() {

FILE: src/__tests__/effectsPipeline.test.ts
  function makeCell (line 27) | function makeCell(char: string, color = '#ffffff', bgColor = '#000000'):...
  function makeCells (line 31) | function makeCells(entries: [string, Cell][]): Map<string, Cell> {
  function makeBlock (line 35) | function makeBlock(overrides: Partial<EffectBlock> = {}): EffectBlock {
  function makeTrack (line 48) | function makeTrack(blockOverrides: Partial<EffectBlock> = {}, trackOverr...

FILE: src/__tests__/layerCompositing.test.ts
  function makeCell (line 34) | function makeCell(char: string, color = '#FFFFFF', bgColor = 'transparen...
  function makeCellMap (line 38) | function makeCellMap(entries: [number, number, Cell][]): Map<string, Cel...
  function makeContentFrame (line 46) | function makeContentFrame(
  function makeLayer (line 61) | function makeLayer(
  function makePropertyTrack (line 77) | function makePropertyTrack(
  constant CANVAS_W (line 94) | const CANVAS_W = 10;
  constant CANVAS_H (line 95) | const CANVAS_H = 10;

FILE: src/__tests__/layerLimits.test.ts
  function resetStore (line 24) | function resetStore() {

FILE: src/__tests__/phase5ExportMigration.test.ts
  function resetStores (line 24) | function resetStores() {
  function makeCell (line 35) | function makeCell(char: string, color = '#ffffff', bgColor = '#000000'):...
  function makeV2Session (line 40) | function makeV2Session(overrides?: Partial<SessionDataV2>): SessionDataV2 {
  function makeV1Session (line 88) | function makeV1Session(): Record<string, unknown> {

FILE: src/__tests__/phase6Integration.test.ts
  function resetStores (line 23) | function resetStores() {
  function makeCell (line 34) | function makeCell(char: string, color = '#ffffff', bgColor = '#000000'):...

FILE: src/__tests__/sessionMigration.test.ts
  function makeV1Session (line 20) | function makeV1Session(overrides?: Record<string, unknown>): Record<stri...
  function makeV2Session (line 52) | function makeV2Session(overrides?: Partial<SessionDataV2>): SessionDataV2 {

FILE: src/__tests__/timelineStore.test.ts
  function resetStore (line 16) | function resetStore() {

FILE: src/__tests__/timelineUI.test.ts
  function resetStore (line 27) | function resetStore() {

FILE: src/__tests__/useTimelineHistory.test.ts
  function resetAll (line 37) | function resetAll() {

FILE: src/components/common/AppReveal.tsx
  type AppRevealProps (line 4) | interface AppRevealProps {
  function AppReveal (line 8) | function AppReveal({ children }: AppRevealProps) {

FILE: src/components/common/AsciiMotionLogo.tsx
  type CellData (line 3) | type CellData = {
  type Frame (line 11) | type Frame = {
  type AsciiMotionLogoProps (line 16) | type AsciiMotionLogoProps = {

FILE: src/components/common/CellRenderer.tsx
  type CellRendererProps (line 4) | interface CellRendererProps {

FILE: src/components/common/CollapsibleHeader.tsx
  type CollapsibleHeaderProps (line 6) | interface CollapsibleHeaderProps {

FILE: src/components/common/CollapsiblePanel.tsx
  type CollapsiblePanelProps (line 5) | interface CollapsiblePanelProps {

FILE: src/components/common/ColorSwatch.tsx
  type ColorSwatchProps (line 3) | interface ColorSwatchProps {

FILE: src/components/common/DraggableDialogBar.tsx
  type DraggableDialogBarProps (line 5) | interface DraggableDialogBarProps {

FILE: src/components/common/PanelSeparator.tsx
  type PanelSeparatorProps (line 23) | interface PanelSeparatorProps {

FILE: src/components/common/PanelToggleButton.tsx
  type PanelToggleButtonProps (line 8) | interface PanelToggleButtonProps {

FILE: src/components/common/PerformanceMonitor.tsx
  type PerformanceTestResult (line 10) | interface PerformanceTestResult {

FILE: src/components/common/Spinner.tsx
  type SpinnerProps (line 4) | interface SpinnerProps {

FILE: src/components/common/ThemeToggle.tsx
  function ThemeToggle (line 6) | function ThemeToggle() {

FILE: src/components/demos/SimpleAsciiDemo.tsx
  constant FRAMES (line 11) | const FRAMES = [

FILE: src/components/features/AboutDialog.tsx
  type AboutDialogProps (line 12) | interface AboutDialogProps {

FILE: src/components/features/AccountButton.tsx
  function AccountButton (line 23) | function AccountButton() {

FILE: src/components/features/ActiveLayerIndicator.tsx
  function ActiveLayerIndicator (line 14) | function ActiveLayerIndicator() {

FILE: src/components/features/ActiveStyleSection.tsx
  type ActiveStyleSectionProps (line 28) | interface ActiveStyleSectionProps {
  function ActiveStyleSection (line 32) | function ActiveStyleSection({ className = '' }: ActiveStyleSectionProps) {

FILE: src/components/features/AnchorPointOverlay.tsx
  constant EMPTY_LAYERS (line 25) | const EMPTY_LAYERS: Layer[] = [];

FILE: src/components/features/AsciiBoxPanel.tsx
  function AsciiBoxPanel (line 28) | function AsciiBoxPanel() {

FILE: src/components/features/AsciiTypePanel.tsx
  constant LAYOUT_LABELS (line 47) | const LAYOUT_LABELS: Record<AsciiTypeLayoutPreset, string> = {
  function AsciiTypePanel (line 55) | function AsciiTypePanel() {

FILE: src/components/features/AsciiTypePreviewDialog.tsx
  constant DIALOG_WIDTH (line 25) | const DIALOG_WIDTH = 680;
  type FontPreviewState (line 27) | interface FontPreviewState {
  function AsciiTypePreviewDialog (line 32) | function AsciiTypePreviewDialog() {

FILE: src/components/features/AuthButtons.tsx
  function AuthButtons (line 8) | function AuthButtons() {

FILE: src/components/features/BackgroundColorMappingSection.tsx
  type BackgroundColorMappingSectionProps (line 53) | interface BackgroundColorMappingSectionProps {
  function BackgroundColorMappingSection (line 57) | function BackgroundColorMappingSection({ onSettingsChange }: BackgroundC...

FILE: src/components/features/BezierActionButtons.tsx
  type BezierActionButtonsProps (line 15) | interface BezierActionButtonsProps {

FILE: src/components/features/BrushControls.tsx
  type BrushControlsProps (line 16) | interface BrushControlsProps {

FILE: src/components/features/BrushPreview.tsx
  type BrushPreviewProps (line 13) | interface BrushPreviewProps {

FILE: src/components/features/BrushSizePreviewOverlay.tsx
  type OverlayState (line 24) | type OverlayState = 'hidden' | 'entering' | 'visible' | 'exiting';

FILE: src/components/features/CanvasActionButtons.tsx
  type ResizeHistoryAction (line 26) | interface ResizeHistoryAction {
  type TimeEffectHistoryAction (line 38) | interface TimeEffectHistoryAction {
  type DurationHistoryAction (line 45) | interface DurationHistoryAction {

FILE: src/components/features/CanvasGrid.tsx
  type CanvasGridProps (line 20) | interface CanvasGridProps {

FILE: src/components/features/CanvasOverlay.tsx
  type GradientPropertyKey (line 18) | type GradientPropertyKey = 'character' | 'textColor' | 'backgroundColor';

FILE: src/components/features/CanvasResizeDialog.tsx
  type CanvasResizeDialogProps (line 26) | interface CanvasResizeDialogProps {
  function CanvasResizeDialog (line 40) | function CanvasResizeDialog({ isOpen, onOpenChange }: CanvasResizeDialog...

FILE: src/components/features/CanvasSizePicker.tsx
  type CanvasSizePickerProps (line 5) | interface CanvasSizePickerProps {

FILE: src/components/features/CanvasWithShortcuts.tsx
  type Window (line 6) | interface Window {
  type CanvasWithShortcutsProps (line 14) | interface CanvasWithShortcutsProps {

FILE: src/components/features/CharacterMappingControls.tsx
  type CharacterMappingControlsProps (line 25) | interface CharacterMappingControlsProps {
  function CharacterMappingControls (line 29) | function CharacterMappingControls({ onSettingsChange }: CharacterMapping...

FILE: src/components/features/CharacterMappingSection.tsx
  type CharacterMappingSectionProps (line 57) | interface CharacterMappingSectionProps {
  function CharacterMappingSection (line 61) | function CharacterMappingSection({ onSettingsChange }: CharacterMappingS...

FILE: src/components/features/CharacterPalette.tsx
  type CharacterPaletteProps (line 21) | interface CharacterPaletteProps {
  constant CATEGORY_ICONS (line 25) | const CATEGORY_ICONS = {

FILE: src/components/features/CharacterPaletteEditor.tsx
  type CharacterPaletteEditorProps (line 33) | interface CharacterPaletteEditorProps {
  function CharacterPaletteEditor (line 37) | function CharacterPaletteEditor({ onPaletteChange }: CharacterPaletteEdi...

FILE: src/components/features/ColorPicker.tsx
  type ColorPickerProps (line 22) | interface ColorPickerProps {

FILE: src/components/features/ColorPickerOverlay.tsx
  type ColorPickerOverlayProps (line 26) | interface ColorPickerOverlayProps {

FILE: src/components/features/ColorPicker_new.tsx
  type ColorPickerProps (line 18) | interface ColorPickerProps {

FILE: src/components/features/ColorReadout.tsx
  type ColorReadoutProps (line 10) | interface ColorReadoutProps {

FILE: src/components/features/EffectsSection.tsx
  type EffectsSectionProps (line 21) | interface EffectsSectionProps {
  function EffectsSection (line 25) | function EffectsSection({ className = '' }: EffectsSectionProps) {

FILE: src/components/features/EnhancedCharacterPicker.tsx
  type EnhancedCharacterPickerProps (line 22) | interface EnhancedCharacterPickerProps {
  constant CATEGORY_ICONS (line 32) | const CATEGORY_ICONS = {

FILE: src/components/features/ExportCharacterPaletteDialog.tsx
  type ExportCharacterPaletteDialogProps (line 15) | interface ExportCharacterPaletteDialogProps {

FILE: src/components/features/ExportImportButtons.tsx
  constant EXPORT_OPTIONS (line 16) | const EXPORT_OPTIONS = [
  constant IMPORT_OPTIONS (line 80) | const IMPORT_OPTIONS = [

FILE: src/components/features/ExportPaletteDialog.tsx
  type ExportPaletteDialogProps (line 15) | interface ExportPaletteDialogProps {

FILE: src/components/features/ForegroundBackgroundSelector.tsx
  type ForegroundBackgroundSelectorProps (line 11) | interface ForegroundBackgroundSelectorProps {

FILE: src/components/features/FullscreenToggle.tsx
  type FullscreenToggleProps (line 6) | interface FullscreenToggleProps {

FILE: src/components/features/GeneratorsPanel.tsx
  constant GENERATOR_ICONS (line 40) | const GENERATOR_ICONS = {
  function GeneratorsPanel (line 54) | function GeneratorsPanel() {

FILE: src/components/features/GeneratorsSection.tsx
  constant GENERATOR_ICONS (line 32) | const GENERATOR_ICONS = {
  type GeneratorsSectionProps (line 40) | interface GeneratorsSectionProps {
  function GeneratorsSection (line 44) | function GeneratorsSection({ className = '' }: GeneratorsSectionProps) {

FILE: src/components/features/GradientPanel.tsx
  function GradientPanel (line 71) | function GradientPanel() {

FILE: src/components/features/GradientPropertyPreview.tsx
  constant MAX_PREVIEW_WIDTH (line 8) | const MAX_PREVIEW_WIDTH = 256;
  constant PREVIEW_HEIGHT (line 9) | const PREVIEW_HEIGHT = 24;
  constant TILE_SIZE (line 10) | const TILE_SIZE = 4;
  type GradientPropertyKey (line 12) | type GradientPropertyKey = 'character' | 'textColor' | 'backgroundColor';
  type GradientPropertyPreviewProps (line 14) | interface GradientPropertyPreviewProps {

FILE: src/components/features/GradientStopPicker.tsx
  type GradientStopPickerProps (line 5) | interface GradientStopPickerProps {

FILE: src/components/features/HamburgerMenu.tsx
  type HamburgerMenuProps (line 24) | interface HamburgerMenuProps {

FILE: src/components/features/ImageExportDialog.tsx
  constant FORMAT_OPTIONS (line 28) | const FORMAT_OPTIONS: Array<{ value: 'png' | 'jpg' | 'svg'; label: strin...

FILE: src/components/features/ImportCharacterPaletteDialog.tsx
  type ImportCharacterPaletteDialogProps (line 15) | interface ImportCharacterPaletteDialogProps {

FILE: src/components/features/ImportPaletteDialog.tsx
  type ImportPaletteDialogProps (line 16) | interface ImportPaletteDialogProps {

FILE: src/components/features/InlineProjectNameEditor.tsx
  function InlineProjectNameEditor (line 21) | function InlineProjectNameEditor() {

FILE: src/components/features/InteractiveBezierOverlay.tsx
  function distanceToSegment (line 688) | function distanceToSegment(px: number, py: number, x1: number, y1: numbe...

FILE: src/components/features/InteractiveVectorShapeOverlay.tsx
  type HandleId (line 28) | type HandleId = 'nw' | 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w';
  constant HANDLE_RADIUS (line 30) | const HANDLE_RADIUS = 5;
  constant HANDLE_HIT_RADIUS (line 31) | const HANDLE_HIT_RADIUS = 8;

FILE: src/components/features/KeyboardShortcutsDialog.tsx
  type KeyboardShortcutsDialogProps (line 8) | interface KeyboardShortcutsDialogProps {
  type ShortcutItem (line 13) | interface ShortcutItem {
  type ShortcutSection (line 18) | interface ShortcutSection {
  constant KEYBOARD_SHORTCUTS (line 23) | const KEYBOARD_SHORTCUTS: ShortcutSection[] = [

FILE: src/components/features/MCPConnectionDialog.tsx
  type MCPConnectionDialogProps (line 20) | interface MCPConnectionDialogProps {

FILE: src/components/features/MainCharacterPaletteSection.tsx
  type MainCharacterPaletteSectionProps (line 50) | interface MainCharacterPaletteSectionProps {
  function MainCharacterPaletteSection (line 54) | function MainCharacterPaletteSection({ className = '' }: MainCharacterPa...

FILE: src/components/features/ManageCharacterPalettesDialog.tsx
  type ManageCharacterPalettesDialogProps (line 10) | interface ManageCharacterPalettesDialogProps {

FILE: src/components/features/ManagePalettesDialog.tsx
  type ManagePalettesDialogProps (line 10) | interface ManagePalettesDialogProps {

FILE: src/components/features/MediaImportPanel.tsx
  function applyColorKey (line 93) | function applyColorKey(
  function hexToRgb (line 163) | function hexToRgb(hex: string): [number, number, number] {
  type CropAlignmentOption (line 168) | type CropAlignmentOption = {
  function MediaImportPanel (line 185) | function MediaImportPanel() {

FILE: src/components/features/NewProjectDialog.tsx
  function NewProjectDialog (line 30) | function NewProjectDialog() {

FILE: src/components/features/PlaybackControls.tsx
  type PlaybackControlsProps (line 7) | interface PlaybackControlsProps {

FILE: src/components/features/PlaybackOverlay.tsx
  type PlaybackOverlayProps (line 8) | interface PlaybackOverlayProps {

FILE: src/components/features/PostEffectsSection.tsx
  type PostEffectsSectionProps (line 22) | interface PostEffectsSectionProps {
  function PostEffectsSection (line 26) | function PostEffectsSection({ className = '' }: PostEffectsSectionProps) {

FILE: src/components/features/PreprocessingSection.tsx
  type PreprocessingSectionProps (line 40) | interface PreprocessingSectionProps {
  function PreprocessingSection (line 44) | function PreprocessingSection({ onSettingsChange }: PreprocessingSection...

FILE: src/components/features/ProjectCanvasPreview.tsx
  type ProjectCanvasPreviewProps (line 14) | interface ProjectCanvasPreviewProps {
  function getFirstFrameCells (line 24) | function getFirstFrameCells(

FILE: src/components/features/ProjectSettingsDialog.tsx
  function ProjectSettingsDialog (line 27) | function ProjectSettingsDialog() {

FILE: src/components/features/ProjectsDialog.tsx
  constant CACHE_KEY_PROJECTS (line 75) | const CACHE_KEY_PROJECTS = 'ascii-motion:projects-cache';
  constant CACHE_KEY_DELETED (line 76) | const CACHE_KEY_DELETED = 'ascii-motion:deleted-projects-cache';
  constant CACHE_KEY_PROFILE (line 77) | const CACHE_KEY_PROFILE = 'ascii-motion:user-profile-cache';
  function hasSessionStorage (line 79) | function hasSessionStorage(): boolean {
  function getCachedProjects (line 83) | function getCachedProjects(): CloudProject[] | null {
  function getCachedDeletedProjects (line 91) | function getCachedDeletedProjects(): CloudProject[] | null {
  function getCachedUserProfile (line 99) | function getCachedUserProfile(): UserProfile | null {
  function setCachedProjects (line 107) | function setCachedProjects(projects: CloudProject[]) {
  function setCachedDeletedProjects (line 112) | function setCachedDeletedProjects(projects: CloudProject[]) {
  function setCachedUserProfile (line 117) | function setCachedUserProfile(profile: UserProfile) {
  function ProjectCardSkeleton (line 123) | function ProjectCardSkeleton() {
  type ProjectsDialogProps (line 148) | interface ProjectsDialogProps {
  function ProjectsDialog (line 156) | function ProjectsDialog({

FILE: src/components/features/PublishToGalleryDialogWrapper.tsx
  type PublishToGalleryDialogWrapperProps (line 16) | interface PublishToGalleryDialogWrapperProps {
  function PublishToGalleryDialogWrapper (line 22) | function PublishToGalleryDialogWrapper({

FILE: src/components/features/PublishedProjectSaveWarningDialog.tsx
  type PublishedProjectSaveWarningDialogProps (line 16) | interface PublishedProjectSaveWarningDialogProps {
  function PublishedProjectSaveWarningDialog (line 23) | function PublishedProjectSaveWarningDialog({

FILE: src/components/features/SaveToCloudDialog.tsx
  type SaveToCloudDialogProps (line 39) | interface SaveToCloudDialogProps {
  function SaveToCloudDialog (line 44) | function SaveToCloudDialog({ open, onOpenChange }: SaveToCloudDialogProp...

FILE: src/components/features/SilentSaveHandler.tsx
  function SilentSaveHandler (line 26) | function SilentSaveHandler() {

FILE: src/components/features/TextColorMappingSection.tsx
  type TextColorMappingSectionProps (line 53) | interface TextColorMappingSectionProps {
  function TextColorMappingSection (line 57) | function TextColorMappingSection({ onSettingsChange }: TextColorMappingS...

FILE: src/components/features/ToolPalette.tsx
  type ToolPaletteProps (line 46) | interface ToolPaletteProps {
  constant DRAWING_TOOLS (line 71) | const DRAWING_TOOLS: Array<{ id: Tool; name: string; icon: React.ReactNo...
  constant SELECTION_TOOLS (line 84) | const SELECTION_TOOLS: Array<{ id: Tool; name: string; icon: React.React...
  constant UTILITY_TOOLS (line 90) | const UTILITY_TOOLS: Array<{ id: Tool; name: string; icon: React.ReactNo...

FILE: src/components/features/ToolPalette_backup.tsx
  type ToolPaletteProps (line 23) | interface ToolPaletteProps {
  constant DRAWING_TOOLS (line 48) | const DRAWING_TOOLS: Array<{ id: Tool; name: string; icon: React.ReactNo...
  constant SELECTION_TOOLS (line 57) | const SELECTION_TOOLS: Array<{ id: Tool; name: string; icon: React.React...
  constant UTILITY_TOOLS (line 64) | const UTILITY_TOOLS: Array<{ id: Tool; name: string; icon: React.ReactNo...

FILE: src/components/features/ToolPalette_new.tsx
  type ToolPaletteProps (line 23) | interface ToolPaletteProps {
  constant DRAWING_TOOLS (line 48) | const DRAWING_TOOLS: Array<{ id: Tool; name: string; icon: React.ReactNo...
  constant SELECTION_TOOLS (line 57) | const SELECTION_TOOLS: Array<{ id: Tool; name: string; icon: React.React...
  constant UTILITY_TOOLS (line 64) | const UTILITY_TOOLS: Array<{ id: Tool; name: string; icon: React.ReactNo...

FILE: src/components/features/TransparencySection.tsx
  type TransparencySectionProps (line 30) | interface TransparencySectionProps {
  function TransparencySection (line 38) | function TransparencySection({ onSettingsChange, previewFrames = [], fra...

FILE: src/components/features/UpgradeToProDialog.tsx
  type UpgradeToProDialogProps (line 22) | interface UpgradeToProDialogProps {
  function UpgradeToProDialog (line 31) | function UpgradeToProDialog({

FILE: src/components/features/WelcomeAsciiAnimationData.tsx
  type CellData (line 8) | type CellData = {
  type Frame (line 16) | type Frame = {
  constant FRAMES (line 21) | const FRAMES: Frame[] = [

FILE: src/components/features/generators/DigitalRainSettings.tsx
  function DigitalRainSettings (line 14) | function DigitalRainSettings() {

FILE: src/components/features/generators/GeneratorsMappingTab.tsx
  function GeneratorsMappingTab (line 33) | function GeneratorsMappingTab() {

FILE: src/components/features/generators/ParticlePhysicsSettings.tsx
  function ParticlePhysicsSettings (line 16) | function ParticlePhysicsSettings() {

FILE: src/components/features/generators/PlaceholderGeneratorSettings.tsx
  type PlaceholderGeneratorSettingsProps (line 11) | interface PlaceholderGeneratorSettingsProps {
  function PlaceholderGeneratorSettings (line 19) | function PlaceholderGeneratorSettings({

FILE: src/components/features/generators/RadioWavesSettings.tsx
  function RadioWavesSettings (line 21) | function RadioWavesSettings() {

FILE: src/components/features/generators/RainDropsSettings.tsx
  function RainDropsSettings (line 14) | function RainDropsSettings() {

FILE: src/components/features/generators/TurbulentNoiseSettings.tsx
  function TurbulentNoiseSettings (line 15) | function TurbulentNoiseSettings() {

FILE: src/components/features/preview/GeneratorPreviewCanvas.tsx
  type GeneratorPreviewCanvasProps (line 22) | interface GeneratorPreviewCanvasProps {
  function GeneratorPreviewCanvas (line 31) | function GeneratorPreviewCanvas({

FILE: src/components/features/timeline/ContentFrameBlock.tsx
  type ContentFrameBlockProps (line 23) | interface ContentFrameBlockProps {
  constant DRAG_THRESHOLD (line 31) | const DRAG_THRESHOLD = 4;

FILE: src/components/features/timeline/EasingCurveEditor.tsx
  type EasingCurveEditorProps (line 19) | interface EasingCurveEditorProps {
  constant SVG_SIZE (line 26) | const SVG_SIZE = 160;
  constant PADDING (line 27) | const PADDING = 16;
  constant GRAPH_SIZE (line 28) | const GRAPH_SIZE = SVG_SIZE - PADDING * 2;
  constant HANDLE_RADIUS (line 29) | const HANDLE_RADIUS = 5;
  constant PRESET_ORDER (line 32) | const PRESET_ORDER: EasingPreset[] = [
  constant PRESET_LABELS (line 44) | const PRESET_LABELS: Record<EasingPreset, string> = {
  function toSvg (line 58) | function toSvg(nx: number, ny: number): { x: number; y: number } {
  function fromSvg (line 66) | function fromSvg(sx: number, sy: number): { nx: number; ny: number } {
  function getControlPoints (line 74) | function getControlPoints(curve: EasingCurve): [number, number, number, ...
  function buildCurvePath (line 82) | function buildCurvePath(cp: [number, number, number, number]): string {
  function buildMiniPath (line 91) | function buildMiniPath(cp: [number, number, number, number], size: numbe...

FILE: src/components/features/timeline/EffectBlock.tsx
  type EffectBlockProps (line 15) | interface EffectBlockProps {
  constant CATEGORY_COLORS (line 20) | const CATEGORY_COLORS: Record<string, { bg: string; border: string; sele...
  constant DEFAULT_COLORS (line 27) | const DEFAULT_COLORS = { bg: 'bg-muted-foreground/15', border: 'border-m...

FILE: src/components/features/timeline/EffectPropertiesPanel.tsx
  function findTrackByBlockId (line 31) | function findTrackByBlockId(blockId: string): { track: EffectTrack; owne...
  type EffectPropertyRowProps (line 62) | interface EffectPropertyRowProps {
  type ColorSwatchRowProps (line 309) | interface ColorSwatchRowProps {
  type MappingEditorProps (line 354) | interface MappingEditorProps {

FILE: src/components/features/timeline/EffectTrackRow.tsx
  type EffectTrackRowProps (line 18) | interface EffectTrackRowProps {

FILE: src/components/features/timeline/FrameRateControl.tsx
  constant FPS_PRESETS (line 37) | const FPS_PRESETS = [1, 2, 4, 8, 10, 12, 15, 24, 25, 30, 60] as const;

FILE: src/components/features/timeline/GroupHeader.tsx
  type GroupHeaderProps (line 43) | interface GroupHeaderProps {

FILE: src/components/features/timeline/GroupPropertiesPanel.tsx
  constant GROUP_TRANSFORM_PROPERTIES (line 26) | const GROUP_TRANSFORM_PROPERTIES: PropertyPath[] = [
  type GroupPropertyRowProps (line 36) | interface GroupPropertyRowProps {

FILE: src/components/features/timeline/KeyframeDiamond.tsx
  function findTrackAndKeyframe (line 16) | function findTrackAndKeyframe(trackId: PropertyTrackId, kfId: KeyframeId) {
  type KeyframeDiamondProps (line 63) | interface KeyframeDiamondProps {
  type KfEntry (line 129) | type KfEntry = { layerId: LayerId; trackId: PropertyTrackId; kfId: Keyfr...

FILE: src/components/features/timeline/LayerContextMenu.tsx
  type LayerContextMenuState (line 36) | interface LayerContextMenuState {
  type Props (line 42) | interface Props {

FILE: src/components/features/timeline/LayerList.tsx
  type LayerListProps (line 28) | interface LayerListProps {

FILE: src/components/features/timeline/LayerListItem.tsx
  type LayerListItemProps (line 30) | interface LayerListItemProps {

FILE: src/components/features/timeline/LayerPropertiesPanel.tsx
  constant TRANSFORM_PROPERTIES (line 37) | const TRANSFORM_PROPERTIES: PropertyPath[] = [
  type PropertyRowProps (line 47) | interface PropertyRowProps {

FILE: src/components/features/timeline/PostEffectBlock.tsx
  constant CATEGORY_COLORS (line 16) | const CATEGORY_COLORS: Record<string, { bg: string; border: string; sele...
  constant DEFAULT_COLORS (line 23) | const DEFAULT_COLORS = { bg: 'bg-muted/30', border: 'border-border/50', ...
  type PostEffectBlockProps (line 25) | interface PostEffectBlockProps {

FILE: src/components/features/timeline/PostEffectPropertiesPanel.tsx
  type PostEffectPropertyRowProps (line 28) | interface PostEffectPropertyRowProps {
  type ColorSwatchRowProps (line 279) | interface ColorSwatchRowProps {

FILE: src/components/features/timeline/PostEffectsTrackHeader.tsx
  constant POST_EFFECT_CATEGORY_COLORS (line 29) | const POST_EFFECT_CATEGORY_COLORS: Record<string, { bg: string; border: ...
  constant DEFAULT_COLORS (line 36) | const DEFAULT_COLORS = { bg: 'bg-muted/30', border: 'border-border/50', ...

FILE: src/components/features/timeline/TimecodeDisplay.tsx
  function formatName (line 33) | function formatName(format: TimecodeFormat): string {

FILE: src/components/features/timeline/TimelineContextMenu.tsx
  type TimelineContextMenuType (line 54) | type TimelineContextMenuType =
  type TimelineContextMenuState (line 60) | interface TimelineContextMenuState {
  type Props (line 66) | interface Props {
  constant LABEL_COLORS (line 105) | const LABEL_COLORS = [

FILE: src/components/features/timeline/TimelineResizeHandle.tsx
  constant MIN_HEIGHT (line 15) | const MIN_HEIGHT = 140;
  constant MAX_HEIGHT (line 16) | const MAX_HEIGHT = 600;
  type TimelineResizeHandleProps (line 19) | interface TimelineResizeHandleProps {

FILE: src/components/features/timeline/TimelineRuler.tsx
  constant BASE_PX_PER_FRAME (line 17) | const BASE_PX_PER_FRAME = 12;
  constant MIN_DURATION (line 19) | const MIN_DURATION = 1;

FILE: src/components/features/timeline/TimelineToolbar.tsx
  constant BTN (line 49) | const BTN = "h-7 px-1.5";
  constant BTN_ICON (line 50) | const BTN_ICON = "w-3.5 h-3.5";

FILE: src/components/features/timeline/TimelineTrackArea.tsx
  constant BASE_PX_PER_FRAME (line 30) | const BASE_PX_PER_FRAME = 12;
  type TimelineTrackAreaProps (line 32) | interface TimelineTrackAreaProps {

FILE: src/components/features/timeline/timecodeUtils.ts
  function formatTimecodeValue (line 9) | function formatTimecodeValue(
  function formatLabel (line 31) | function formatLabel(format: TimecodeFormat): string {
  function parseTimecodeInput (line 49) | function parseTimecodeInput(

FILE: src/components/features/timeline/timelineRulerUtils.ts
  function getTickInterval (line 8) | function getTickInterval(zoom: number, frameRate: number): { minor: numb...
  function formatFrameLabel (line 17) | function formatFrameLabel(frame: number, frameRate: number): string {

FILE: src/components/icons/types.ts
  type IconProps (line 5) | interface IconProps extends React.SVGAttributes<SVGElement> {

FILE: src/components/tools/index.ts
  type ToolComponent (line 20) | type ToolComponent =

FILE: src/components/ui/badge.tsx
  type BadgeProps (line 26) | interface BadgeProps
  function Badge (line 30) | function Badge({ className, variant, ...props }: BadgeProps) {

FILE: src/components/ui/button.tsx
  type ButtonProps (line 37) | interface ButtonProps

FILE: src/components/ui/menubar.tsx
  function MenubarMenu (line 7) | function MenubarMenu({
  function MenubarGroup (line 13) | function MenubarGroup({
  function MenubarPortal (line 19) | function MenubarPortal({
  function MenubarRadioGroup (line 25) | function MenubarRadioGroup({
  function MenubarSub (line 31) | function MenubarSub({

FILE: src/components/ui/sheet.tsx
  type SheetContentProps (line 52) | interface SheetContentProps

FILE: src/components/ui/skeleton.tsx
  function Skeleton (line 3) | function Skeleton({

FILE: src/components/ui/slider.tsx
  type SliderProps (line 4) | interface SliderProps extends Omit<React.InputHTMLAttributes<HTMLInputEl...

FILE: src/components/ui/sonner.tsx
  type ToasterProps (line 6) | type ToasterProps = React.ComponentProps<typeof Sonner>

FILE: src/constants/bezierAutofill/ansiCharacters.ts
  constant ANSI_CHARACTERS_PALETTE (line 18) | const ANSI_CHARACTERS_PALETTE: AutofillPalette = {

FILE: src/constants/bezierAutofill/ansiCharacters_backup.ts
  constant ANSI_CHARACTERS_PALETTE (line 18) | const ANSI_CHARACTERS_PALETTE: AutofillPalette = {

FILE: src/constants/bezierAutofill/blockCharacters.ts
  constant BLOCK_CHARACTERS_PALETTE (line 32) | const BLOCK_CHARACTERS_PALETTE: AutofillPalette = {

FILE: src/constants/bezierAutofill/brailleCharacters.ts
  constant BRAILLE_CHARACTERS_PALETTE (line 23) | const BRAILLE_CHARACTERS_PALETTE: AutofillPalette = {

FILE: src/constants/bezierAutofill/index.ts
  constant AUTOFILL_PALETTES (line 17) | const AUTOFILL_PALETTES: AutofillPalette[] = [
  constant DEFAULT_PALETTE_ID (line 26) | const DEFAULT_PALETTE_ID = 'block';
  function getPaletteById (line 34) | function getPaletteById(id: string): AutofillPalette | undefined {
  function getAvailablePaletteIds (line 44) | function getAvailablePaletteIds(): string[] {
  function getPaletteDisplayInfo (line 54) | function getPaletteDisplayInfo(): Array<{ id: string; name: string; desc...
  function doesPatternMatch (line 69) | function doesPatternMatch(pattern: RegionPattern, filledRegions: Set<Reg...
  function getCharacterForPattern (line 91) | function getCharacterForPattern(

FILE: src/constants/bezierAutofill/types.ts
  type RegionName (line 14) | type RegionName = 'TL' | 'TC' | 'TR' | 'ML' | 'MC' | 'MR' | 'BL' | 'BC' ...
  type RegionPattern (line 20) | interface RegionPattern {
  type AutofillPalette (line 35) | interface AutofillPalette {

FILE: src/constants/boxDrawingStyles.ts
  type BoxDrawingStyle (line 8) | interface BoxDrawingStyle {
  constant BOX_DRAWING_STYLES (line 37) | const BOX_DRAWING_STYLES: BoxDrawingStyle[] = [
  function getAllBoxDrawingCharacters (line 164) | function getAllBoxDrawingCharacters(): Set<string> {
  function isBoxDrawingCharacter (line 179) | function isBoxDrawingCharacter(char: string): boolean {
  function getBoxDrawingStyle (line 187) | function getBoxDrawingStyle(id: string): BoxDrawingStyle | undefined {

FILE: src/constants/colors.ts
  constant ANSI_COLORS (line 6) | const ANSI_COLORS = {
  constant SEMANTIC_COLORS (line 34) | const SEMANTIC_COLORS = {
  constant ANSI_CSS_VARS (line 49) | const ANSI_CSS_VARS = {
  type AnsiColor (line 68) | type AnsiColor = keyof typeof ANSI_COLORS
  type SemanticColor (line 69) | type SemanticColor = keyof typeof SEMANTIC_COLORS

FILE: src/constants/defaultCharacterPalettes.ts
  constant MINIMAL_ASCII_PALETTE (line 28) | const MINIMAL_ASCII_PALETTE: CharacterPalette = createCharacterPalette(
  constant STANDARD_ASCII_PALETTE (line 39) | const STANDARD_ASCII_PALETTE: CharacterPalette = createCharacterPalette(
  constant BLOCK_CHARACTERS_PALETTE (line 56) | const BLOCK_CHARACTERS_PALETTE: CharacterPalette = createCharacterPalette(
  constant EXTENDED_UNICODE_PALETTE (line 67) | const EXTENDED_UNICODE_PALETTE: CharacterPalette = createCharacterPalette(
  constant DOTS_LINES_PALETTE (line 85) | const DOTS_LINES_PALETTE: CharacterPalette = createCharacterPalette(
  constant RETRO_COMPUTING_PALETTE (line 102) | const RETRO_COMPUTING_PALETTE: CharacterPalette = createCharacterPalette(
  constant DEFAULT_CHARACTER_PALETTES (line 117) | const DEFAULT_CHARACTER_PALETTES: CharacterPalette[] = [

FILE: src/constants/defaultPalettes.ts
  constant ANSI_PALETTE (line 21) | const ANSI_PALETTE: ColorPalette = {
  constant WEB_SAFE_PALETTE (line 49) | const WEB_SAFE_PALETTE: ColorPalette = {
  constant MATERIAL_DESIGN_PALETTE (line 74) | const MATERIAL_DESIGN_PALETTE: ColorPalette = {
  constant RETRO_8BIT_PALETTE (line 157) | const RETRO_8BIT_PALETTE: ColorPalette = {
  constant EARTH_TONES_PALETTE (line 185) | const EARTH_TONES_PALETTE: ColorPalette = {
  constant COOL_BLUES_PALETTE (line 213) | const COOL_BLUES_PALETTE: ColorPalette = {
  constant WARM_REDS_PALETTE (line 241) | const WARM_REDS_PALETTE: ColorPalette = {
  constant BRIGHT_GREENS_PALETTE (line 269) | const BRIGHT_GREENS_PALETTE: ColorPalette = {
  constant FIERY_SUNSET_PALETTE (line 289) | const FIERY_SUNSET_PALETTE: ColorPalette = {
  constant LUMINOUS_GLOW_PALETTE (line 311) | const LUMINOUS_GLOW_PALETTE: ColorPalette = {
  constant PURPLE_RAIN_PALETTE (line 328) | const PURPLE_RAIN_PALETTE: ColorPalette = {
  constant SOFT_RAINBOW_PALETTE (line 350) | const SOFT_RAINBOW_PALETTE: ColorPalette = {
  constant SUNSET_GRADIENT_PALETTE (line 372) | const SUNSET_GRADIENT_PALETTE: ColorPalette = {
  constant VIVID_NIGHTFALL_PALETTE (line 394) | const VIVID_NIGHTFALL_PALETTE: ColorPalette = {
  constant VIBRANT_FIESTA_PALETTE (line 414) | const VIBRANT_FIESTA_PALETTE: ColorPalette = {
  constant COMMODORE_64_PALETTE (line 432) | const COMMODORE_64_PALETTE: ColorPalette = {
  constant DEFAULT_PALETTES (line 460) | const DEFAULT_PALETTES: ColorPalette[] = [
  constant DEFAULT_ACTIVE_PALETTE_ID (line 482) | const DEFAULT_ACTIVE_PALETTE_ID = 'ansi-16';

FILE: src/constants/effectsDefaults.ts
  constant EFFECT_DEFINITIONS (line 18) | const EFFECT_DEFINITIONS: EffectDefinition[] = [
  constant DEFAULT_LEVELS_SETTINGS (line 64) | const DEFAULT_LEVELS_SETTINGS: LevelsEffectSettings = {
  constant DEFAULT_HUE_SATURATION_SETTINGS (line 80) | const DEFAULT_HUE_SATURATION_SETTINGS: HueSaturationEffectSettings = {
  constant DEFAULT_REMAP_COLORS_SETTINGS (line 92) | const DEFAULT_REMAP_COLORS_SETTINGS: RemapColorsEffectSettings = {
  constant DEFAULT_REMAP_CHARACTERS_SETTINGS (line 106) | const DEFAULT_REMAP_CHARACTERS_SETTINGS: RemapCharactersEffectSettings = {
  constant DEFAULT_SCATTER_SETTINGS (line 111) | const DEFAULT_SCATTER_SETTINGS: ScatterEffectSettings = {
  constant DEFAULT_MOTION_TRAILS_SETTINGS (line 125) | const DEFAULT_MOTION_TRAILS_SETTINGS: MotionTrailsSettings = {
  constant CANVAS_ANALYSIS (line 141) | const CANVAS_ANALYSIS = {
  constant EFFECT_LIMITS (line 153) | const EFFECT_LIMITS = {

FILE: src/constants/features.ts
  constant FEATURES (line 24) | const FEATURES = {
  type FeatureFlag (line 47) | type FeatureFlag = keyof typeof FEATURES;

FILE: src/constants/figletFonts.ts
  type FigletFontCategory (line 1) | interface FigletFontCategory {
  constant FIGLET_FONTS_BY_CATEGORY (line 6) | const FIGLET_FONTS_BY_CATEGORY: FigletFontCategory[] = [
  constant ALL_FIGLET_FONTS (line 357) | const ALL_FIGLET_FONTS: string[] = FIGLET_FONTS_BY_CATEGORY.flatMap((cat...

FILE: src/constants/fonts.d.ts
  type MonospaceFont (line 5) | interface MonospaceFont {

FILE: src/constants/fonts.ts
  type MonospaceFont (line 6) | interface MonospaceFont {
  constant MONOSPACE_FONTS (line 18) | const MONOSPACE_FONTS: MonospaceFont[] = [
  constant DEFAULT_FONT_ID (line 163) | const DEFAULT_FONT_ID = 'auto';

FILE: src/constants/generators.ts
  constant GENERATOR_DEFINITIONS (line 17) | const GENERATOR_DEFINITIONS: GeneratorDefinition[] = [
  constant DEFAULT_RADIO_WAVES_SETTINGS (line 52) | const DEFAULT_RADIO_WAVES_SETTINGS: RadioWavesSettings = {
  constant DEFAULT_TURBULENT_NOISE_SETTINGS (line 83) | const DEFAULT_TURBULENT_NOISE_SETTINGS: TurbulentNoiseSettings = {
  constant DEFAULT_PARTICLE_PHYSICS_SETTINGS (line 106) | const DEFAULT_PARTICLE_PHYSICS_SETTINGS: ParticlePhysicsSettings = {
  constant DEFAULT_RAIN_DROPS_SETTINGS (line 162) | const DEFAULT_RAIN_DROPS_SETTINGS: RainDropsSettings = {
  constant DEFAULT_DIGITAL_RAIN_SETTINGS (line 194) | const DEFAULT_DIGITAL_RAIN_SETTINGS: DigitalRainSettings = {
  constant GENERATOR_LIMITS (line 230) | const GENERATOR_LIMITS = {
  constant PREVIEW_DEBOUNCE_MS (line 259) | const PREVIEW_DEBOUNCE_MS = GENERATOR_LIMITS.PREVIEW_DEBOUNCE_MS;
  constant LOOP_SMOOTHING (line 262) | const LOOP_SMOOTHING = {

FILE: src/constants/hotkeys.ts
  type ToolHotkey (line 8) | interface ToolHotkey {
  constant TOOL_HOTKEYS (line 24) | const TOOL_HOTKEYS: ToolHotkey[] = [
  constant HOTKEY_TO_TOOL (line 45) | const HOTKEY_TO_TOOL = new Map<string, Tool>(
  constant TOOL_TO_HOTKEY (line 49) | const TOOL_TO_HOTKEY = new Map<Tool, ToolHotkey>(

FILE: src/constants/index.ts
  constant PANEL_ANIMATION (line 10) | const PANEL_ANIMATION = {
  constant CHARACTER_CATEGORIES (line 16) | const CHARACTER_CATEGORIES = {
  constant DEFAULT_CANVAS_SIZES (line 90) | const DEFAULT_CANVAS_SIZES = [
  constant DEFAULT_COLORS (line 98) | const DEFAULT_COLORS = [
  constant EXPORT_FORMATS (line 105) | const EXPORT_FORMATS = [
  constant FRAME_RATE_PRESETS (line 112) | const FRAME_RATE_PRESETS = [
  constant MAX_LIMITS (line 119) | const MAX_LIMITS = {
  constant DEFAULT_FRAME_DURATION (line 127) | const DEFAULT_FRAME_DURATION = 100;
  constant MIN_FRAME_DURATION (line 128) | const MIN_FRAME_DURATION = 17;
  constant MAX_FRAME_DURATION (line 129) | const MAX_FRAME_DURATION = 10000;

FILE: src/constants/onionSkin.ts
  constant ONION_SKIN_COLORS (line 7) | const ONION_SKIN_COLORS = {
  constant ONION_SKIN_OPACITY (line 24) | const ONION_SKIN_OPACITY = {

FILE: src/constants/postEffectDefaults.ts
  type ChromaticAberrationSettings (line 9) | interface ChromaticAberrationSettings {
  constant DEFAULT_CHROMATIC_ABERRATION_SETTINGS (line 18) | const DEFAULT_CHROMATIC_ABERRATION_SETTINGS: ChromaticAberrationSettings...
  type ScreenDistortionSettings (line 28) | interface ScreenDistortionSettings {
  constant DEFAULT_SCREEN_DISTORTION_SETTINGS (line 37) | const DEFAULT_SCREEN_DISTORTION_SETTINGS: ScreenDistortionSettings = {
  type GlowSettings (line 47) | interface GlowSettings {
  constant DEFAULT_GLOW_SETTINGS (line 66) | const DEFAULT_GLOW_SETTINGS: GlowSettings = {
  type BlurSettings (line 81) | interface BlurSettings {
  constant DEFAULT_BLUR_SETTINGS (line 91) | const DEFAULT_BLUR_SETTINGS: BlurSettings = {
  type PixelateSettings (line 102) | interface PixelateSettings {
  constant DEFAULT_PIXELATE_SETTINGS (line 107) | const DEFAULT_PIXELATE_SETTINGS: PixelateSettings = {
  type PostEffectDefinition (line 115) | interface PostEffectDefinition {
  constant POST_EFFECT_DEFINITIONS (line 123) | const POST_EFFECT_DEFINITIONS: PostEffectDefinition[] = [
  constant POST_EFFECT_LIMITS (line 165) | const POST_EFFECT_LIMITS = {

FILE: src/constants/shapeVectors.ts
  constant INTERNAL_CIRCLES (line 24) | const INTERNAL_CIRCLES: Array<[number, number, number]> = [
  constant EXTERNAL_CIRCLES (line 40) | const EXTERNAL_CIRCLES: Array<[number, number, number]> = [
  constant AFFECTING_EXTERNAL_INDICES (line 57) | const AFFECTING_EXTERNAL_INDICES: number[][] = [
  type CharacterShapeEntry (line 68) | interface CharacterShapeEntry {
  constant BASIC_ASCII_SHAPE_VECTORS (line 84) | const BASIC_ASCII_SHAPE_VECTORS: CharacterShapeEntry[] = [
  constant BLOCK_CHAR_SHAPE_VECTORS (line 197) | const BLOCK_CHAR_SHAPE_VECTORS: CharacterShapeEntry[] = [
  function normalizeShapeVectors (line 226) | function normalizeShapeVectors(
  constant PRINTABLE_ASCII (line 255) | const PRINTABLE_ASCII = Array.from({ length: 95 }, (_, i) => String.from...
  constant BLOCK_CHARACTERS (line 258) | const BLOCK_CHARACTERS = [
  function getNormalizedAsciiVectors (line 268) | function getNormalizedAsciiVectors(): CharacterShapeEntry[] {
  function getNormalizedBlockVectors (line 281) | function getNormalizedBlockVectors(): CharacterShapeEntry[] {
  function tryGenerateFromCanvas (line 293) | function tryGenerateFromCanvas(characters: string[]): CharacterShapeEntr...
  function generateShapeVectors (line 314) | function generateShapeVectors(

FILE: src/constants/version.ts
  constant VERSION (line 4) | const VERSION = "2.1.3";
  constant BUILD_DATE (line 5) | const BUILD_DATE = "2026-04-14T19:04:28.035Z";
  constant BUILD_HASH (line 6) | const BUILD_HASH = "b76e9d4";
  constant VERSION_HISTORY (line 9) | const VERSION_HISTORY = [

FILE: src/contexts/CanvasContext/context.ts
  type SelectionPreviewState (line 7) | interface SelectionPreviewState {
  type CanvasState (line 15) | interface CanvasState {
  type CanvasActions (line 62) | interface CanvasActions {
  type CanvasContextValue (line 112) | type CanvasContextValue = CanvasState & CanvasActions;
  type CanvasProviderProps (line 114) | interface CanvasProviderProps {

FILE: src/contexts/ModalContext/context.ts
  type ModalContextType (line 4) | interface ModalContextType {
  type ModalProviderProps (line 10) | interface ModalProviderProps {

FILE: src/contexts/ThemeContext/context.ts
  type Theme (line 4) | type Theme = 'dark' | 'light';
  type ThemeContextType (line 6) | interface ThemeContextType {
  type ThemeProviderProps (line 12) | interface ThemeProviderProps {

FILE: src/hooks/useAdminProjectLoader.ts
  function useAdminProjectLoader (line 5) | function useAdminProjectLoader() {

FILE: src/hooks/useAsciiTypePlacement.ts
  type PlacePreviewOptions (line 9) | interface PlacePreviewOptions {

FILE: src/hooks/useAsciiTypeTool.ts
  type PreviewCanvasCell (line 8) | interface PreviewCanvasCell {

FILE: src/hooks/useCanvasMouseHandlers.ts
  type MouseHandlers (line 19) | interface MouseHandlers {

FILE: src/hooks/useCanvasResize.ts
  function shiftCellMap (line 20) | function shiftCellMap(
  function useCanvasResize (line 39) | function useCanvasResize() {

FILE: src/hooks/useCloudDialogState.ts
  type CloudDialogState (line 12) | interface CloudDialogState {

FILE: src/hooks/useCloudProjectActions.ts
  function useCloudProjectActions (line 26) | function useCloudProjectActions() {

FILE: src/hooks/useCompositedCanvas.ts
  function useCompositedCanvas (line 39) | function useCompositedCanvas() {

FILE: src/hooks/useCropToSelection.ts
  function useCropToSelection (line 17) | function useCropToSelection() {

FILE: src/hooks/useEffectBlockHistory.ts
  type OwnerId (line 16) | type OwnerId = LayerId | LayerGroupId | null;
  function getOwnerType (line 18) | function getOwnerType(ownerId: OwnerId): 'layer' | 'group' | 'global' {
  function findTrackByBlockId (line 25) | function findTrackByBlockId(blockId: EffectBlockId): { track: EffectTrac...
  function useEffectBlockHistory (line 43) | function useEffectBlockHistory() {

FILE: src/hooks/useGeneratorPreview.ts
  function useGeneratorPreview (line 15) | function useGeneratorPreview() {

FILE: src/hooks/useKeyboardShortcuts.ts
  type CanvasStoreState (line 30) | type CanvasStoreState = ReturnType<typeof useCanvasStore.getState>;
  type CanvasStoreForHistory (line 31) | type CanvasStoreForHistory = Pick<CanvasStoreState, 'setCanvasData'>;
  type AnimationStoreState (line 32) | type AnimationStoreState = ReturnType<typeof useAnimationStore.getState>;

FILE: src/hooks/useKeyframeableProperty.ts
  function useKeyframeableProperty (line 52) | function useKeyframeableProperty(

FILE: src/hooks/useLayerLimit.ts
  type LayerLimitInfo (line 18) | interface LayerLimitInfo {
  function useLayerLimit (line 46) | function useLayerLimit(): LayerLimitInfo {

FILE: src/hooks/useLayerTransformTool.ts
  type TransformDragMode (line 38) | type TransformDragMode = 'none' | 'move' | 'scale' | 'rotate' | 'anchor';
  type TransformDragState (line 40) | interface TransformDragState {
  type TransformBoundingBox (line 56) | interface TransformBoundingBox {
  constant ANCHOR_HIT_RADIUS (line 69) | const ANCHOR_HIT_RADIUS = 1.5;
  constant HANDLE_HIT_RADIUS (line 70) | const HANDLE_HIT_RADIUS = 2.0;
  constant SCALE_MIN (line 71) | const SCALE_MIN = PROPERTY_DEFINITIONS['transform.scale.x']?.min ?? 0.1;
  constant SCALE_MAX (line 72) | const SCALE_MAX = PROPERTY_DEFINITIONS['transform.scale.x']?.max ?? 10;
  function forwardTransformPoint (line 79) | function forwardTransformPoint(
  function isPointInQuad (line 104) | function isPointInQuad(
  function dist (line 127) | function dist(a: { x: number; y: number }, b: { x: number; y: number }):...
  function angleDeg (line 132) | function angleDeg(a: { x: number; y: number }, b: { x: number; y: number...
  constant EMPTY_LAYERS (line 140) | const EMPTY_LAYERS: Layer[] = [];
  function useLayerTransformTool (line 142) | function useLayerTransformTool() {
  type LayerTransformMouseHandlers (line 684) | interface LayerTransformMouseHandlers {
  constant NOOP_HANDLERS (line 690) | const NOOP_HANDLERS: LayerTransformMouseHandlers = {

FILE: src/hooks/useLayoutState.ts
  type LayoutState (line 3) | interface LayoutState {
  type UserPreferences (line 10) | interface UserPreferences {
  type FullscreenState (line 16) | interface FullscreenState {
  constant DEFAULT_LAYOUT (line 22) | const DEFAULT_LAYOUT: LayoutState = {
  constant DEFAULT_PREFERENCES (line 29) | const DEFAULT_PREFERENCES: UserPreferences = {
  constant MOBILE_BREAKPOINT (line 36) | const MOBILE_BREAKPOINT = 768;
  constant TABLET_BREAKPOINT (line 37) | const TABLET_BREAKPOINT = 1024;
  constant COMPACT_BREAKPOINT (line 38) | const COMPACT_BREAKPOINT = 1200;

FILE: src/hooks/useMemoizedGrid.ts
  type GridCell (line 6) | interface GridCell {
  type MemoizedGridData (line 15) | interface MemoizedGridData {
  type MoveState (line 22) | interface MoveState {

FILE: src/hooks/usePasteMode.ts
  type PastePreview (line 7) | interface PastePreview {
  type PasteModeState (line 18) | interface PasteModeState {

FILE: src/hooks/usePlaybackOnlySnapshot.ts
  type PlaybackSnapshot (line 4) | interface PlaybackSnapshot {

FILE: src/hooks/usePostEffectBlockHistory.ts
  function findPostEffectTrackByBlockId (line 13) | function findPostEffectTrackByBlockId(
  function usePostEffectBlockHistory (line 24) | function usePostEffectBlockHistory() {

FILE: src/hooks/usePostEffectsRenderer.ts
  function hexToRgb (line 29) | function hexToRgb(hex: string): [number, number, number] {
  function getOverlayCanvas (line 45) | function getOverlayCanvas(): HTMLCanvasElement | null {
  function usePostEffectsRenderer (line 53) | function usePostEffectsRenderer(): {
  function applyPlaybackPostEffects (line 220) | function applyPlaybackPostEffects(
  function disposePlaybackPostEffects (line 264) | function disposePlaybackPostEffects(): void {
  function applyPostEffectsToCanvas (line 286) | function applyPostEffectsToCanvas(

FILE: src/hooks/useProjectDialogState.ts
  type ProjectDialogState (line 12) | interface ProjectDialogState {

FILE: src/hooks/useScrubInput.ts
  type UseScrubInputOptions (line 16) | interface UseScrubInputOptions {
  type UseScrubInputResult (line 31) | interface UseScrubInputResult {
  function useScrubInput (line 36) | function useScrubInput({

FILE: src/hooks/useSelectionSync.ts
  function useSelectionSync (line 20) | function useSelectionSync() {
  function clearAllSelections (line 81) | function clearAllSelections() {
  function getActiveSelectionType (line 98) | function getActiveSelectionType(): 'rect' | 'lasso' | 'magicwand' | null {
  function hasAnySelection (line 117) | function hasAnySelection(): boolean {
  function clearOtherToolSelections (line 131) | function clearOtherToolSelections(keepTool: 'select' | 'lasso' | 'magicw...
  function commitMoveAndUpdateSelection (line 153) | function commitMoveAndUpdateSelection() {

FILE: src/hooks/useTimelineHistory.ts
  function useTimelineHistory (line 47) | function useTimelineHistory() {

FILE: src/hooks/useWelcomeDialog.ts
  constant STORAGE_KEY (line 16) | const STORAGE_KEY = 'ascii-motion-welcome-state';

FILE: src/lib/figletClient.ts
  constant FIGLET_FONT_MODULES (line 3) | const FIGLET_FONT_MODULES = import.meta.glob<{ default: string }>(
  function getFontModuleLoader (line 12) | function getFontModuleLoader(fontName: string) {
  function ensureFontLoaded (line 22) | async function ensureFontLoaded(fontName: string): Promise<void> {
  type AsciiTypeLayoutPreset (line 48) | type AsciiTypeLayoutPreset = 'normal' | 'narrow' | 'squeezed' | 'fitted'...
  constant LAYOUT_PRESET_TO_FIGLET (line 50) | const LAYOUT_PRESET_TO_FIGLET: Record<AsciiTypeLayoutPreset, figlet.Kern...
  constant ASCII_TYPE_LAYOUT_OPTIONS (line 58) | const ASCII_TYPE_LAYOUT_OPTIONS: AsciiTypeLayoutPreset[] = [
  type FigletRenderOptions (line 66) | interface FigletRenderOptions {
  type FigletRenderResult (line 72) | interface FigletRenderResult {
  function renderFigletText (line 76) | async function renderFigletText(
  function getFigletKerning (line 93) | function getFigletKerning(layout: AsciiTypeLayoutPreset): figlet.Kerning...

FILE: src/lib/premium-stub.ts
  type CloudProject (line 18) | interface CloudProject {
  type SessionData (line 29) | interface SessionData {
  type SessionFrame (line 65) | interface SessionFrame {
  type Cell (line 72) | interface Cell {
  type SessionToolState (line 78) | interface SessionToolState {
  type SessionUIState (line 87) | interface SessionUIState {
  type TypographySettings (line 100) | interface TypographySettings {
  type PaletteColor (line 107) | interface PaletteColor {
  type PaletteState (line 113) | interface PaletteState {
  type CharacterPaletteState (line 125) | interface CharacterPaletteState {
  type ProjectListItem (line 137) | interface ProjectListItem {
  type SaveProjectOptions (line 149) | interface SaveProjectOptions {
  type ConflictStrategy (line 155) | type ConflictStrategy = 'use-cloud' | 'use-local' | 'create-copy' | 'can...
  type ConflictDetection (line 157) | interface ConflictDetection {
  type SubscriptionTier (line 164) | interface SubscriptionTier {
  type UserProfile (line 173) | interface UserProfile {
  type ValidationResult (line 185) | interface ValidationResult {
  type Profile (line 190) | type Profile = {
  type Database (line 205) | type Database = Record<string, unknown>;
  function useAuth (line 237) | function useAuth() {
  function usePasswordRecoveryCallback (line 257) | function usePasswordRecoveryCallback() {
  function useEmailVerificationCallback (line 261) | function useEmailVerificationCallback() {
  function useCloudProject (line 269) | function useCloudProject() {
  function useAdminCheckContext (line 296) | function useAdminCheckContext() {
  function validateProjectName (line 304) | function validateProjectName(name: string): ValidationResult {
  function validateProjectDescription (line 314) | function validateProjectDescription(description: string): ValidationResu...
  function sanitizeString (line 321) | function sanitizeString(input: string): string {
  function generatePreview (line 332) | async function generatePreview(_frames: any[], _options?: any): Promise<...
  function generateThumbnail (line 337) | async function generateThumbnail(..._args: any[]): Promise<any> {
  function generatePreviewAndThumbnail (line 342) | async function generatePreviewAndThumbnail(..._args: any[]): Promise<any> {
  function estimatePreviewSize (line 346) | function estimatePreviewSize() {
  function uploadPreviewImage (line 351) | async function uploadPreviewImage(_projectId: string, _blob: any): Promi...
  function getFontStack (line 355) | function getFontStack(_fontId?: string): string {
  function deserializeProject (line 363) | function deserializeProject() { return null; }
  function deserializeProjectListItem (line 364) | function deserializeProjectListItem() { return null; }
  function serializeProject (line 365) | function serializeProject() { return null; }
  function validateSessionData (line 366) | function validateSessionData() { return true; }
  function extractProjectNameFromFilename (line 367) | function extractProjectNameFromFilename(filename: string) {
  function useStripeCheckout (line 375) | function useStripeCheckout() {
  function useStripePortal (line 379) | function useStripePortal() {
  function getStripe (line 383) | function getStripe() { return null; }
  function getStripePriceId (line 384) | function getStripePriceId() { return ''; }
  function childrenPassthrough (line 393) | function childrenPassthrough({ children }: { children?: ReactNode }) {
  type AnyProps (line 401) | type AnyProps = Record<string, any>;
  function nullComponent (line 402) | function nullComponent(_props?: AnyProps) { return null; }

FILE: src/lib/utils.ts
  function cn (line 4) | function cn(...inputs: ClassValue[]) {

FILE: src/mcp/client.ts
  constant DEFAULT_PORT (line 19) | const DEFAULT_PORT = 9876;
  constant HEARTBEAT_INTERVAL (line 20) | const HEARTBEAT_INTERVAL = 30000;
  constant RECONNECT_DELAY (line 21) | const RECONNECT_DELAY = 3000;
  class MCPClient (line 23) | class MCPClient {
    method constructor (line 34) | constructor() {
    method connect (line 41) | connect(token: string, port: number = DEFAULT_PORT): Promise<void> {
    method disconnect (line 104) | disconnect(): void {
    method isConnected (line 119) | isConnected(): boolean {
    method sendStateSnapshot (line 126) | sendStateSnapshot(): void {
    method flushCanvasToActiveContentFrame (line 306) | private flushCanvasToActiveContentFrame(): void {
    method generateSessionId (line 321) | private generateSessionId(): string {
    method sendAuth (line 345) | private sendAuth(): void {
    method startHeartbeat (line 357) | private startHeartbeat(): void {
    method scheduleReconnect (line 366) | private scheduleReconnect(): void {
    method cleanup (line 384) | private cleanup(): void {
    method send (line 398) | private send(message: unknown): void {
    method handleMessage (line 404) | private handleMessage(data: string): void {
    method handleNotification (line 450) | private handleNotification(method: string, params: unknown): void {
    method handleStateChange (line 465) | private handleStateChange(type: string, data: unknown): void {
    method executeCommand (line 872) | private executeCommand(command: MCPCommand): void {
    method handleSetCell (line 986) | private handleSetCell(cmd: { x: number; y: number; cell: Cell }): void {
    method handleSetCellsBatch (line 990) | private handleSetCellsBatch(cmd: { cells: Array<{ x: number; y: number...
    method handleClearCell (line 997) | private handleClearCell(cmd: { x: number; y: number }): void {
    method handleResizeCanvas (line 1001) | private handleResizeCanvas(cmd: { width: number; height: number }): vo...
    method handleSetCanvasData (line 1005) | private handleSetCanvasData(cmd: { cells: Array<{ key: string; cell: C...
    method handleAddFrame (line 1013) | private handleAddFrame(cmd: { atIndex?: number; cells?: Array<{ key: s...
    method handleDeleteFrame (line 1024) | private handleDeleteFrame(cmd: { index: number }): void {
    method handleGoToFrame (line 1028) | private handleGoToFrame(cmd: { index: number }): void {
    method handleSetFrameDuration (line 1032) | private handleSetFrameDuration(cmd: { index: number; duration: number ...
    method handleSetFrameData (line 1036) | private handleSetFrameData(cmd: { index: number; cells: Array<{ key: s...
    method handleUndo (line 1044) | private handleUndo(): void {
    method handleRedo (line 1048) | private handleRedo(): void {
    method handleNewProject (line 1052) | private handleNewProject(cmd: { width: number; height: number; backgro...
    method handleLoadProject (line 1076) | private handleLoadProject(_cmd: { sessionData: unknown }): void {
    method handleSetForegroundColor (line 1083) | private handleSetForegroundColor(cmd: { color: string }): void {
    method handleSetBackgroundColor (line 1087) | private handleSetBackgroundColor(cmd: { color: string }): void {
    method handleSelectRectangle (line 1091) | private handleSelectRectangle(cmd: { x: number; y: number; width: numb...
    method handleClearSelection (line 1102) | private handleClearSelection(): void {
    method handleAddPostEffect (line 1110) | private handleAddPostEffect(cmd: { postEffectType: string; startFrame?...
    method handleRemovePostEffect (line 1125) | private handleRemovePostEffect(cmd: { blockId: string }): void {
    method handleUpdatePostEffect (line 1134) | private handleUpdatePostEffect(cmd: { blockId: string; settings?: Reco...
    method handleSetPostEffectKeyframe (line 1155) | private handleSetPostEffectKeyframe(cmd: { blockId: string; propertyPa...
    method handleRemovePostEffectKeyframe (line 1175) | private handleRemovePostEffectKeyframe(cmd: { blockId: string; propert...
    method handleListPostEffects (line 1189) | private handleListPostEffects(): void {
    method handleGetPostEffectPresets (line 1204) | private handleGetPostEffectPresets(): void {
    method handleExportRequest (line 1237) | private async handleExportRequest(request: MCPExportRequest): Promise<...
    method captureExportBlob (line 1341) | private async captureExportBlob(exportFn: () => Promise<void>): Promis...
    method blobToBase64 (line 1372) | private blobToBase64(blob: Blob): Promise<string> {
  function createMCPClient (line 1393) | function createMCPClient(): MCPClient {

FILE: src/mcp/store.ts
  type MCPConnectionState (line 9) | type MCPConnectionState = 'disconnected' | 'connecting' | 'connected' | ...
  type MCPStoreState (line 11) | interface MCPStoreState {

FILE: src/mcp/types.ts
  type MCPCommand (line 12) | type MCPCommand =
  type MCPSetCellCommand (line 32) | interface MCPSetCellCommand {
  type MCPSetCellsBatchCommand (line 39) | interface MCPSetCellsBatchCommand {
  type MCPClearCellCommand (line 44) | interface MCPClearCellCommand {
  type MCPResizeCanvasCommand (line 50) | interface MCPResizeCanvasCommand {
  type MCPSetCanvasDataCommand (line 56) | interface MCPSetCanvasDataCommand {
  type MCPAddFrameCommand (line 61) | interface MCPAddFrameCommand {
  type MCPDeleteFrameCommand (line 68) | interface MCPDeleteFrameCommand {
  type MCPGoToFrameCommand (line 73) | interface MCPGoToFrameCommand {
  type MCPSetFrameDurationCommand (line 78) | interface MCPSetFrameDurationCommand {
  type MCPSetFrameDataCommand (line 84) | interface MCPSetFrameDataCommand {
  type MCPUndoCommand (line 90) | interface MCPUndoCommand {
  type MCPRedoCommand (line 94) | interface MCPRedoCommand {
  type MCPNewProjectCommand (line 98) | interface MCPNewProjectCommand {
  type MCPLoadProjectCommand (line 106) | interface MCPLoadProjectCommand {
  type MCPSetForegroundColorCommand (line 111) | interface MCPSetForegroundColorCommand {
  type MCPSetBackgroundColorCommand (line 116) | interface MCPSetBackgroundColorCommand {
  type MCPSelectRectangleCommand (line 121) | interface MCPSelectRectangleCommand {
  type MCPClearSelectionCommand (line 129) | interface MCPClearSelectionCommand {
  type MCPStateUpdate (line 136) | interface MCPStateUpdate {
  type StateChange (line 142) | interface StateChange {
  type MCPMessage (line 151) | interface MCPMessage {
  type MCPClientMessage (line 160) | type MCPClientMessage =
  type MCPClientAuth (line 165) | interface MCPClientAuth {
  type MCPClientHeartbeat (line 171) | interface MCPClientHeartbeat {
  type MCPClientStateSnapshot (line 175) | interface MCPClientStateSnapshot {
  type MCPExportRequest (line 205) | interface MCPExportRequest {
  type MCPExportResult (line 217) | interface MCPExportResult {
  type MCPServerMessage (line 231) | interface MCPServerMessage {

FILE: src/mcp/useMCPConnection.ts
  type UseMCPConnectionReturn (line 11) | interface UseMCPConnectionReturn {
  function useMCPConnection (line 55) | function useMCPConnection(): UseMCPConnectionReturn {

FILE: src/pages/CommunityPage.tsx
  function CommunityPage (line 9) | function CommunityPage() {
  function UserProfilePageWrapper (line 39) | function UserProfilePageWrapper({ onClose }: { onClose: () => void }) {

FILE: src/pages/EditorPage.tsx
  function EditorPage (line 43) | function EditorPage() {

FILE: src/registry/effectRegistry.ts
  type EffectProcessOptions (line 23) | interface EffectProcessOptions {
  type EffectProcessResult (line 46) | interface EffectProcessResult {
  type EffectRegistryEntry (line 57) | interface EffectRegistryEntry {
  function registerEffect (line 119) | function registerEffect(entry: EffectRegistryEntry): void {
  function getEffect (line 130) | function getEffect(type: string): EffectRegistryEntry | undefined {
  function getAllEffects (line 137) | function getAllEffects(): EffectRegistryEntry[] {
  function getEffectsByCategory (line 144) | function getEffectsByCategory(category: EffectRegistryEntry['category'])...
  function isEffectRegistered (line 151) | function isEffectRegistered(type: string): boolean {
  function clearEffectRegistry (line 158) | function clearEffectRegistry(): void {

FILE: src/registry/effects/index.ts
  function registerAllEffects (line 21) | function registerAllEffects(): void {

FILE: src/registry/effects/motionTrails.ts
  constant DEFAULT_TRAIL_COLORS (line 15) | const DEFAULT_TRAIL_COLORS = [
  function trailCountValuesForIndex (line 29) | function trailCountValuesForIndex(minCount: number): string[] {

FILE: src/registry/effects/waveWarp.ts
  function deriveCanvasBounds (line 123) | function deriveCanvasBounds(cells: Map<string, Cell>): { width: number; ...

FILE: src/registry/effects/wiggle.ts
  function deriveCanvasBounds (line 180) | function deriveCanvasBounds(cells: Map<string, Cell>): { width: number; ...

FILE: src/registry/postEffectRegistry.ts
  type PostEffectRegistryEntry (line 21) | interface PostEffectRegistryEntry {
  function registerPostEffect (line 95) | function registerPostEffect(entry: PostEffectRegistryEntry): void {
  function getPostEffect (line 106) | function getPostEffect(type: string): PostEffectRegistryEntry | undefined {
  function getAllPostEffects (line 113) | function getAllPostEffects(): PostEffectRegistryEntry[] {
  function getPostEffectsByCategory (line 120) | function getPostEffectsByCategory(
  function isPostEffectRegistered (line 129) | function isPostEffectRegistered(type: string): boolean {
  function clearPostEffectRegistry (line 136) | function clearPostEffectRegistry(): void {

FILE: src/registry/postEffects/index.ts
  function registerAllPostEffects (line 18) | function registerAllPostEffects(): void {

FILE: src/stores/animationStore.ts
  function getActiveLayer (line 28) | function getActiveLayer() {
  function contentFrameToLegacyFrame (line 38) | function contentFrameToLegacyFrame(cf: ContentFrame): Frame {
  function deriveLegacyFrames (line 49) | function deriveLegacyFrames(): Frame[] {
  function _getContentFrameByIndex (line 56) | function _getContentFrameByIndex(index: number): ContentFrame | undefined {
  type LegacyAnimationState (line 68) | interface LegacyAnimationState {

FILE: src/stores/animationStoreAdapter.ts
  function getActiveLayer (line 27) | function getActiveLayer() {
  function contentFrameToLegacyFrame (line 37) | function contentFrameToLegacyFrame(cf: ContentFrame): Frame {
  function deriveLegacyFrames (line 48) | function deriveLegacyFrames(): Frame[] {
  type LegacyAnimationState (line 59) | interface LegacyAnimationState {

FILE: src/stores/asciiBoxStore.ts
  type BoxDrawingMode (line 4) | type BoxDrawingMode = 'rectangle' | 'freedraw' | 'erase';
  type AsciiBoxStore (line 6) | interface AsciiBoxStore {

FILE: src/stores/asciiTypeStore.ts
  type AsciiPreviewCell (line 5) | interface AsciiPreviewCell {
  type AsciiPreviewGrid (line 10) | type AsciiPreviewGrid = AsciiPreviewCell[][];
  type AsciiDimensions (line 12) | interface AsciiDimensions {
  type PreviewDragState (line 17) | interface PreviewDragState {
  type RenderRequestMeta (line 22) | interface RenderRequestMeta {
  type AsciiTypeStoreState (line 27) | interface AsciiTypeStoreState {
  constant DEFAULT_FONT (line 80) | const DEFAULT_FONT = 'ANSI Shadow';
  constant DEFAULT_STATE (line 131) | const DEFAULT_STATE: Omit<AsciiTypeStoreState,

FILE: src/stores/bezierStore.ts
  type VectorShapeType (line 18) | type VectorShapeType = 'freeform' | 'rectangle' | 'ellipse';
  type BezierSessionSettings (line 24) | interface BezierSessionSettings {
  type BezierAnchorPoint (line 39) | interface BezierAnchorPoint {
  type BezierStore (line 65) | interface BezierStore {
  type BezierStoreState (line 487) | interface BezierStoreState {
  function generateAnchorId (line 552) | function generateAnchorId(): string {
  function createSessionSettings (line 559) | function createSessionSettings(state: BezierStoreState): BezierSessionSe...

FILE: src/stores/canvasStore.ts
  type CanvasState (line 9) | interface CanvasState extends Canvas {

FILE: src/stores/characterPaletteStore.ts
  type CharacterPaletteState (line 16) | interface CharacterPaletteState {

FILE: src/stores/exportStore.ts
  type ExportActions (line 20) | interface ExportActions {
  type ExportStoreState (line 50) | interface ExportStoreState extends ExportState, ExportActions {}
  constant DEFAULT_SVG_SETTINGS (line 53) | const DEFAULT_SVG_SETTINGS: SvgExportSettings = {
  constant DEFAULT_IMAGE_SETTINGS (line 62) | const DEFAULT_IMAGE_SETTINGS: ImageExportSettings = {
  constant DEFAULT_VIDEO_SETTINGS (line 70) | const DEFAULT_VIDEO_SETTINGS: VideoExportSettings = {
  constant DEFAULT_SESSION_SETTINGS (line 81) | const DEFAULT_SESSION_SETTINGS: SessionExportSettings = {
  constant DEFAULT_TEXT_SETTINGS (line 85) | const DEFAULT_TEXT_SETTINGS: TextExportSettings = {
  constant DEFAULT_JSON_SETTINGS (line 93) | const DEFAULT_JSON_SETTINGS: JsonExportSettings = {
  constant DEFAULT_HTML_SETTINGS (line 99) | const DEFAULT_HTML_SETTINGS: HtmlExportSettings = {
  constant DEFAULT_REACT_SETTINGS (line 108) | const DEFAULT_REACT_SETTINGS: ReactExportSettings = {
  constant DEFAULT_INK_SETTINGS (line 115) | const DEFAULT_INK_SETTINGS: InkExportSettings = {
  constant DEFAULT_OPENTUI_SETTINGS (line 122) | const DEFAULT_OPENTUI_SETTINGS: OpenTuiExportSettings = {
  constant DEFAULT_BUBBLETEA_SETTINGS (line 129) | const DEFAULT_BUBBLETEA_SETTINGS: BubbleteaExportSettings = {

FILE: src/stores/generatorsStore.ts
  type GeneratorUIState (line 44) | interface GeneratorUIState {
  constant DEFAULT_MAPPING_SETTINGS (line 51) | const DEFAULT_MAPPING_SETTINGS: GeneratorMappingSettings = {
  type GeneratorsState (line 70) | interface GeneratorsState {
  constant DEFAULT_UI_STATE (line 131) | const DEFAULT_UI_STATE: GeneratorUIState = {

FILE: src/stores/gradientStore.ts
  type GradientSessionSettings (line 10) | interface GradientSessionSettings {
  type GradientUIState (line 19) | interface GradientUIState {
  type GradientStore (line 26) | interface GradientStore {

FILE: src/stores/importStore.ts
  type ImportUIState (line 15) | interface ImportUIState {
  type ImportState (line 23) | interface ImportState {
  type ImportSettings (line 63) | interface ImportSettings {
  constant DEFAULT_UI_STATE (line 137) | const DEFAULT_UI_STATE: ImportUIState = {
  constant DEFAULT_IMPORT_SETTINGS (line 145) | const DEFAULT_IMPORT_SETTINGS: ImportSettings = {

FILE: src/stores/paletteStore.ts
  type PaletteStore (line 15) | interface PaletteStore {

FILE: src/stores/playbackOnlyStore.ts
  type PlaybackOnlyStateInterface (line 7) | interface PlaybackOnlyStateInterface {
  type PlaybackSubscriber (line 16) | type PlaybackSubscriber = () => void;
  type PlaybackOnlyState (line 153) | type PlaybackOnlyState = PlaybackOnlyStateInterface;

FILE: src/stores/previewStore.ts
  type PreviewState (line 4) | interface PreviewState {

FILE: src/stores/projectMetadataStore.ts
  type ProjectMetadataState (line 3) | interface ProjectMetadataState {

FILE: src/stores/selectionStore.ts
  type SelectionBounds (line 22) | interface SelectionBounds {
  type MoveState (line 29) | interface MoveState {
  type SelectionState (line 42) | interface SelectionState {

FILE: src/stores/timelineStore.ts
  function findTrackKeyframeByFrame (line 60) | function findTrackKeyframeByFrame(
  function findPostEffectTrackOwner (line 102) | function findPostEffectTrackOwner(
  function updateEffectPropertyTrackKeyframes (line 118) | function updateEffectPropertyTrackKeyframes(
  function computeMergedContentFrames (line 213) | function computeMergedContentFrames(
  type TimelineState (line 274) | interface TimelineState {
  constant INITIAL_CONFIG (line 683) | const INITIAL_CONFIG: TimelineConfig = {
  constant INITIAL_VIEW (line 689) | const INITIAL_VIEW: TimelineViewState = {
  function updateLayer (line 725) | function updateLayer(
  constant DEFAULT_LAYER (line 738) | const DEFAULT_LAYER = createDefaultLayer();
  type Entry (line 1987) | type Entry = { layerId: string; trackId: string; propertyPath: string; f...

FILE: src/stores/toolStore.ts
  type ToolStoreState (line 22) | interface ToolStoreState extends ToolState {

FILE: src/types/easing.ts
  constant NEWTON_ITERATIONS (line 21) | const NEWTON_ITERATIONS = 8;
  constant NEWTON_EPSILON (line 26) | const NEWTON_EPSILON = 1e-7;
  constant SUBDIVISION_PRECISION (line 31) | const SUBDIVISION_PRECISION = 1e-7;
  constant SUBDIVISION_MAX_ITERATIONS (line 32) | const SUBDIVISION_MAX_ITERATIONS = 10;
  function cubicBezier (line 38) | function cubicBezier(t: number, p1: number, p2: number): number {
  function cubicBezierDerivative (line 50) | function cubicBezierDerivative(t: number, p1: number, p2: number): number {
  function solveCubicBezierX (line 59) | function solveCubicBezierX(x: number, x1: number, x2: number): number {
  constant LUT_SIZE (line 106) | const LUT_SIZE = 256;
  function buildLUT (line 117) | function buildLUT(x1: number, y1: number, x2: number, y2: number): Float...
  function lookupLUT (line 131) | function lookupLUT(lut: Float64Array, x: number): number {
  function getPresetLUT (line 148) | function getPresetLUT(preset: EasingPreset): Float64Array {
  function evaluateEasing (line 170) | function evaluateEasing(progress: number, easing: EasingCurve): number {
  function interpolateBetweenKeyframes (line 210) | function interpolateBetweenKeyframes(
  function interpolateKeyframes (line 240) | function interpolateKeyframes(
  function interpolateKeyframesNonLooping (line 268) | function interpolateKeyframesNonLooping(sorted: Keyframe[], frame: numbe...
  function defaultEasing (line 294) | function defaultEasing(): EasingCurve {
  function easingFromPreset (line 301) | function easingFromPreset(preset: EasingPreset): EasingCurve {
  function customEasing (line 308) | function customEasing(x1: number, y1: number, x2: number, y2: number): E...

FILE: src/types/effectBlock.ts
  type Brand (line 18) | type Brand<T, B> = T & { [__brand]: B };
  type EffectBlockId (line 20) | type EffectBlockId = Brand<string, 'EffectBlockId'>;
  type EffectTrackId (line 21) | type EffectTrackId = Brand<string, 'EffectTrackId'>;
  type EffectPropertyTrackId (line 22) | type EffectPropertyTrackId = Brand<string, 'EffectPropertyTrackId'>;
  function generateEffectBlockId (line 32) | function generateEffectBlockId(): EffectBlockId {
  function generateEffectTrackId (line 36) | function generateEffectTrackId(): EffectTrackId {
  function generateEffectPropertyTrackId (line 40) | function generateEffectPropertyTrackId(): EffectPropertyTrackId {
  function resetEffectIdCounters (line 47) | function resetEffectIdCounters(): void {
  type EffectKeyframe (line 61) | interface EffectKeyframe {
  type EffectPropertyTrack (line 76) | interface EffectPropertyTrack {
  type EffectBlock (line 91) | interface EffectBlock {
  type EffectTrack (line 118) | interface EffectTrack {
  type EffectInterpolationMode (line 145) | type EffectInterpolationMode = 'numeric' | 'hold';
  type EffectPropertyDefinition (line 151) | interface EffectPropertyDefinition {
  type SessionEffectKeyframeV2 (line 190) | interface SessionEffectKeyframeV2 {
  type SessionEffectPropertyTrackV2 (line 200) | interface SessionEffectPropertyTrackV2 {
  type SessionEffectBlockV2 (line 210) | interface SessionEffectBlockV2 {
  type SessionEffectTrackV2 (line 223) | interface SessionEffectTrackV2 {

FILE: src/types/effects.ts
  type EffectType (line 8) | type EffectType = 'levels' | 'hue-saturation' | 'remap-colors' | 'remap-...
  type ColorRange (line 11) | interface ColorRange {
  type LevelsEffectSettings (line 17) | interface LevelsEffectSettings {
  type HueSaturationEffectSettings (line 31) | interface HueSaturationEffectSettings {
  type RemapColorsEffectSettings (line 41) | interface RemapColorsEffectSettings {
  type RemapCharactersEffectSettings (line 55) | interface RemapCharactersEffectSettings {
  type ScatterEffectSettings (line 60) | interface ScatterEffectSettings {
  type EffectDefinition (line 75) | interface EffectDefinition {
  type ColorFrequency (line 84) | interface ColorFrequency {
  type CharacterFrequency (line 89) | interface CharacterFrequency {
  type ColorDistribution (line 94) | interface ColorDistribution {
  type CharacterDistribution (line 100) | interface CharacterDistribution {
  type ColorBrightnessStats (line 106) | interface ColorBrightnessStats {
  type CanvasAnalysis (line 114) | interface CanvasAnalysis {
  type EffectProcessingResult (line 150) | interface EffectProcessingResult {
  type EffectHistoryAction (line 159) | interface EffectHistoryAction {
  type MotionTrailsSettings (line 168) | interface MotionTrailsSettings {
  type EffectSettings (line 184) | type EffectSettings =
  type LastAppliedEffect (line 193) | interface LastAppliedEffect {

FILE: src/types/export.ts
  type ExportFormatId (line 7) | type ExportFormatId = 'png' | 'svg' | 'mp4' | 'session' | 'media' | 'tex...
  type ExportFormat (line 10) | interface ExportFormat {
  type SvgExportSettings (line 20) | interface SvgExportSettings {
  type ImageExportSettings (line 28) | interface ImageExportSettings {
  type ReactExportSettings (line 38) | interface ReactExportSettings {
  type InkExportSettings (line 46) | interface InkExportSettings {
  type OpenTuiExportSettings (line 53) | interface OpenTuiExportSettings {
  type BubbleteaExportSettings (line 60) | interface BubbleteaExportSettings {
  type VideoExportSettings (line 68) | interface VideoExportSettings {
  type SessionExportSettings (line 80) | interface SessionExportSettings {
  type TextExportSettings (line 85) | interface TextExportSettings {
  type JsonExportSettings (line 93) | interface JsonExportSettings {
  type HtmlExportSettings (line 99) | interface HtmlExportSettings {
  type PaletteExportState (line 109) | interface PaletteExportState {
  type CharacterPaletteExportState (line 115) | interface CharacterPaletteExportState {
  type ExportSettings (line 124) | type ExportSettings =
  type ExportDataBundle (line 136) | interface ExportDataBundle {
  type ExportResult (line 204) | interface ExportResult {
  type ExportProgress (line 212) | interface ExportProgress {
  type ExportHandler (line 219) | interface ExportHandler {
  type ExportHistoryEntry (line 228) | interface ExportHistoryEntry {
  type ExportState (line 237) | interface ExportState {
  type ImportResult (line 264) | interface ImportResult {
  type ImportValidator (line 270) | interface ImportValidator {
  type SessionExportData (line 275) | interface SessionExportData {

FILE: src/types/generators.ts
  type GeneratorId (line 8) | type GeneratorId = 'radio-waves' | 'turbulent-noise' | 'particle-physics...
  type NoiseType (line 11) | type NoiseType = 'perlin' | 'simplex' | 'worley';
  type DitherType (line 14) | type DitherType = 'none' | '2x2' | '4x4' | 'noise' | 'animated-noise';
  type WaveShape (line 17) | type WaveShape = 'circle' | 'square' | 'triangle' | 'pentagon' | 'hexago...
  type ProfileShape (line 20) | type ProfileShape = 'solid' | 'fade-out' | 'fade-in' | 'fade-in-out';
  type ScatterType (line 23) | type ScatterType = 'noise' | 'bayer-2x2' | 'bayer-4x4' | 'gaussian';
  type TimingMode (line 26) | type TimingMode = 'duration' | 'frameCount' | 'both';
  type RadioWavesSettings (line 30) | interface RadioWavesSettings {
  type TurbulentNoiseSettings (line 61) | interface TurbulentNoiseSettings {
  type ParticlePhysicsSettings (line 84) | interface ParticlePhysicsSettings {
  type RainDropsSettings (line 142) | interface RainDropsSettings {
  type DigitalRainSettings (line 174) | interface DigitalRainSettings {
  type GeneratorSettings (line 210) | type GeneratorSettings =
  type GeneratorMappingSettings (line 218) | interface GeneratorMappingSettings {
  type GeneratorDefinition (line 241) | interface GeneratorDefinition {
  type GeneratorFrame (line 249) | interface GeneratorFrame {

FILE: src/types/index.ts
  type FrameId (line 3) | type FrameId = string & { __brand: 'FrameId' };
  type ProjectId (line 4) | type ProjectId = string & { __brand: 'ProjectId' };
  type Cell (line 6) | interface Cell {
  type Frame (line 12) | interface Frame {
  type Animation (line 20) | interface Animation {
  type Canvas (line 29) | interface Canvas {
  type Project (line 35) | interface Project {
  type Tool (line 58) | type Tool =
  type BrushShape (line 79) | type BrushShape = 'circle' | 'square' | 'horizontal' | 'vertical';
  type BrushSettings (line 81) | interface BrushSettings {
  type ToolState (line 86) | interface ToolState {
  type SelectionShape (line 100) | type SelectionShape = 'rectangle' | 'custom';
  type Selection (line 102) | interface Selection {
  type LassoSelection (line 110) | interface LassoSelection {
  type MagicWandSelection (line 117) | interface MagicWandSelection {
  type TextToolState (line 124) | interface TextToolState {
  type CharacterPalette (line 132) | interface CharacterPalette {
  type ExportSettings (line 142) | interface ExportSettings {
  type InterpolationMethod (line 164) | type InterpolationMethod = 'linear' | 'constant' | 'bayer2x2' | 'bayer4x...
  type QuantizeStepCount (line 165) | type QuantizeStepCount =
  type GradientType (line 177) | type GradientType = 'linear' | 'radial';
  type GradientStop (line 179) | interface GradientStop {
  type GradientProperty (line 184) | interface GradientProperty {
  type GradientDefinition (line 192) | interface GradientDefinition {
  type GradientState (line 199) | interface GradientState {
  type HistoryActionType (line 249) | type HistoryActionType =
  type HistoryAction (line 315) | interface HistoryAction {
  type CanvasHistoryAction (line 321) | interface CanvasHistoryAction extends HistoryAction {
  type CanvasResizeHistoryAction (line 332) | interface CanvasResizeHistoryAction extends HistoryAction {
  type AddFrameHistoryAction (line 387) | interface AddFrameHistoryAction extends HistoryAction {
  type DuplicateFrameHistoryAction (line 397) | interface DuplicateFrameHistoryAction extends HistoryAction {
  type DuplicateFrameRangeHistoryAction (line 407) | interface DuplicateFrameRangeHistoryAction extends HistoryAction {
  type DeleteFrameHistoryAction (line 421) | interface DeleteFrameHistoryAction extends HistoryAction {
  type ReorderFramesHistoryAction (line 431) | interface ReorderFramesHistoryAction extends HistoryAction {
  type UpdateDurationHistoryAction (line 441) | interface UpdateDurationHistoryAction extends HistoryAction {
  type UpdateNameHistoryAction (line 450) | interface UpdateNameHistoryAction extends HistoryAction {
  type NavigateFrameHistoryAction (line 459) | interface NavigateFrameHistoryAction extends HistoryAction {
  type DeleteFrameRangeHistoryAction (line 467) | interface DeleteFrameRangeHistoryAction extends HistoryAction {
  type DeleteAllFramesHistoryAction (line 479) | interface DeleteAllFramesHistoryAction extends HistoryAction {
  type ReorderFrameRangeHistoryAction (line 487) | interface ReorderFrameRangeHistoryAction extends HistoryAction {
  type ApplyEffectHistoryAction (line 500) | interface ApplyEffectHistoryAction extends HistoryAction {
  type ApplyTimeEffectHistoryAction (line 518) | interface ApplyTimeEffectHistoryAction extends HistoryAction {
  type SetFrameDurationsHistoryAction (line 529) | interface SetFrameDurationsHistoryAction extends HistoryAction {
  type ImportMediaHistoryAction (line 538) | interface ImportMediaHistoryAction extends HistoryAction {
  type ApplyGeneratorHistoryAction (line 563) | interface ApplyGeneratorHistoryAction extends HistoryAction {
  type BezierAddPointHistoryAction (line 576) | interface BezierAddPointHistoryAction extends HistoryAction {
  type BezierMovePointHistoryAction (line 586) | interface BezierMovePointHistoryAction extends HistoryAction {
  type BezierAdjustHandleHistoryAction (line 596) | interface BezierAdjustHandleHistoryAction extends HistoryAction {
  type BezierToggleHandlesHistoryAction (line 612) | interface BezierToggleHandlesHistoryAction extends HistoryAction {
  type BezierDeletePointHistoryAction (line 626) | interface BezierDeletePointHistoryAction extends HistoryAction {
  type BezierCloseShapeHistoryAction (line 635) | interface BezierCloseShapeHistoryAction extends HistoryAction {
  type BezierCommitHistoryAction (line 644) | interface BezierCommitHistoryAction extends HistoryAction {
  type LayerAddHistoryAction (line 676) | interface LayerAddHistoryAction extends HistoryAction {
  type LayerRemoveHistoryAction (line 685) | interface LayerRemoveHistoryAction extends HistoryAction {
  type LayerReorderHistoryAction (line 694) | interface LayerReorderHistoryAction extends HistoryAction {
  type LayerRenameHistoryAction (line 707) | interface LayerRenameHistoryAction extends HistoryAction {
  type LayerVisibilityHistoryAction (line 716) | interface LayerVisibilityHistoryAction extends HistoryAction {
  type LayerOpacityHistoryAction (line 725) | interface LayerOpacityHistoryAction extends HistoryAction {
  type ContentFrameAddHistoryAction (line 734) | interface ContentFrameAddHistoryAction extends HistoryAction {
  type ContentFrameRemoveHistoryAction (line 743) | interface ContentFrameRemoveHistoryAction extends HistoryAction {
  type ContentFrameTimingHistoryAction (line 752) | interface ContentFrameTimingHistoryAction extends HistoryAction {
  type ContentFrameDataHistoryAction (line 764) | interface ContentFrameDataHistoryAction extends HistoryAction {
  type ContentFrameRenameHistoryAction (line 774) | interface ContentFrameRenameHistoryAction extends HistoryAction {
  type KeyframeAddHistoryAction (line 784) | interface KeyframeAddHistoryAction extends HistoryAction {
  type KeyframeRemoveHistoryAction (line 794) | interface KeyframeRemoveHistoryAction extends HistoryAction {
  type KeyframeUpdateHistoryAction (line 804) | interface KeyframeUpdateHistoryAction extends HistoryAction {
  type PropertyTrackAddHistoryAction (line 815) | interface PropertyTrackAddHistoryAction extends HistoryAction {
  type PropertyTrackRemoveHistoryAction (line 824) | interface PropertyTrackRemoveHistoryAction extends HistoryAction {
  type FrameRateChangeHistoryAction (line 833) | interface FrameRateChangeHistoryAction extends HistoryAction {
  type StaticPropertyChangeHistoryAction (line 845) | interface StaticPropertyChangeHistoryAction extends HistoryAction {
  type ContentFrameReorderHistoryAction (line 859) | interface ContentFrameReorderHistoryAction extends HistoryAction {
  type TimelineDurationChangeHistoryAction (line 883) | interface TimelineDurationChangeHistoryAction extends HistoryAction {
  type TrimToWorkAreaHistoryAction (line 895) | interface TrimToWorkAreaHistoryAction extends HistoryAction {
  type AnyHistoryAction (line 907) | type AnyHistoryAction =
  type ApplyTransformsHistoryAction (line 973) | interface ApplyTransformsHistoryAction extends HistoryAction {
  type MergeLayersHistoryAction (line 982) | interface MergeLayersHistoryAction extends HistoryAction {
  type CreateGroupHistoryAction (line 996) | interface CreateGroupHistoryAction extends HistoryAction {
  type UngroupLayersHistoryAction (line 1005) | interface UngroupLayersHistoryAction extends HistoryAction {
  type EffectBlockAddHistoryAction (line 1016) | interface EffectBlockAddHistoryAction extends HistoryAction {
  type EffectBlockRemoveHistoryAction (line 1025) | interface EffectBlockRemoveHistoryAction extends HistoryAction {
  type EffectBlockUpdateHistoryAction (line 1035) | interface EffectBlockUpdateHistoryAction extends HistoryAction {
  type EffectBlockReorderHistoryAction (line 1046) | interface EffectBlockReorderHistoryAction extends HistoryAction {
  type EffectKeyframeAddHistoryAction (line 1056) | interface EffectKeyframeAddHistoryAction extends HistoryAction {
  type EffectKeyframeRemoveHistoryAction (line 1067) | interface EffectKeyframeRemoveHistoryAction extends HistoryAction {
  type EffectKeyframeUpdateHistoryAction (line 1078) | interface EffectKeyframeUpdateHistoryAction extends HistoryAction {
  type EffectBakeHistoryAction (line 1091) | interface EffectBakeHistoryAction extends HistoryAction {
  type PostEffectBlockAddHistoryAction (line 1108) | interface PostEffectBlockAddHistoryAction extends HistoryAction {
  type PostEffectBlockRemoveHistoryAction (line 1115) | interface PostEffectBlockRemoveHistoryAction extends HistoryAction {
  type PostEffectBlockUpdateHistoryAction (line 1123) | interface PostEffectBlockUpdateHistoryAction extends HistoryAction {

FILE: src/types/mp4box.d.ts
  type MP4VideoTrack (line 2) | interface MP4VideoTrack {
  type MP4Info (line 9) | interface MP4Info {
  type MP4File (line 13) | interface MP4File {

FILE: src/types/palette.ts
  type PaletteColor (line 3) | interface PaletteColor {
  type ColorPalette (line 9) | interface ColorPalette {
  type ColorPickerState (line 17) | interface ColorPickerState {
  type DragState (line 25) | interface DragState {
  type PaletteExportFormat (line 33) | interface PaletteExportFormat {
  type HSVColor (line 39) | interface HSVColor {
  type RGBColor (line 46) | interface RGBColor {
  type ColorFormat (line 53) | type ColorFormat = 'hex' | 'rgb' | 'hsv';
  type CharacterPalette (line 101) | interface CharacterPalette {
  type CharacterMappingSettings (line 110) | interface CharacterMappingSettings {
  type CharacterPaletteEditorState (line 121) | interface CharacterPaletteEditorState {
  type CharacterPaletteExportFormat (line 129) | interface CharacterPaletteExportFormat {

FILE: src/types/postEffect.ts
  type Brand (line 19) | type Brand<T, B> = T & { [__brand]: B };
  type PostEffectBlockId (line 21) | type PostEffectBlockId = Brand<string, 'PostEffectBlockId'>;
  type PostEffectTrackId (line 22) | type PostEffectTrackId = Brand<string, 'PostEffectTrackId'>;
  type PostEffectPropertyTrackId (line 23) | type PostEffectPropertyTrackId = Brand<string, 'PostEffectPropertyTrackI...
  function generatePostEffectBlockId (line 33) | function generatePostEffectBlockId(): PostEffectBlockId {
  function generatePostEffectTrackId (line 37) | function generatePostEffectTrackId(): PostEffectTrackId {
  function generatePostEffectPropertyTrackId (line 41) | function generatePostEffectPropertyTrackId(): PostEffectPropertyTrackId {
  function resetPostEffectIdCounters (line 48) | function resetPostEffectIdCounters(): void {
  type PostEffectKeyframe (line 62) | interface PostEffectKeyframe {
  type PostEffectPropertyTrack (line 77) | interface PostEffectPropertyTrack {
  type PostEffectBlock (line 93) | interface PostEffectBlock {
  type PostEffectTrack (line 120) | interface PostEffectTrack {
  type PostEffectInterpolationMode (line 139) | type PostEffectInterpolationMode = 'numeric' | 'hold';
  type PostEffectPropertyDefinition (line 145) | interface PostEffectPropertyDefinition {
  type SessionPostEffectKeyframeV2 (line 184) | interface SessionPostEffectKeyframeV2 {
  type SessionPostEffectPropertyTrackV2 (line 194) | interface SessionPostEffectPropertyTrackV2 {
  type SessionPostEffectBlockV2 (line 204) | interface SessionPostEffectBlockV2 {
  type SessionPostEffectTrackV2 (line 217) | interface SessionPostEffectTrackV2 {

FILE: src/types/timeEffects.ts
  type TimeEffectType (line 11) | type TimeEffectType = 'wave-warp' | 'wiggle';
  type WaveAxis (line 14) | type WaveAxis = 'horizontal' | 'vertical';
  type WiggleMode (line 17) | type WiggleMode = 'horizontal-wave' | 'vertical-wave' | 'noise';
  type WaveWarpSettings (line 25) | interface WaveWarpSettings {
  type WiggleSettings (line 39) | interface WiggleSettings {
  type FrameRangeSettings (line 61) | interface FrameRangeSettings {
  type TimeEffectHistoryAction (line 73) | interface TimeEffectHistoryAction {
  type SetFrameDurationHistoryAction (line 94) | interface SetFrameDurationHistoryAction {
  type FrameDurationMode (line 113) | type FrameDurationMode = 'ms' | 'fps';

FILE: src/types/timeline.ts
  type Brand (line 17) | type Brand<T, B> = T & { [__brand]: B };
  type LayerId (line 19) | type LayerId = Brand<string, 'LayerId'>;
  type LayerGroupId (line 20) | type LayerGroupId = Brand<string, 'LayerGroupId'>;
  type ContentFrameId (line 21) | type ContentFrameId = Brand<string, 'ContentFrameId'>;
  type KeyframeId (line 22) | type KeyframeId = Brand<string, 'KeyframeId'>;
  type PropertyTrackId (line 23) | type PropertyTrackId = Brand<string, 'PropertyTrackId'>;
  function generateLayerId (line 35) | function generateLayerId(): LayerId {
  function generateLayerGroupId (line 39) | function generateLayerGroupId(): LayerGroupId {
  function generateContentFrameId (line 43) | function generateContentFrameId(): ContentFrameId {
  function generateKeyframeId (line 47) | function generateKeyframeId(): KeyframeId {
  function generatePropertyTrackId (line 51) | function generatePropertyTrackId(): PropertyTrackId {
  function resetIdCounters (line 58) | function resetIdCounters(): void {
  type Layer (line 74) | interface Layer {
  type LayerGroup (line 112) | interface LayerGroup {
  type ContentFrame (line 136) | interface ContentFrame {
  type PropertyTrack (line 161) | interface PropertyTrack {
  type PropertyPath (line 173) | type PropertyPath =
  constant PROPERTY_DISPLAY_ORDER (line 189) | const PROPERTY_DISPLAY_ORDER: PropertyPath[] = [
  type PropertyDefinition (line 202) | interface PropertyDefinition {
  constant PROPERTY_DEFINITIONS (line 217) | const PROPERTY_DEFINITIONS: Partial<Record<PropertyPath, PropertyDefinit...
  type Keyframe (line 296) | interface Keyframe {
  type EasingCurve (line 307) | interface EasingCurve {
  type EasingPreset (line 319) | type EasingPreset =
  constant EASING_PRESETS (line 332) | const EASING_PRESETS: Record<EasingPreset, [number, number, number, numb...
  type TimelineConfig (line 350) | interface TimelineConfig {
  type TimelineViewState (line 361) | interface TimelineViewState {
  type TimecodeFormat (line 432) | type TimecodeFormat =
  type EffectScope (line 445) | type EffectScope = 'layer' | 'global';
  type EffectInstance (line 450) | interface EffectInstance {
  type SessionDataV2 (line 469) | interface SessionDataV2 {
  type SessionLayerV2 (line 519) | interface SessionLayerV2 {
  type SessionContentFrameV2 (line 549) | interface SessionContentFrameV2 {
  type SessionPropertyTrackV2 (line 562) | interface SessionPropertyTrackV2 {
  type SessionKeyframeV2 (line 572) | interface SessionKeyframeV2 {
  type SessionLayerGroupV2 (line 582) | interface SessionLayerGroupV2 {
  type SessionEffectV2 (line 600) | interface SessionEffectV2 {
  function createDefaultLayer (line 617) | function createDefaultLayer(id?: LayerId, name?: string, canvasWidth = 8...
  function contentFramesOverlap (line 645) | function contentFramesOverlap(a: ContentFrame, b: ContentFrame): boolean {
  function validateContentFrames (line 655) | function validateContentFrames(frames: ContentFrame[]): boolean {

FILE: src/types/welcomeDialog.ts
  type WelcomeMediaType (line 8) | type WelcomeMediaType = 'image' | 'video' | 'youtube' | 'vimeo' | 'compo...
  type WelcomeMedia (line 10) | interface WelcomeMedia {
  type WelcomeCTA (line 19) | interface WelcomeCTA {
  type WelcomeSecondaryCTA (line 27) | interface WelcomeSecondaryCTA {
  type WelcomeTab (line 32) | interface WelcomeTab {
  type WelcomeState (line 41) | interface WelcomeState {

FILE: src/utils/asciiConverter.ts
  constant DEFAULT_ASCII_CHARS (line 18) | const DEFAULT_ASCII_CHARS = [
  type ConversionSettings (line 22) | interface ConversionSettings {
  type MappingAlgorithmOptions (line 86) | interface MappingAlgorithmOptions {
  type MappingAlgorithm (line 96) | interface MappingAlgorithm {
  constant MAPPING_ALGORITHMS (line 303) | const MAPPING_ALGORITHMS: Record<CharacterMappingSettings['mappingMethod...
  class ColorMatcher (line 317) | class ColorMatcher {
    method calculateColorDistance (line 321) | static calculateColorDistance(r1: number, g1: number, b1: number, r2: ...
    method findClosestColor (line 328) | static findClosestColor(r: number, g: number, b: number, palette: stri...
    method hexToRgb (line 348) | static hexToRgb(hex: string): { r: number; g: number; b: number } {
    method rgbToHex (line 360) | static rgbToHex(r: number, g: number, b: number): string {
    method matchesColorKey (line 374) | static matchesColorKey(r: number, g: number, b: number, keyColor: stri...
    method ditherColor (line 384) | static ditherColor(r: number, g: number, b: number, palette: string[],...
    method ditherColorNoise (line 398) | static ditherColorNoise(
    method ditherColorBayer2x2 (line 424) | static ditherColorBayer2x2(
    method ditherColorBayer4x4 (line 453) | static ditherColorBayer4x4(
    method mapColorByIndex (line 483) | static mapColorByIndex(r: number, g: number, b: number, palette: strin...
    method mapColorByIndexNoise (line 500) | static mapColorByIndexNoise(
    method mapColorByIndexBayer2x2 (line 541) | static mapColorByIndexBayer2x2(
    method mapColorByIndexBayer4x4 (line 585) | static mapColorByIndexBayer4x4(
  class CharacterMapper (line 631) | class CharacterMapper {
    method mapCharacterByIndex (line 636) | static mapCharacterByIndex(r: number, g: number, b: number, characters...
    method mapCharacterByIndexNoise (line 652) | static mapCharacterByIndexNoise(
    method mapCharacterByIndexBayer2x2 (line 687) | static mapCharacterByIndexBayer2x2(
    method mapCharacterByIndexBayer4x4 (line 726) | static mapCharacterByIndexBayer4x4(
  type ConversionResult (line 764) | interface ConversionResult {
  class ASCIIConverter (line 777) | class ASCIIConverter {
    method convertFrame (line 783) | convertFrame(frame: ProcessedFrame, settings: ConversionSettings): Con...
    method convertFrameAutoMode (line 1069) | private convertFrameAutoMode(
    method applyPreprocessing (line 1199) | private applyPreprocessing(imageData: ImageData, settings: ConversionS...
    method resolveShapeMappingMethod (line 1251) | private resolveShapeMappingMethod(
    method convertFrameLineArt (line 1274) | private convertFrameLineArt(
    method applyContrastToChannel (line 1376) | private applyContrastToChannel(channelValue: number, enhancement: numb...
    method applySaturationAdjustment (line 1386) | private applySaturationAdjustment(r: number, g: number, b: number, sat...
    method applyTonalAdjustments (line 1457) | private applyTonalAdjustments(
    method applyBlurFilter (line 1490) | private applyBlurFilter(imageData: ImageData, blurAmount: number): Ima...
    method applySharpenFilter (line 1568) | private applySharpenFilter(imageData: ImageData, sharpenAmount: number...
    method getNeighborValues (line 1619) | private getNeighborValues(data: Uint8ClampedArray, width: number, heig...
    method calculateSobelGradients (line 1650) | private calculateSobelGradients(data: Uint8ClampedArray, width: number...
    method selectCharacterWithAlgorithm (line 1692) | private selectCharacterWithAlgorithm(
    method rgbToHex (line 1736) | private rgbToHex(r: number, g: number, b: number): string {
    method extractColors (line 1743) | private extractColors(imageData: ImageData, paletteSize: number): stri...
    method quantizeColor (line 1786) | private quantizeColor(
    method colorDistance (line 1819) | private colorDistance(r: number, g: number, b: number, hexColor: strin...
    method clearCache (line 1834) | clearCache(): void {

FILE: src/utils/bezierAutofillUtils.ts
  function getSharedCanvas (line 25) | function getSharedCanvas(
  function detectCellRegions (line 76) | function detectCellRegions(
  function isPointInPath (line 132) | function isPointInPath(
  function calculateCellOverlap (line 165) | function calculateCellOverlap(
  function isCellInside (line 220) | function isCellInside(
  function cleanupSharedCanvas (line 238) | function cleanupSharedCanvas(): void {
  constant BRAILLE_DOTS (line 263) | const BRAILLE_DOTS: Array<{ col: number; row: number; bit: number }> = [
  function detectBrailleDots (line 280) | function detectBrailleDots(
  function brailleBitsToChar (line 311) | function brailleBitsToChar(bits: number): string {

FILE: src/utils/bezierFillUtils.ts
  function mapOverlapToColor (line 34) | function mapOverlapToColor(overlapPercentage: number, colorPalette: Colo...
  function fillConstant (line 67) | function fillConstant(
  function fillPalette (line 147) | function fillPalette(
  function fillAutofill (line 248) | function fillAutofill(
  function generateBezierPreview (line 357) | function generateBezierPreview(
  function fillLineArt (line 535) | function fillLineArt(

FILE: src/utils/bezierPathUtils.ts
  function pointToPixel (line 20) | function pointToPixel(
  function pixelToPoint (line 43) | function pixelToPoint(
  function createBezierPath (line 72) | function createBezierPath(
  function getBezierBounds (line 197) | function getBezierBounds(anchorPoints: BezierAnchorPoint[]): {
  function getIntegerBounds (line 254) | function getIntegerBounds(
  function isPointInBezierPath (line 282) | function isPointInBezierPath(

FILE: src/utils/bezierStrokeUtils.ts
  type Point (line 14) | interface Point {
  function cubicBezierPoint (line 28) | function cubicBezierPoint(
  function cubicBezierTangent (line 56) | function cubicBezierTangent(
  function normalize (line 76) | function normalize(v: Point): Point {
  function perpendicular (line 85) | function perpendicular(v: Point): Point {
  function calculateTaperedWidth (line 97) | function calculateTaperedWidth(
  function generateSegmentStroke (line 135) | function generateSegmentStroke(
  function computeMiterPoint (line 192) | function computeMiterPoint(
  function generateStrokeOutline (line 249) | function generateStrokeOutline(
  function createStrokePath (line 382) | function createStrokePath(
  function getStrokeBounds (line 427) | function getStrokeBounds(

FILE: src/utils/boxDrawingEngine.ts
  type ConnectionState (line 15) | interface ConnectionState {
  function getBoxDrawingCharacter (line 25) | function getBoxDrawingCharacter(
  function isBoxCharacter (line 71) | function isBoxCharacter(char: string): boolean {
  function detectConnections (line 83) | function detectConnections(
  function generateBoxRectangle (line 113) | function generateBoxRectangle(
  function addBoxCell (line 161) | function addBoxCell(
  function eraseBoxCell (line 200) | function eraseBoxCell(
  function getLineCells (line 232) | function getLineCells(

FILE: src/utils/canvasAnalysis.ts
  function analyzeCanvas (line 18) | function analyzeCanvas(canvas: Canvas): CanvasAnalysis {
  function analyzeFrame (line 137) | function analyzeFrame(frame: Frame, canvasWidth: number, canvasHeight: n...
  function analyzeFrames (line 151) | function analyzeFrames(frames: Frame[], canvasWidth: number, canvasHeigh...
  function calculateColorBrightnessStats (line 271) | function calculateColorBrightnessStats(colors: string[]) {
  function calculateColorBrightness (line 306) | function calculateColorBrightness(color: string): number {
  function hslToRgb (line 351) | function hslToRgb(h: number, s: number, l: number): { r: number; g: numb...
  function getEmptyAnalysis (line 383) | function getEmptyAnalysis(): CanvasAnalysis {
  function filterAnalysisByFrequency (line 427) | function filterAnalysisByFrequency(
  function compareAnalyses (line 444) | function compareAnalyses(oldAnalysis: CanvasAnalysis, newAnalysis: Canva...

FILE: src/utils/canvasDPI.ts
  type ExtendedCanvasRenderingContext2D (line 32) | type ExtendedCanvasRenderingContext2D = CanvasRenderingContext2D & {

FILE: src/utils/canvasResizeUtils.ts
  type AnchorPosition (line 7) | type AnchorPosition =
  type AnchorPositionData (line 21) | interface AnchorPositionData {
  constant ANCHOR_POSITIONS (line 31) | const ANCHOR_POSITIONS: AnchorPositionData[] = [
  function calculateAnchorOffset (line 53) | function calculateAnchorOffset(
  function resizeFrameWithAnchor (line 124) | function resizeFrameWithAnchor(
  function resizeAllFramesWithAnchor (line 170) | function resizeAllFramesWithAnchor(
  function getAnchorDescription (line 193) | function getAnchorDescription(anchor: AnchorPosition): string {

FILE: src/utils/canvasSizeConversion.ts
  type TypographySettings (line 7) | interface TypographySettings {
  type CharacterDimensions (line 14) | interface CharacterDimensions {
  type PixelDimensions (line 19) | interface PixelDimensions {
  function charactersToPixels (line 28) | function charactersToPixels(
  function pixelsToCharacters (line 53) | function pixelsToCharacters(
  function validateCharacterDimensions (line 78) | function validateCharacterDimensions(
  function getPixelConstraints (line 90) | function getPixelConstraints(typography: TypographySettings): {
  function validatePixelInput (line 114) | function validatePixelInput(

FILE: src/utils/canvasTextRendering.ts
  type ExtendedCanvasRenderingContext2D (line 32) | type ExtendedCanvasRenderingContext2D = CanvasRenderingContext2D & {

FILE: src/utils/characterPaletteValidation.ts
  type CharacterPaletteDraft (line 6) | type CharacterPaletteDraft = {
  type CharacterValidationResult (line 13) | interface CharacterValidationResult {

FILE: src/utils/cropUtils.ts
  function cropAllFramesToSelection (line 11) | function cropAllFramesToSelection(

FILE: src/utils/directCanvasRenderer.ts
  type DirectRenderSettings (line 12) | interface DirectRenderSettings {

FILE: src/utils/dirtyTracker.ts
  type DirtyRegion (line 6) | interface DirtyRegion {
  class DirtyTracker (line 13) | class DirtyTracker {
    method markCellDirty (line 21) | markCellDirty(x: number, y: number): void {
    method markRegionDirty (line 41) | markRegionDirty(startX: number, startY: number, endX: number, endY: nu...
    method markFullRedraw (line 66) | markFullRedraw(): void {
    method isDirtyFlag (line 75) | isDirtyFlag(): boolean {
    method needsFullRedraw (line 82) | needsFullRedraw(): boolean {
    method getDirtyRegion (line 89) | getDirtyRegion(): DirtyRegion | null {
    method clear (line 96) | clear(): void {
    method getRenderBounds (line 105) | getRenderBounds(canvasWidth: number, canvasHeight: number): DirtyRegio...

FILE: src/utils/effectKeyframeInterpolation.ts
  function interpolateNumeric (line 15) | function interpolateNumeric(kfA: EffectKeyframe, kfB: EffectKeyframe, fr...
  function holdInterpolate (line 31) | function holdInterpolate(
  function interpolateEffectProperty (line 58) | function interpolateEffectProperty(
  function interpolateNumericTrack (line 87) | function interpolateNumericTrack(sorted: EffectKeyframe[], frame: number...
  function wrapFrame (line 110) | function wrapFrame(sorted: EffectKeyframe[], frame: number): number {

FILE: src/utils/effectsPipeline.ts
  function evaluateEffectBlock (line 34) | function evaluateEffectBlock(
  function isFrameInRange (line 70) | function isFrameInRange(block: EffectBlock, frame: number): boolean {
  function applyEffectsToLayer (line 85) | function applyEffectsToLayer(
  function applyEffectsToGroup (line 124) | function applyEffectsToGroup(
  function applyGlobalEffects (line 142) | function applyGlobalEffects(
  function bakeEffectIntoFrames (line 163) | function bakeEffectIntoFrames(
  function hasActiveEffectsAtFrame (line 266) | function hasActiveEffectsAtFrame(

FILE: src/utils/effectsProcessing.ts
  function mapCanvasColorsToPalette (line 29) | function mapCanvasColorsToPalette(
  type ProcessEffectOptions (line 66) | interface ProcessEffectOptions {
  function processEffect (line 80) | async function processEffect(
  function processEffectOnFrames (line 175) | async function processEffectOnFrames(
  function processLevelsEffect (line 226) | function processLevelsEffect(
  function processHueSaturationEffect (line 288) | function processHueSaturationEffect(
  function processRemapColorsEffect (line 329) | function processRemapColorsEffect(
  function processRemapCharactersEffect (line 370) | function processRemapCharactersEffect(
  function shouldProcessColor (line 406) | function shouldProcessColor(color: string, colorRange: ColorRange | unde...
  function applyLevelsToColor (line 423) | function applyLevelsToColor(
  function applyLevelsToChannel (line 445) | function applyLevelsToChannel(
  function applyHSLAdjustments (line 480) | function applyHSLAdjustments(color: string, hueShift: number, saturation...
  function findColorMapping (line 497) | function findColorMapping(color: string, mappings: Record<string, string...
  function hexToRgb (line 535) | function hexToRgb(hex: string): { r: number; g: number; b: number } | nu...
  function rgbToHex (line 547) | function rgbToHex(r: number, g: number, b: number): string {
  function hexToHsl (line 558) | function hexToHsl(hex: string): { h: number; s: number; l: number } | nu...
  function hslToHex (line 594) | function hslToHex(h: number, s: number, l: number): string {
  function processScatterEffect (line 627) | function processScatterEffect(
  function createSeededRNG (line 756) | function createSeededRNG(seed: number) {
  function calculateDisplacement (line 784) | function calculateDisplacement(
  function blendColorPair (line 868) | function blendColorPair(color1: string, color2: string, weight: number):...

FILE: src/utils/exportDataCollector.ts
  function computeCompositedFrames (line 23) | function computeCompositedFrames(
  class ExportDataCollector (line 58) | class ExportDataCollector {
    method collect (line 62) | static collect(): ExportDataBundle {

FILE: src/utils/exportPixelCalculator.ts
  type PixelDimensions (line 6) | interface PixelDimensions {
  type ExportPixelOptions (line 11) | interface ExportPixelOptions {
  type ImageEstimateOptions (line 83) | interface ImageEstimateOptions {
  type SvgEstimateOptions (line 111) | interface SvgEstimateOptions {

FILE: src/utils/exportRenderer.ts
  type JsonExportFrameColors (line 35) | interface JsonExportFrameColors {
  type JsonExportFrameEntry (line 40) | interface JsonExportFrameEntry {
  type JsonExportMetadata (line 48) | interface JsonExportMetadata {
  type JsonExportStructure (line 61) | interface JsonExportStructure {
  class ExportRenderer (line 81) | class ExportRenderer {
    method constructor (line 84) | constructor(progressCallback?: (progress: ExportProgress) => void) {
    method exportImage (line 91) | async exportImage(
    method exportSvg (line 159) | async exportSvg(
    method exportVideo (line 312) | async exportVideo(
    method exportSession (line 359) | async exportSession(
    method exportText (line 478) | async exportText(
    method exportJson (line 570) | async exportJson(
    method exportHtml (line 723) | async exportHtml(
    method exportReactComponent (line 1348) | async exportReactComponent(
    method sanitizeReactFileName (line 1471) | private sanitizeReactFileName(value: string): string {
    method toPascalCase (line 1486) | private toPascalCase(value: string): string {
    method generateReactComponentCode (line 1500) | private generateReactComponentCode(options: {
    method exportInkComponent (line 1960) | async exportInkComponent(
    method generateInkComponentCode (line 2122) | private generateInkComponentCode(options: {
    method suggestLightModeColor (line 2373) | private suggestLightModeColor(hex: string): string {
    method suggestLightModeAnsiColor (line 2406) | private suggestLightModeAnsiColor(ansiColor: string): string {
    method exportOpenTuiComponent (line 2437) | async exportOpenTuiComponent(
    method generateOpenTuiComponentCode (line 2599) | private generateOpenTuiComponentCode(options: {
    method exportBubbleteaComponent (line 2844) | async exportBubbleteaComponent(
    method hexToAnsi16Color (line 2949) | private hexToAnsi16Color(hex: string): { code: string; name: string } {
    method hexTo256Color (line 3004) | private hexTo256Color(hex: string): number {
    method color256ToHex (line 3037) | private color256ToHex(code: number): string {
    method hexTo256Hex (line 3073) | private hexTo256Hex(hex: string): string {
    method generateBubbleteaCode (line 3081) | private generateBubbleteaCode(params: {
    method cropGrid (line 3447) | private cropGrid(grid: string[][], settings: TextExportSettings): stri...
    method createExportCanvas (line 3490) | private createExportCanvas(
    method renderFrame (line 3541) | private async renderFrame(
    method drawGrid (line 3600) | private drawGrid(
    method drawExportCell (line 3635) | private drawExportCell(
    method canvasToBlob (line 3666) | private canvasToBlob(canvas: HTMLCanvasElement, type: string, quality?...
    method supportsWebCodecs (line 3696) | private supportsWebCodecs(): boolean {
    method exportWebMVideo (line 3705) | private async exportWebMVideo(
    method exportMP4Fallback (line 3746) | private async exportMP4Fallback(
    method generateVideoFrames (line 3846) | private async generateVideoFrames(
    method deduplicateCliFrames (line 3932) | private deduplicateCliFrames(
    method getLoopMultiplier (line 3961) | private getLoopMultiplier(loops: VideoExportSettings['loops']): number {
    method encodeWebMVideo (line 3974) | private async encodeWebMVideo(
    method getBitrateForQuality (line 4053) | private getBitrateForQuality(quality: VideoExportSettings['quality'], ...
    method buildShaderExportBundle (line 4078) | private buildShaderExportBundle(
    method generateWebGLShaderRuntime (line 4177) | private generateWebGLShaderRuntime(bundle: NonNullable<ReturnType<Expo...
    method updateProgress (line 4415) | private updateProgress(message: string, percentage: number): void {

FILE: src/utils/fillArea.ts
  type FillAreaOptions (line 6) | interface FillAreaOptions {

FILE: src/utils/flipUtils.ts
  type FlipBounds (line 8) | interface FlipBounds {

FILE: src/utils/font/fontLoader.ts
  class FontLoader (line 16) | class FontLoader {
    method loadFont (line 24) | async loadFont(
    method loadFontFile (line 69) | private async loadFontFile(
    method preloadBundledFonts (line 108) | async preloadBundledFonts(): Promise<void> {
    method getFontForFamily (line 129) | async getFontForFamily(familyName: string): Promise<Font | null> {
    method getLoadedFont (line 170) | getLoadedFont(fontId: string): LoadedFont | null {
    method isFontLoaded (line 177) | isFontLoaded(fontId: string): boolean {
    method clearCache (line 184) | clearCache(): void {
    method getCacheStats (line 193) | getCacheStats() {
    method createError (line 205) | private createError(
    method handleLoadError (line 222) | private handleLoadError(error: unknown, fontId: string): FontLoadError...

FILE: src/utils/font/fontRegistry.ts
  constant FONT_REGISTRY (line 13) | const FONT_REGISTRY: FontMetadata[] = [
  constant DEFAULT_OUTLINE_FONT_ID (line 28) | const DEFAULT_OUTLINE_FONT_ID = 'jetbrains-mono';
  function getFontMetadata (line 33) | function getFontMetadata(fontId: string): FontMetadata | undefined {
  function getRecommendedFonts (line 40) | function getRecommendedFonts(): FontMetadata[] {
  function getFontPath (line 47) | function getFontPath(fontId: string): string | undefined {
  function isValidFontId (line 55) | function isValidFontId(fontId: string): boolean {
  function getFontDisplayName (line 62) | function getFontDisplayName(fontId: string): string {

FILE: src/utils/font/opentypePathConverter.ts
  function convertGlyphToSvgPath (line 14) | function convertGlyphToSvgPath(
  function transformPathToSvg (line 73) | function transformPathToSvg(
  function generateSvgPathElement (line 184) | function generateSvgPathElement(
  function hasGlyph (line 213) | function hasGlyph(font: Font, char: string): boolean {
  function getMissingGlyphs (line 225) | function getMissingGlyphs(font: Font, text: string): string[] {

FILE: src/utils/font/types.ts
  type FontMetadata (line 11) | interface FontMetadata {
  type FontLoadOptions (line 37) | interface FontLoadOptions {
  type LoadedFont (line 51) | interface LoadedFont {
  type GlyphExportOptions (line 68) | interface GlyphExportOptions {
  type GlyphPathResult (line 97) | interface GlyphPathResult {
  type FontLoadError (line 114) | type FontLoadError =
  type FontLoadErrorDetail (line 125) | interface FontLoadErrorDetail {

FILE: src/utils/fontDetection.ts
  function probeLocalFont (line 22) | async function probeLocalFont(fontName: string): Promise<boolean> {
  function canvasFontDetection (line 40) | function canvasFontDetection(fontName: string): boolean {
  function isFontAvailable (line 85) | async function isFontAvailable(fontName: string): Promise<boolean> {
  function parseFontStack (line 115) | function parseFontStack(fontStack: string): string[] {
  function getActualUsedFont (line 133) | async function getActualUsedFont(fontStack: string): Promise<string> {
  function detectMonospaceDefault (line 163) | function detectMonospaceDefault(): string {
  function detectAvailableFont (line 207) | async function detectAvailableFont(fontStack: string): Promise<string> {
  function isFallbackActive (line 225) | async function isFallbackActive(
  function clearFontCache (line 237) | function clearFontCache(): void {
  function getFontFallbackMessage (line 246) | function getFontFallbackMessage(

FILE: src/utils/fontLoader.ts
  constant BUNDLED_FONT_FILES (line 15) | const BUNDLED_FONT_FILES: Record<string, { url: string; weight?: number;...
  function loadBundledFont (line 43) | async function loadBundledFont(fontName: string): Promise<void> {
  function isFontLoaded (line 104) | function isFontLoaded(fontName: string): boolean {
  function isFontLoading (line 111) | function isFontLoading(fontName: string): boolean {
  function preloadBundledFonts (line 119) | function preloadBundledFonts(): void {
  function getBundledFontNames (line 136) | function getBundledFontNames(): string[] {

FILE: src/utils/fontMetrics.ts
  type FontMetrics (line 8) | interface FontMetrics {
  type SpacingSettings (line 16) | interface SpacingSettings {
  constant CELL_ASPECT_RATIO (line 25) | const CELL_ASPECT_RATIO = 0.6;
  constant DEFAULT_SPACING (line 119) | const DEFAULT_SPACING: SpacingSettings = {

FILE: src/utils/generators/digitalRain.ts
  type DigitalTrail (line 10) | interface DigitalTrail {
  function generateDigitalRain (line 24) | async function generateDigitalRain(

FILE: src/utils/generators/generatorEngine.ts
  type GeneratorResult (line 18) | interface GeneratorResult {
  function generateFrames (line 38) | async function generateFrames(
  function validateGeneratorParams (line 147) | function validateGeneratorParams(

FILE: src/utils/generators/particlePhysics.ts
  function perlinNoise3D (line 15) | function perlinNoise3D(x: number, y: number, z: number): number {
  function hash (line 53) | function hash(n: number): number {
  function fade (line 58) | function fade(t: number): number {
  function lerp (line 62) | function lerp(a: number, b: number, t: number): number {
  function grad (line 66) | function grad(hash: number, x: number, y: number, z: number): number {
  type Particle (line 73) | interface Particle {
  function getEmitterPosition (line 91) | function getEmitterPosition(
  function checkParticleCollision (line 134) | function checkParticleCollision(
  function resolveParticleCollision (line 148) | function resolveParticleCollision(
  function generateParticlePhysics (line 197) | async function generateParticlePhysics(

FILE: src/utils/generators/radioWaves.ts
  function calculateShapeDistance (line 15) | function calculateShapeDistance(
  function calculateProfileIntensity (line 112) | function calculateProfileIntensity(
  function generateRadioWaves (line 143) | async function generateRadioWaves(

FILE: src/utils/generators/rainDrops.ts
  type Ripple (line 11) | interface Ripple {
  function generateRainDrops (line 23) | async function generateRainDrops(

FILE: src/utils/generators/turbulentNoise.ts
  function generateTurbulentNoise (line 13) | async function generateTurbulentNoise(
  function perlinNoise3D (line 124) | function perlinNoise3D(x: number, y: number, z: number): number {
  function simplexNoise3D (line 165) | function simplexNoise3D(x: number, y: number, z: number): number {
  function worleyNoise3D (line 174) | function worleyNoise3D(x: number, y: number, z: number): number {
  function hash3D (line 212) | function hash3D(x: number, y: number, z: number): number {
  function grad3D (line 219) | function grad3D(hash: number, x: number, y: number, z: number): number {
  function fade (line 229) | function fade(t: number): number {
  function lerp (line 236) | function lerp(a: number, b: number, t: number): number {

FILE: src/utils/gradientEngine.ts
  type GradientPoint (line 3) | interface GradientPoint {
  type GradientOptions (line 8) | interface GradientOptions {

FILE: src/utils/kdTree.ts
  type KdNode (line 9) | interface KdNode<T> {
  type NearestResult (line 17) | interface NearestResult<T> {
  class KdTree (line 23) | class KdTree<T> {
    method constructor (line 27) | constructor(entries: Array<{ point: number[]; data: T }>) {
    method buildTree (line 37) | private buildTree(
    method findNearest (line 64) | findNearest(query: number[]): NearestResult<T> | null {
    method squaredDistance (line 104) | private squaredDistance(a: number[], b: number[]): number {

FILE: src/utils/layerCompositing.ts
  function compositeLayersAtFrame (line 44) | function compositeLayersAtFrame(
  function getContentFrameAtTime (line 394) | function getContentFrameAtTime(layer: Layer, frame: number): ContentFram...
  function getPropertyValueAtFrame (line 436) | function getPropertyValueAtFrame(
  function getTransformAtFrame (line 461) | function getTransformAtFrame(
  function applyRotation (line 501) | function applyRotation(
  function getVisibleLayers (line 534) | function getVisibleLayers(layers: Layer[]): Layer[] {
  function isLayerEditable (line 547) | function isLayerEditable(layer: Layer): boolean {
  function inverseTransformPoint (line 563) | function inverseTransformPoint(
  function getGroupPropertyValue (line 594) | function getGroupPropertyValue(
  function compositeOneLayerToScreenSpace (line 622) | function compositeOneLayerToScreenSpace(

FILE: src/utils/layerLimits.ts
  constant FREE_TIER_MAX_LAYERS (line 26) | const FREE_TIER_MAX_LAYERS = 5;
  constant UNLIMITED_LAYERS (line 29) | const UNLIMITED_LAYERS = -1;
  function registerSubscriptionLayerLimit (line 60) | function registerSubscriptionLayerLimit(getter: () => number): void {
  function getSubscriptionLayerLimit (line 68) | function getSubscriptionLayerLimit(): number {
  function canAddLayer (line 86) | function canAddLayer(): boolean {
  function getImportableLayerCount (line 101) | function getImportableLayerCount(incomingLayers: number): number {
  function getRemainingLayerCount (line 113) | function getRemainingLayerCount(): number {

FILE: src/utils/layerTransformUtils.ts
  type ComposedTransform (line 31) | interface ComposedTransform {
  function getComposedTransformForLayer (line 52) | function getComposedTransformForLayer(
  function screenToLocalForLayer (line 86) | function screenToLocalForLayer(
  function getActiveComposedTransform (line 111) | function getActiveComposedTransform(): ComposedTransform | null {
  function hasNonIdentityTransform (line 121) | function hasNonIdentityTransform(t: ComposedTransform): boolean {
  function screenToLocal (line 142) | function screenToLocal(x: number, y: number): { x: number; y: number } {
  function localToScreen (line 153) | function localToScreen(x: number, y: number): { x: number; y: number } {
  function transformCellMapToLocal (line 176) | function transformCellMapToLocal(cells: Map<string, Cell>): Map<string, ...
  function transformCellMapToScreen (line 194) | function transformCellMapToScreen(cells: Map<string, Cell>): Map<string,...

FILE: src/utils/lineArtConverter.ts
  type LineArtOptions (line 19) | interface LineArtOptions {
  constant DEFAULT_LINE_ART_OPTIONS (line 34) | const DEFAULT_LINE_ART_OPTIONS: LineArtOptions = {
  constant CHAR_WEIGHTS (line 47) | const CHAR_WEIGHTS: Record<string, number> = {
  constant EXCLUDED_CHARS (line 63) | const EXCLUDED_CHARS = new Set('abcdefghijklmnopqrstuvwxyz0123456789{}&$...
  type CharCandidate (line 66) | interface CharCandidate {
  class LineArtConverter (line 74) | class LineArtConverter {
    method init (line 83) | init(cellPixelWidth: number, cellPixelHeight: number, fontFamily = 'mo...
    method convertImage (line 144) | convertImage(
    method matchCharacter (line 216) | private matchCharacter(
    method sobelEdgeDetect (line 278) | private sobelEdgeDetect(
    method gaussianBlur (line 310) | private gaussianBlur(
    method morphDilate (line 357) | private morphDilate(
    method morphErode (line 390) | private morphErode(
    method sdfBlur (line 425) | private sdfBlur(

FILE: src/utils/mediaProcessor.ts
  type Mp4ArrayBuffer (line 15) | type Mp4ArrayBuffer = ArrayBuffer & { fileStart?: number };
  type MediaFile (line 17) | interface MediaFile {
  type ProcessingOptions (line 26) | interface ProcessingOptions {
  type ProcessedFrame (line 44) | interface ProcessedFrame {
  type ProcessingResult (line 52) | interface ProcessingResult {
  constant SUPPORTED_IMAGE_FORMATS (line 70) | const SUPPORTED_IMAGE_FORMATS = [
  constant SUPPORTED_VIDEO_FORMATS (line 80) | const SUPPORTED_VIDEO_FORMATS = [
  constant ALL_SUPPORTED_FORMATS (line 90) | const ALL_SUPPORTED_FORMATS = [
  class MediaProcessor (line 95) | class MediaProcessor {
    method constructor (line 99) | constructor() {
    method validateFile (line 111) | validateFile(file: File): MediaFile | null {
    method processImage (line 130) | async processImage(mediaFile: MediaFile, options: ProcessingOptions): ...
    method processVideo (line 165) | async processVideo(mediaFile: MediaFile, options: ProcessingOptions): ...
    method loadImage (line 202) | private loadImage(file: File): Promise<HTMLImageElement> {
    method loadVideo (line 214) | private loadVideo(file: File): Promise<HTMLVideoElement> {
    method processImageToCanvas (line 234) | private processImageToCanvas(img: HTMLImageElement, options: Processin...
    method extractVideoFrames (line 311) | private async extractVideoFrames(video: HTMLVideoElement, options: Pro...
    method estimateVideoFrameRate (line 366) | private async estimateVideoFrameRate(video: HTMLVideoElement, original...
    method extractFrameRateFromMetadata (line 386) | private async extractFrameRateFromMetadata(_video: HTMLVideoElement, o...
    method parseMP4FrameRate (line 403) | private parseMP4FrameRate(arrayBuffer: ArrayBuffer): Promise<number> {
    method processVideoFrameToCanvas (line 489) | private processVideoFrameToCanvas(
    method calculateSourceRect (line 571) | private calculateSourceRect(
    method dispose (line 659) | dispose(): void {

FILE: src/utils/paletteValidation.ts
  type ValidationResult (line 6) | interface ValidationResult {
  constant SUPPORTED_PALETTE_EXTENSIONS (line 195) | const SUPPORTED_PALETTE_EXTENSIONS = ['.json', '.palette', '.pal'] as co...

FILE: src/utils/performance.ts
  type PerformanceMetric (line 6) | interface PerformanceMetric {
  type RenderMetrics (line 13) | interface RenderMetrics {
  class PerformanceMonitor (line 20) | class PerformanceMonitor {
    method constructor (line 27) | constructor() {
    method start (line 35) | start(name: string): void {
    method end (line 47) | end(name: string): number {
    method measureCanvasRender (line 68) | measureCanvasRender(cellCount: number): { duration: number; fps: numbe...
    method getStats (line 105) | getStats(): {
    method logStats (line 144) | logStats(): void {
    method clear (line 153) | clear(): void {
    method testLargeGrid (line 163) | async testLargeGrid(width: number, height: number): Promise<{
    method getRecommendation (line 206) | private getRecommendation(renderTime: number, cellCount: number): stri...
  type PerformanceHelperBindings (line 240) | type PerformanceHelperBindings = {

FILE: src/utils/polygon.ts
  type Point (line 5) | interface Point {
  function isPointInPolygon (line 16) | function isPointInPolygon(point: Point, polygon: Point[]): boolean {
  function lineIntersectsCell (line 47) | function lineIntersectsCell(p1: Point, p2: Point, cellX: number, cellY: ...
  function getCellsInPolygon (line 111) | function getCellsInPolygon(polygon: Point[], width: number, height: numb...
  function smoothPolygonPath (line 155) | function smoothPolygonPath(points: Point[], tolerance: number = 2): Poin...

FILE: src/utils/postEffectsPipeline.ts
  function evaluatePostEffectBlock (line 26) | function evaluatePostEffectBlock(
  function getActivePostEffects (line 89) | function getActivePostEffects(
  function hasActivePostEffectsAtFrame (line 106) | function hasActivePostEffectsAtFrame(
  function buildPostEffectPasses (line 131) | function buildPostEffectPasses(
  function hasAnyPostEffects (line 153) | function hasAnyPostEffects(postEffectTracks: PostEffectTrack[]): boolean {

FILE: src/utils/projectUtils.ts
  function getProjectFrameCount (line 11) | function getProjectFrameCount(sessionData: CloudProject['sessionData']):...

FILE: src/utils/renderScheduler.ts
  type RenderCallback (line 6) | type RenderCallback = () => void;
  class RenderScheduler (line 8) | class RenderScheduler {
    method schedule (line 16) | schedule(callback: RenderCallback): void {
    method executeBatch (line 30) | private executeBatch(): void {
    method cancel (line 50) | cancel(): void {
    method flush (line 62) | flush(): void {
  type RenderListener (line 85) | type RenderListener = () => void;
  function notifyCanvasRendered (line 89) | function notifyCanvasRendered(): void {
  function onCanvasRendered (line 96) | function onCanvasRendered(fn: RenderListener): () => void {

FILE: src/utils/selectionConstraint.ts
  function isCellDrawable (line 21) | function isCellDrawable(x: number, y: number): boolean {
  function isCellDrawableWithState (line 43) | function isCellDrawableWithState(
  function constrainCellsToSelection (line 61) | function constrainCellsToSelection(
  function constrainCellsToSelectionWithState (line 83) | function constrainCellsToSelectionWithState(
  function constrainCellMapToSelection (line 102) | function constrainCellMapToSelection(
  function constrainCellMapToMask (line 128) | function constrainCellMapToMask(
  function getSelectionState (line 148) | function getSelectionState(): {
  function hasActiveSelection (line 161) | function hasActiveSelection(): boolean {
  function getSelectionBounds (line 170) | function getSelectionBounds(): {
  function isPointInSelectionBounds (line 187) | function isPointInSelectionBounds(x: number, y: number): boolean {
  function canFillCell (line 203) | function canFillCell(cellKey: string): boolean {
  function canFillCellWithState (line 219) | function canFillCellWithState(

FILE: src/utils/selectionUtils.ts
  type SelectionBounds (line 3) | interface SelectionBounds {

FILE: src/utils/sessionImporter.ts
  type SessionFrameCells (line 17) | type SessionFrameCells = Record<string, Cell>;
  type SessionFrameData (line 19) | interface SessionFrameData {
  type SessionCanvasData (line 27) | interface SessionCanvasData {
  type SessionAnimationData (line 34) | interface SessionAnimationData {
  type SessionToolsData (line 41) | interface SessionToolsData {
  type SessionPalettesData (line 49) | interface SessionPalettesData {
  type SessionCharacterPalettesData (line 55) | interface SessionCharacterPalettesData {
  type SessionImportData (line 63) | interface SessionImportData {
  class SessionImporter (line 79) | class SessionImporter {
    method importSessionFile (line 84) | static async importSessionFile(
    method _validateSessionData (line 154) | private static _validateSessionData(data: unknown): data is SessionImp...
    method _restoreSessionData (line 247) | private static _restoreSessionData(
    method restoreSessionDataV2 (line 415) | private static restoreSessionDataV2(

FILE: src/utils/sessionMigration.ts
  type V1SessionFrame (line 24) | interface V1SessionFrame {
  type V1SessionData (line 36) | interface V1SessionData {
  function detectSessionVersion (line 71) | function detectSessionVersion(data: unknown): '1.0.0' | '2.0.0' | 'unkno...
  constant DEFAULT_FRAME_DURATION_MS (line 99) | const DEFAULT_FRAME_DURATION_MS = 100;
  constant MIN_FRAME_RATE (line 104) | const MIN_FRAME_RATE = 1;
  constant MAX_FRAME_RATE (line 105) | const MAX_FRAME_RATE = 60;
  function migrateV1ToV2 (line 120) | function migrateV1ToV2(v1Data: unknown): SessionDataV2 {
  function validateAndRepairV2 (line 233) | function validateAndRepairV2(data: SessionDataV2): {

FILE: src/utils/shapeBasedConverter.ts
  type AutoModeCharacterSet (line 29) | type AutoModeCharacterSet = 'basic-ascii' | 'block-characters' | 'braille';
  type ShapeMappingMethod (line 32) | type ShapeMappingMethod = 'brightness' | 'luminance' | 'saturation' | 'r...
  type ShapeConverterOptions (line 34) | interface ShapeConverterOptions {
  constant SAMPLING_QUALITY_PRESETS (line 45) | const SAMPLING_QUALITY_PRESETS = {
  type SamplingQuality (line 51) | type SamplingQuality = keyof typeof SAMPLING_QUALITY_PRESETS;
  class ShapeBasedConverter (line 53) | class ShapeBasedConverter {
    method constructor (line 58) | constructor(options: ShapeConverterOptions) {
    method convertImage (line 86) | convertImage(
    method convertImageBraille (line 177) | private convertImageBraille(
    method computeSamplingVector (line 253) | computeSamplingVector(
    method computeExternalSamplingVector (line 279) | private computeExternalSamplingVector(
    method sampleCircle (line 305) | private sampleCircle(
    method pixelToScalar (line 349) | private pixelToScalar(r: number, g: number, b: number): number {
    method applyGlobalContrast (line 386) | applyGlobalContrast(vector: number[], exponent: number): number[] {
    method applyDirectionalContrast (line 405) | applyDirectionalContrast(
    method findBestCharacter (line 430) | findBestCharacter(samplingVector: number[]): string {

FILE: src/utils/svgExportUtils.ts
  function generateSvgHeader (line 12) | function generateSvgHeader(
  function generateSvgGrid (line 27) | function generateSvgGrid(
  function generateSvgTextElement (line 55) | function generateSvgTextElement(
  function convertTextToPath (line 94) | function convertTextToPath(
  function convertTextToPathPixelTracing (line 153) | function convertTextToPathPixelTracing(
  function canvasToSvgPath (line 229) | function canvasToSvgPath(
  function traceContour (line 293) | function traceContour(
  function escapeXml (line 388) | function escapeXml(str: string): string {
  function prettifySvg (line 401) | function prettifySvg(svg: string): string {
  function minifySvg (line 410) | function minifySvg(svg: string): string {

FILE: src/utils/timeEffectsProcessing.ts
  function calculateAccumulatedTime (line 22) | function calculateAccumulatedTime(
  function applyWaveWarpToFrame (line 50) | function applyWaveWarpToFrame(
  function applyWiggleToFrame (line 110) | function applyWiggleToFrame(
  function fpsToMs (line 179) | function fpsToMs(fps: number): number {
  function msToFps (line 190) | function msToFps(ms: number): number {
  function clampFrameDuration (line 203) | function clampFrameDuration(ms: number, min: number = 17, max: number = ...
  function clampFps (line 215) | function clampFps(fps: number, min: number = 1, max: number = 60): number {

FILE: src/utils/vectorShapeGeometry.ts
  function generateShapeAnchorId (line 11) | function generateShapeAnchorId(): string {
  constant KAPPA (line 19) | const KAPPA = 0.5522847498;
  type ShapeBounds (line 21) | interface ShapeBounds {
  function generateRectangleAnchorPoints (line 33) | function generateRectangleAnchorPoints(bounds: ShapeBounds, filled: bool...
  function generateEllipseAnchorPoints (line 74) | function generateEllipseAnchorPoints(bounds: ShapeBounds, filled: boolea...

FILE: src/utils/webgl/WebGLPostProcessor.ts
  type PostEffectPass (line 26) | interface PostEffectPass {
  class WebGLPostProcessor (line 37) | class WebGLPostProcessor {
    method initialize (line 73) | initialize(canvas: HTMLCanvasElement): boolean {
    method dispose (line 114) | dispose(): void {
    method isReady (line 155) | isReady(): boolean {
    method render (line 172) | render(
    method renderPassthrough (line 311) | renderPassthrough(
    method createQuad (line 351) | private createQuad(): void {
    method uploadTexture (line 385) | private uploadTexture(texture: WebGLTexture, source: HTMLCanvasElement...
    method ensureFramebuffers (line 401) | private ensureFramebuffers(width: number, height: number): void {
    method setUniform (line 455) | private setUniform(
    method setUniformFromValue (line 488) | private setUniformFromValue(
  function hexToRgb (line 533) | function hexToRgb(hex: string): [number, number, number] {

FILE: src/utils/webgl/commonShaders.ts
  constant FULLSCREEN_VERTEX_SHADER (line 15) | const FULLSCREEN_VERTEX_SHADER = `#version 300 es
  constant PASSTHROUGH_FRAGMENT_SHADER (line 37) | const PASSTHROUGH_FRAGMENT_SHADER = `#version 300 es
  constant GLSL_UTILITIES (line 57) | const GLSL_UTILITIES = `
  function buildFragmentShader (line 122) | function buildFragmentShader(

FILE: src/utils/webgl/shaderCompiler.ts
  type ShaderProgram (line 12) | interface ShaderProgram {
  function compileShader (line 26) | function compileShader(
  function linkProgram (line 58) | function linkProgram(
  function createShaderProgram (line 83) | function createShaderProgram(
  function cacheKey (line 132) | function cacheKey(vertexSource: string, fragmentSource: string): string {
  function getOrCreateProgram (line 146) | function getOrCreateProgram(
  function clearProgramCache (line 170) | function clearProgramCache(): void {
Copy disabled (too large) Download .json
Condensed preview — 653 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (18,260K chars).
[
  {
    "path": ".gitignore",
    "chars": 1011,
    "preview": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\nlerna-debug.log*\n\nnode_modules\ndist\ndis"
  },
  {
    "path": ".gitmodules",
    "chars": 228,
    "preview": "[submodule \"packages/premium\"]\n\tpath = packages/premium\n\turl = https://github.com/cameronfoxly/Ascii-Motion-Premium.git\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 5803,
    "preview": "# Contributing to ASCII Motion\n\nThank you for your interest in contributing to ASCII Motion! We welcome contributions to"
  },
  {
    "path": "COPILOT_INSTRUCTIONS.md",
    "chars": 14444,
    "preview": "# ASCII Motion - Copilot Development Instructions\n\n## Project Overview\n\nASCII Motion is a React + TypeScript web applica"
  },
  {
    "path": "LICENSE-MIT",
    "chars": 1069,
    "preview": "MIT License\n\nCopyright (c) 2025 ASCII Motion\n\nPermission is hereby granted, free of charge, to any person obtaining a co"
  },
  {
    "path": "LICENSE-PREMIUM",
    "chars": 1999,
    "preview": "PROPRIETARY LICENSE\n\nCopyright (c) 2025 ASCII Motion\n\nAll rights reserved.\n\nThis software and associated documentation f"
  },
  {
    "path": "README.md",
    "chars": 12334,
    "preview": "# [ASCII Motion](https://ascii-motion.app)\n\n![ASCII Motion](https://img.shields.io/badge/version-2.0.4-green)\n![License "
  },
  {
    "path": "api/og.ts",
    "chars": 6305,
    "preview": "// Vercel Edge Function for Dynamic Open Graph Tags\n// This handles /community/project/:projectId URLs and injects dynam"
  },
  {
    "path": "components.json",
    "chars": 444,
    "preview": "{\n  \"$schema\": \"https://ui.shadcn.com/schema.json\",\n  \"style\": \"new-york\",\n  \"rsc\": false,\n  \"tsx\": true,\n  \"tailwind\": "
  },
  {
    "path": "dev-tools/README.md",
    "chars": 1283,
    "preview": "# Development Tools & Test Files\n\nThis directory contains development utilities, test scripts, and debugging tools used "
  },
  {
    "path": "dev-tools/bubbletea-test-cli/README.md",
    "chars": 4796,
    "preview": "# Bubbletea Test CLI\n\nTest harness for ASCII Motion Bubbletea (Go) component exports.\n\n## Prerequisites\n\n- Go 1.21 or la"
  },
  {
    "path": "dev-tools/bubbletea-test-cli/animations/ascii_motion_anim.go",
    "chars": 176724,
    "preview": "package asciimotion\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/charmbra"
  },
  {
    "path": "dev-tools/bubbletea-test-cli/animations/copilotspin/copilot_spin.go",
    "chars": 231928,
    "preview": "package copilotspin\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/charmbra"
  },
  {
    "path": "dev-tools/bubbletea-test-cli/animations/effects/ascii_motion_anim_effects.go",
    "chars": 851092,
    "preview": "package effects\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/charmbracele"
  },
  {
    "path": "dev-tools/bubbletea-test-cli/animations/effects2/ascii_motion_anim_effects2.go",
    "chars": 851093,
    "preview": "package effects2\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/charmbracel"
  },
  {
    "path": "dev-tools/bubbletea-test-cli/animations/effects3/ascii_motion_anim_effects3.go",
    "chars": 851097,
    "preview": "package effects3\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/charmbracel"
  },
  {
    "path": "dev-tools/bubbletea-test-cli/animations/newtest/ascii_motion_anim_new.go",
    "chars": 176720,
    "preview": "package newtest\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/charmbracele"
  },
  {
    "path": "dev-tools/bubbletea-test-cli/go.mod",
    "chars": 918,
    "preview": "module bubbletea-test-cli\n\ngo 1.21\n\nrequire (\n\tgithub.com/charmbracelet/bubbletea v1.2.4\n\tgithub.com/charmbracelet/lipgl"
  },
  {
    "path": "dev-tools/bubbletea-test-cli/go.sum",
    "chars": 3342,
    "preview": "github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=\ngithub.com/aymanbagabas/go-os"
  },
  {
    "path": "dev-tools/bubbletea-test-cli/main.go",
    "chars": 402,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\tanim \"bubbletea-test-cli/animations/effects3\"\n\n\ttea \"github.com/charmbracelet/bubb"
  },
  {
    "path": "dev-tools/clipboard-test.js",
    "chars": 1659,
    "preview": "/**\n * Test file for clipboard utilities\n * Run this in browser console to verify OS clipboard functionality\n */\n\n// Exa"
  },
  {
    "path": "dev-tools/debug-video-export.js",
    "chars": 2224,
    "preview": "/**\n * Video Export Debug Script\n * Run this in the browser console to test video export functionality\n */\n\n// Test func"
  },
  {
    "path": "dev-tools/font-test.html",
    "chars": 4019,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <title>Font Metrics Test</title>\n    <style>\n        body { font-family: Arial, sans-s"
  },
  {
    "path": "dev-tools/gridColorTest.ts",
    "chars": 1322,
    "preview": "/**\n * Test script to validate grid color calculations\n * This can be used to quickly test different background colors\n "
  },
  {
    "path": "dev-tools/ink-test-cli/README.md",
    "chars": 1686,
    "preview": "# Ink Test CLI\n\nA simple CLI project for testing ASCII Motion Ink component exports.\n\n## Setup\n\n```bash\ncd dev-tools/ink"
  },
  {
    "path": "dev-tools/ink-test-cli/package.json",
    "chars": 562,
    "preview": "{\n  \"name\": \"ink-test-cli\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Test CLI for ASCII Motion Ink component exports\",\n  "
  },
  {
    "path": "dev-tools/ink-test-cli/src/ascii-motion-cli-effects.tsx",
    "chars": 949378,
    "preview": "import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';\nimport { Box, Text } from 'ink';\n\n// C"
  },
  {
    "path": "dev-tools/ink-test-cli/src/ascii-motion-cli_256.tsx",
    "chars": 268743,
    "preview": "import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';\nimport { Box, Text } from 'ink';\n\n// C"
  },
  {
    "path": "dev-tools/ink-test-cli/src/cli.tsx",
    "chars": 3212,
    "preview": "#!/usr/bin/env node\nimport React from 'react';\nimport { render, Box, Text } from 'ink';\n\n// Import your exported Ink com"
  },
  {
    "path": "dev-tools/ink-test-cli/tsconfig.json",
    "chars": 400,
    "preview": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"NodeNext\",\n    \"moduleResolution\": \"NodeNext\",\n    \"jsx\""
  },
  {
    "path": "dev-tools/opentui-test-cli/README.md",
    "chars": 1995,
    "preview": "# OpenTUI Test CLI\n\nTest harness for ASCII Motion OpenTUI component exports.\n\n> **Note:** OpenTUI is designed for [Bun]("
  },
  {
    "path": "dev-tools/opentui-test-cli/package.json",
    "chars": 664,
    "preview": "{\n  \"name\": \"opentui-test-cli\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Test CLI for OpenTUI component exports from ASCI"
  },
  {
    "path": "dev-tools/opentui-test-cli/src/ascii-motion-opentui-hex.tsx",
    "chars": 184984,
    "preview": "import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';\n\n// Color themes - edit these values t"
  },
  {
    "path": "dev-tools/opentui-test-cli/src/ascii-motion-tui-ansi2.tsx",
    "chars": 268217,
    "preview": "import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';\n\n// Color themes - edit these values t"
  },
  {
    "path": "dev-tools/opentui-test-cli/src/ascii-motion-tui-effects.tsx",
    "chars": 949331,
    "preview": "import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';\n\n// Color themes - edit these values t"
  },
  {
    "path": "dev-tools/opentui-test-cli/src/ascii-motion-tui-semantic.tsx",
    "chars": 216699,
    "preview": "import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';\n\n// Color themes - edit these values t"
  },
  {
    "path": "dev-tools/opentui-test-cli/src/ascii-motion-tui.tsx",
    "chars": 435912,
    "preview": "\nimport React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';\n\n// Color themes - edit these values "
  },
  {
    "path": "dev-tools/opentui-test-cli/src/ascii-motion-tui2.tsx",
    "chars": 268201,
    "preview": "import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';\n\n// Color themes - edit these values t"
  },
  {
    "path": "dev-tools/opentui-test-cli/src/cli.tsx",
    "chars": 915,
    "preview": "import React from 'react';\nimport { createCliRenderer } from '@opentui/core';\nimport { createRoot } from '@opentui/react"
  },
  {
    "path": "dev-tools/opentui-test-cli/src/fish-animation-256.tsx",
    "chars": 88942,
    "preview": "import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';\n\n// Color themes - hex colors clamped "
  },
  {
    "path": "dev-tools/opentui-test-cli/src/fish-animation.tsx",
    "chars": 88321,
    "preview": "import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';\n\n// Color themes - edit these values t"
  },
  {
    "path": "dev-tools/opentui-test-cli/tsconfig.json",
    "chars": 557,
    "preview": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"lib\": ["
  },
  {
    "path": "dev-tools/react-export-test/README.md",
    "chars": 927,
    "preview": "# React Export Test Harness\n\nA minimal React + Vite project for testing ASCII Motion's exported React components.\n\n## Se"
  },
  {
    "path": "dev-tools/react-export-test/index.html",
    "chars": 319,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-w"
  },
  {
    "path": "dev-tools/react-export-test/package.json",
    "chars": 458,
    "preview": "{\n  \"name\": \"react-export-test\",\n  \"private\": true,\n  \"version\": \"0.0.0\",\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": "
  },
  {
    "path": "dev-tools/react-export-test/src/App.tsx",
    "chars": 1153,
    "preview": "/**\n * ASCII Motion — React Export Test Harness\n * \n * Drop an exported .tsx/.jsx file from ASCII Motion into src/ and i"
  },
  {
    "path": "dev-tools/react-export-test/src/ascii-motion-animation-effects.tsx",
    "chars": 568625,
    "preview": "'use client';\n\nimport { useEffect, useRef, useCallback, useState } from 'react';\n\n// Compact cell format: [x, y, char, c"
  },
  {
    "path": "dev-tools/react-export-test/src/ascii-motion-animation-new.tsx",
    "chars": 227594,
    "preview": "'use client';\n\nimport { useEffect, useRef, useCallback } from 'react';\n\n// Compact cell format: [x, y, char, colorIndex,"
  },
  {
    "path": "dev-tools/react-export-test/src/ascii-motion-animation.tsx",
    "chars": 229623,
    "preview": "'use client';\n\nimport { useEffect, useRef, useCallback, useState } from 'react';\n\n// Compact cell format: [x, y, char, c"
  },
  {
    "path": "dev-tools/react-export-test/src/main.tsx",
    "chars": 205,
    "preview": "import { StrictMode } from 'react'\nimport { createRoot } from 'react-dom/client'\nimport App from './App'\n\ncreateRoot(doc"
  },
  {
    "path": "dev-tools/react-export-test/src/shader-test-01.tsx",
    "chars": 178818,
    "preview": "'use client';\n\nimport { useEffect, useRef, useCallback } from 'react';\n\n// Compact cell format: [x, y, char, colorIndex,"
  },
  {
    "path": "dev-tools/react-export-test/src/shader-test-02.tsx",
    "chars": 179643,
    "preview": "'use client';\n\nimport { useEffect, useRef, useCallback } from 'react';\n\n// Compact cell format: [x, y, char, colorIndex,"
  },
  {
    "path": "dev-tools/react-export-test/src/vite-env.d.ts",
    "chars": 38,
    "preview": "/// <reference types=\"vite/client\" />\n"
  },
  {
    "path": "dev-tools/react-export-test/tsconfig.json",
    "chars": 377,
    "preview": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"useDefineForClassFields\": true,\n    \"lib\": [\"ES2020\", \"DOM\", \"DOM."
  },
  {
    "path": "dev-tools/react-export-test/vite.config.ts",
    "chars": 158,
    "preview": "import { defineConfig } from 'vite'\nimport react from '@vitejs/plugin-react'\n\nexport default defineConfig({\n  plugins: ["
  },
  {
    "path": "dev-tools/sample-json-export.json",
    "chars": 1519,
    "preview": "{\n  \"metadata\": {\n    \"exportedAt\": \"2025-09-24T18:30:00.000Z\",\n    \"exportVersion\": \"1.0.0\",\n    \"appVersion\": \"0.1.10\""
  },
  {
    "path": "dev-tools/test-frame-timing.js",
    "chars": 4129,
    "preview": "/**\n * Video Frame Timing Test Script\n * Run this in the browser console to test the corrected frame timing calculations"
  },
  {
    "path": "dev-tools/test-ibm-vga-font.html",
    "chars": 3161,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n  <title>IBM VGA Font Test</title>\n  <style>\n    @font-face {\n      font-family: 'Px437 IB"
  },
  {
    "path": "dev-tools/test-json-html-export.js",
    "chars": 4783,
    "preview": "/**\n * JSON Export/Import Test Script - NEW TEXT-BASED FORMAT\n * Run this in the browser console to test the updated JSO"
  },
  {
    "path": "dev-tools/test-palette.json",
    "chars": 452,
    "preview": "{\n  \"name\": \"Test Palette\",\n  \"description\": \"A sample palette for testing import functionality\",\n  \"version\": \"1.0.0\",\n"
  },
  {
    "path": "dev-tools/test-sf-mono.html",
    "chars": 3168,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <title>SF Mono Detection Test</title>\n    <style>\n        body {\n            font-fami"
  },
  {
    "path": "dev-tools/test-video-export.js",
    "chars": 2534,
    "preview": "/**\n * Video Export Test Script\n * Quick verification that video export functionality is working\n */\n\n// Test WebCodecs "
  },
  {
    "path": "dev-tools/test-video-loops.js",
    "chars": 2108,
    "preview": "/**\n * Loop Functionality Test Script\n * Run this in the browser console to test the video export loop settings\n */\n\n// "
  },
  {
    "path": "docs/ADDING_CUSTOM_FONTS.md",
    "chars": 13953,
    "preview": "# Adding Custom Fonts to ASCII Motion\n\nThis guide covers how to properly add custom fonts to ASCII Motion so they work c"
  },
  {
    "path": "docs/ADDING_FEATURES_TO_PROJECT_SYSTEM.md",
    "chars": 16137,
    "preview": "# Adding Features to the Project Save System\n\n**Date:** October 12, 2025  \n**For:** ASCII Motion Developers  \n**Purpose:"
  },
  {
    "path": "docs/ANIMATION_PLAYBACK_OPTIMIZATION.md",
    "chars": 5890,
    "preview": "# Animation Playback Optimization Implementation\n\n## Quick Reference\n**Status:** ✅ Completed (October 2025)  \n**Performa"
  },
  {
    "path": "docs/ANIMATION_PLAYBACK_OPTIMIZATION_PLAN.md",
    "chars": 20391,
    "preview": "# Animation Playback Performance Optimization Plan\n\n## Executive Summary\n\nAfter analyzing your animation playbook system"
  },
  {
    "path": "docs/ANIMATION_SYSTEM_GUIDE.md",
    "chars": 23661,
    "preview": "# Animation System Implementation Guide\n\n## Recent Updates (October 2025)\n\n### 🚀 Performance Optimization Completed\nThe "
  },
  {
    "path": "docs/ASCII_BOX_TOOL_IMPLEMENTATION_PLAN.md",
    "chars": 41385,
    "preview": "# ASCII Box Drawing Tool - Implementation Plan\n\n**Date:** October 5, 2025  \n**Status:** ✅ Ready for Implementation  \n**T"
  },
  {
    "path": "docs/ASCII_TYPE_TOOL_IMPLEMENTATION_PLAN.md",
    "chars": 7692,
    "preview": "# ASCII Type Tool Implementation Plan\n\n## Overview\nCreate a new \"ASCII Type\" tool that lets users render Figlet fonts di"
  },
  {
    "path": "docs/BEZIER_GRANULAR_UNDO_IMPLEMENTATION.md",
    "chars": 7436,
    "preview": "# Bezier Granular Undo/Redo Implementation\n\n## Overview\nImplemented granular undo/redo tracking for all bezier shape too"
  },
  {
    "path": "docs/BEZIER_SHAPE_TOOL_IMPLEMENTATION_PLAN.md",
    "chars": 53439,
    "preview": "# Bezier Shape Tool - Complete Implementation Plan\n\n## Overview\nA sophisticated bezier shape drawing tool inspired by Fi"
  },
  {
    "path": "docs/BRUSH_HOVER_PREVIEW_PLAN.md",
    "chars": 12239,
    "preview": "# Brush Hover Preview Implementation Plan\n\n## Overview\nAdd a canvas hover preview system that displays the brush pattern"
  },
  {
    "path": "docs/BRUSH_TOOL_USER_GUIDE.md",
    "chars": 5605,
    "preview": "# Brush Tool User Guide\n\n## Overview\nThe brush system provides advanced drawing capabilities for the pencil tool, allowi"
  },
  {
    "path": "docs/BUBBLETEA_EXPORT_IMPLEMENTATION_PLAN.md",
    "chars": 9287,
    "preview": "# Bubbletea Export Implementation Plan\n\n## Overview\n\nThis document outlines the implementation plan for exporting ASCII "
  },
  {
    "path": "docs/BUILD_FIXES.md",
    "chars": 7159,
    "preview": "# Build Fixes - Resolved TypeScript Errors\n\n## Problem\nRunning `npm run build` was failing with 11+ TypeScript errors pr"
  },
  {
    "path": "docs/CANVAS_RENDERING_IMPROVEMENTS.md",
    "chars": 5708,
    "preview": "# Canvas Rendering Quality: Final Implementation Report\n\n## Problem Identified\nThe ASCII Motion canvas was displaying bl"
  },
  {
    "path": "docs/CANVAS_TEXT_RENDERING.md",
    "chars": 12029,
    "preview": "# Canvas Text Rendering: Final Implementation\n\n## Overview\n\nThis document outlines the **final working solution** for cr"
  },
  {
    "path": "docs/COEP_CONFIGURATION_GUIDE.md",
    "chars": 9644,
    "preview": "# COEP Configuration Guide\n\n## Overview\n\nThis document explains the Cross-Origin-Embedder-Policy (COEP) configuration fo"
  },
  {
    "path": "docs/COEP_TROUBLESHOOTING_GUIDE.md",
    "chars": 8854,
    "preview": "# COEP/CSP Troubleshooting Guide\n\n## Quick Diagnostic Flowchart\n\n```\nIssue: FFmpeg or Vimeo not working in production\n├─"
  },
  {
    "path": "docs/COLOR_PALETTE_OVERHAUL_PLAN.md",
    "chars": 13898,
    "preview": "# Color Palette System Overhaul - Implementat## Phase 5: Import/Export System\n**Status: ✅ Complete**\n- [x] Create import"
  },
  {
    "path": "docs/CROP_CANVAS_TO_SELECTION.md",
    "chars": 6769,
    "preview": "# Crop Canvas to Selection Feature\n\n## Overview\nThe Crop Canvas to Selection feature allows users to reduce the canvas s"
  },
  {
    "path": "docs/DIALOG_COMPONENT_AUDIT.md",
    "chars": 19177,
    "preview": "# Dialog Component Audit\n\n> **Complete analysis of all 26 dialog components in ASCII Motion**\n> \n> Use this document to "
  },
  {
    "path": "docs/DIALOG_CONSISTENCY_UPDATE.md",
    "chars": 4998,
    "preview": "# Dialog Consistency Update\n\n**Date**: October 17, 2025\n**Author**: GitHub Copilot\n**Status**: ✅ Complete\n\n## Overview\n\n"
  },
  {
    "path": "docs/DIGITAL_RAIN_GENERATOR_IMPLEMENTATION.md",
    "chars": 19528,
    "preview": "# Digital Rain (Matrix) Generator - Implementation Summary\n\n**Date:** October 31, 2025  \n**Status:** ✅ Implemented  \n**F"
  },
  {
    "path": "docs/DITHERING_ANALYSIS_AND_PLAN.md",
    "chars": 11415,
    "preview": "# Dithering Analysis and Implementation Plan\n\n## Current State Analysis\n\n### Current Dithering Implementation\n\nThe media"
  },
  {
    "path": "docs/DITHERING_IMPLEMENTATION_SUMMARY.md",
    "chars": 10109,
    "preview": "# Dithering Implementation Summary\n\n## Overview\n\nSuccessfully implemented enhanced dithering options for the media impor"
  },
  {
    "path": "docs/DITHERING_QUICK_REFERENCE.md",
    "chars": 6370,
    "preview": "# Dithering Quick Reference Guide\n\n## What is Dithering?\n\nDithering is a technique used when converting images with many"
  },
  {
    "path": "docs/DRAGGABLE_PICKERS_IMPLEMENTATION.md",
    "chars": 9282,
    "preview": "# Draggable Picker Dialogs Implementation Summary\n\n## Overview\nAdded drag-to-reposition functionality to all character a"
  },
  {
    "path": "docs/DRAWING_GAP_FIX.md",
    "chars": 6190,
    "preview": "# Drawing Tool Architecture: Gap-Filling & Shift+Click Line Drawing\n\n## Problem History ❌\n1. **Original Issue**: Fast mo"
  },
  {
    "path": "docs/EFFECTS_DEVELOPER_GUIDE.md",
    "chars": 14986,
    "preview": "# Effects System Developer Guide\n\n## 🎯 **Adding New Effects to ASCII Motion**\n\nThis guide provides step-by-step instruct"
  },
  {
    "path": "docs/EFFECTS_IMPLEMENTATION_SUMMARY.md",
    "chars": 14515,
    "preview": "# Effects System Implementation Summary\n\n## 🎉 **PRODUCTION READY - EXTENDED**\n\n**Final Status**: 5 effects implemented a"
  },
  {
    "path": "docs/EFFECTS_SYSTEM_IMPLEMENTATION.md",
    "chars": 29396,
    "preview": "# ASCII Motion - Effects System Implementation Guide\n\n## 🚨 **CURRENT STATUS: PRODUCTION READY** 🚨\n\n**Implementation Stat"
  },
  {
    "path": "docs/EFFECTS_SYSTEM_USER_GUIDE.md",
    "chars": 16997,
    "preview": "# Effects System User Guide\n\nThe ASCII Motion Effects System provides powerful, easy-to-use tools to transform your ASCI"
  },
  {
    "path": "docs/ELLIPSE_RADIAL_GRADIENTS.md",
    "chars": 3039,
    "preview": "# Elliptical Radial Gradients\n\n## Overview\nThe gradient fill tool now supports elliptical radial gradients in addition t"
  },
  {
    "path": "docs/EXPORT_METADATA_AUDIT_COMPLETE.md",
    "chars": 11291,
    "preview": "# Export Metadata Audit - Complete ✅\n\n**Date:** 2025-10-16  \n**Status:** All export dialogs updated  \n**Single Source of"
  },
  {
    "path": "docs/FIGMA_COMPONENT_RECREATION_GUIDE.md",
    "chars": 17133,
    "preview": "# Figma Component Recreation Guide\n\n> **Step-by-step instructions for recreating ASCII Motion's dialog components in Fig"
  },
  {
    "path": "docs/FIGMA_DESIGN_SYSTEM_SETUP.md",
    "chars": 17952,
    "preview": "# Figma Design System Setup Guide\n\n> **Purpose**: This guide helps you recreate ASCII Motion's dialog design system in F"
  },
  {
    "path": "docs/FIGMA_MCP_WORKFLOW_GUIDE.md",
    "chars": 13476,
    "preview": "# Figma MCP Workflow Guide\n\n> **Quick reference for using Figma MCP tools to sync designs with code**\n\n---\n\n## 🚀 Quick S"
  },
  {
    "path": "docs/FIGMA_REACT_DIALOG_REDESIGN_MASTER_GUIDE.md",
    "chars": 16768,
    "preview": "# Figma ↔ React Dialog Redesign - Master Guide\n\n> **Complete workflow for iterating on dialog designs using Figma and sy"
  },
  {
    "path": "docs/FIGMA_WORKFLOW_IMPLEMENTATION_SUMMARY.md",
    "chars": 11745,
    "preview": "# Figma ↔ React Workflow - Implementation Summary\n\n> **Documentation package created: 2025-10-14**\n\n---\n\n## 🎯 Mission Ac"
  },
  {
    "path": "docs/FIGMA_WORKFLOW_README.md",
    "chars": 11912,
    "preview": "# Figma ↔ React Design Workflow Documentation\n\n> **Complete documentation package for redesigning ASCII Motion dialogs u"
  },
  {
    "path": "docs/FONT_QUICK_REFERENCE.md",
    "chars": 2572,
    "preview": "# Quick Reference: Adding Fonts to ASCII Motion\n\n## 5-Step Font Addition Process\n\n### 1. Add Font Files\n```\npublic/fonts"
  },
  {
    "path": "docs/FONT_SELECTION_IMPLEMENTATION_PLAN.md",
    "chars": 24238,
    "preview": "# Font Selection & Export Fix Implementation Plan\n\n**Created**: October 23, 2025  \n**Completed**: October 24, 2025  \n**S"
  },
  {
    "path": "docs/FONT_SYSTEM_IMPLEMENTATION_PLAN.md",
    "chars": 14960,
    "preview": "# Font System Implementation Plan\n\n## Project Overview\nImplement a comprehensive font selection system with manual font "
  },
  {
    "path": "docs/FRAME_SYNCHRONIZATION_DEBUGGING_GUIDE.md",
    "chars": 8056,
    "preview": "# Frame Synchronization Debugging Guide\n\n## Overview\n\nThis document captures critical learnings from debugging a complex"
  },
  {
    "path": "docs/GENERATORS_IMPLEMENTATION_PLAN.md",
    "chars": 20836,
    "preview": "# Generators System - Implementation Plan\n\n**Date:** October 27, 2025  \n**Status:** 🚧 Draft – Pending Implementation App"
  },
  {
    "path": "docs/GENERATOR_CANVAS_PREVIEW_OPTIMIZATION.md",
    "chars": 7022,
    "preview": "# Generator Canvas Preview Optimization\n\n**Date:** October 29, 2025  \n**Status:** ✅ Implemented  \n**Related:** `GENERATO"
  },
  {
    "path": "docs/GENERATOR_PREVIEW_RACE_CONDITION_FIX.md",
    "chars": 8195,
    "preview": "# Generator Preview Race Condition Fix\n\n**Date:** October 29, 2025  \n**Status:** ✅ Resolved  \n**Related:** `GENERATORS_I"
  },
  {
    "path": "docs/GIT_SUBMODULE_SETUP.md",
    "chars": 10615,
    "preview": "# Git Submodule Setup for Premium Package\n\n**Strategy:** Private GitHub repository for premium code using Git submodules"
  },
  {
    "path": "docs/GRADIENT_FILL_IMPLEMENTATION.md",
    "chars": 14285,
    "preview": "# Gradient Fill Tool - Implementation Documentation\n\n## 🎯 **Implementation Status: COMPLETE** (September 2025)\n\n### **📋 "
  },
  {
    "path": "docs/GRID_OPACITY_IMPROVEMENTS.md",
    "chars": 2626,
    "preview": "# Grid Overlay Opacity Improvements\n\n## Problem\nThe grid overlay in the ASCII Motion canvas was too harsh at 100% opacit"
  },
  {
    "path": "docs/INK_COMPONENT_EXPORT_IMPLEMENTATION_PLAN.md",
    "chars": 19451,
    "preview": "# Ink Component Export Feature - Implementation Plan\n\n**Date**: January 18, 2026  \n**Feature**: Ink (CLI) Component Expo"
  },
  {
    "path": "docs/LAYER_TIMELINE_OPTIMIZATIONS.md",
    "chars": 41036,
    "preview": "# Layer Timeline Performance Optimizations\n\n> **Created:** February 12, 2026  \n> **Status:** In Progress  \n> **Branch:**"
  },
  {
    "path": "docs/LAYER_TIMELINE_REFACTOR_PLAN.md",
    "chars": 296967,
    "preview": "# Layer Timeline System Refactor Plan\n\n> **Version:** 5.2.0  \n> **Created:** February 1, 2026  \n> **Last Updated:** Febr"
  },
  {
    "path": "docs/LOGGING_CLEANUP_SUMMARY.md",
    "chars": 5965,
    "preview": "# Logging Cleanup Summary\n\n**Date:** October 19, 2025  \n**Branch:** add-authentication  \n**Purpose:** Clean up verbose d"
  },
  {
    "path": "docs/MCP_GUIDE_RESOURCE_CODE.ts",
    "chars": 3800,
    "preview": "/**\n * MCP Resource: LLM Best Practices Guide\n * \n * This resource provides learned patterns and best practices for LLMs"
  },
  {
    "path": "docs/MCP_LLM_USAGE_GUIDE.md",
    "chars": 10035,
    "preview": "# ASCII Motion MCP - LLM Best Practices Guide\n\nThis guide documents learned patterns for effectively using the ASCII Mot"
  },
  {
    "path": "docs/MCP_SERVER_IMPLEMENTATION_PLAN.md",
    "chars": 28959,
    "preview": "# Plan: MCP Server for Ascii-Motion\n\nBuild a standalone, stdio-based MCP server (`ascii-motion-mcp`) enabling LLM-powere"
  },
  {
    "path": "docs/MEDIA_IMPORT_ANALYSIS.md",
    "chars": 20492,
    "preview": "# Media Import - Current State Analysis\n\n**Date**: October 10, 2025  \n**Status**: Bug Investigation & Feature Enhancemen"
  },
  {
    "path": "docs/MEDIA_IMPORT_FIXES_COMPLETE.md",
    "chars": 6165,
    "preview": "# Media Import Fixes - Final Implementation Summary\n\n**Date**: October 10, 2025  \n**Status**: ✅ **COMPLETE & TESTED**  \n"
  },
  {
    "path": "docs/MEDIA_IMPORT_HISTORY_INTEGRATION.md",
    "chars": 9952,
    "preview": "# Media Import History Integration - Implementation Summary\n\n**Date**: October 10, 2025  \n**Status**: ✅ **COMPLETE**  \n*"
  },
  {
    "path": "docs/MONOREPO_QUICK_REFERENCE.md",
    "chars": 4928,
    "preview": "# Monorepo Quick Reference Card\n\n**ASCII Motion Dual-License Monorepo**  \n*Keep this handy while developing!*\n\n---\n\n## 📦"
  },
  {
    "path": "docs/MONOREPO_SETUP_COMPLETE.md",
    "chars": 14239,
    "preview": "# Monorepo Setup Complete - Summary\n\n**Date:** October 12, 2025  \n**Branch:** `add-authentication`  \n**Status:** ✅ Struc"
  },
  {
    "path": "docs/MONOREPO_SETUP_GUIDE.md",
    "chars": 11682,
    "preview": "# Monorepo Structure & Dual Licensing Guide\n\nThis document explains the monorepo structure, licensing strategy, and how "
  },
  {
    "path": "docs/MULTI_FRAME_SELECTION_IMPLEMENTATION_PLAN.md",
    "chars": 33062,
    "preview": "# Multi-Frame Selection - Implementation Plan\n\n**Status**: Phases 1-4 Complete; Phases 5-7 In Progress  \n**Date**: Octob"
  },
  {
    "path": "docs/MULTI_FRAME_SELECTION_MANUAL_TEST_PLAN.md",
    "chars": 6226,
    "preview": "# Multi-Frame Selection – Manual Test Plan\n\n## 🎯 Objectives\n- Validate the stability of timeline multi-frame selection a"
  },
  {
    "path": "docs/ONION_SKINNING_GUIDE.md",
    "chars": 8280,
    "preview": "# Onion Skinning Implementation Guide\n\n## Overview\n\nThe onion skinning feature allows animators to see previous and next"
  },
  {
    "path": "docs/OPENTUI_COMPONENT_EXPORT_IMPLEMENTATION_PLAN.md",
    "chars": 9539,
    "preview": "# OpenTUI Component Export Feature - Implementation Plan\n\n**Date**: January 19, 2026  \n**Feature**: OpenTUI Component Ex"
  },
  {
    "path": "docs/OPEN_SOURCE_SECURITY_STRATEGY.md",
    "chars": 20561,
    "preview": "# Open Source + Premium Security Strategy\n\n**Date:** October 12, 2025  \n**For:** ASCII Motion Project  \n**Purpose:** Mai"
  },
  {
    "path": "docs/OS_CLIPBOARD_TESTING.md",
    "chars": 5681,
    "preview": "# OS Clipboard Integration - Testing Guide\n\n## ✅ Implementation Status\n\n### Features Implemented:\n- **OS Clipboard Integ"
  },
  {
    "path": "docs/PALETTE_REMAP_IMPLEMENTATION.md",
    "chars": 8757,
    "preview": "# Palette-Based Color Remapping Implementation\n\n## Overview\nAdded palette-based automatic color remapping to the Remap C"
  },
  {
    "path": "docs/PASTE_FUNCTIONALITY_TEST.md",
    "chars": 5018,
    "preview": "# Enhanced Paste Functionality - Test Guide\n\n## Overview\nThe enhanced paste functionality has been successfully implemen"
  },
  {
    "path": "docs/PERFORMANCE_ANALYSIS_REPORT.md",
    "chars": 12192,
    "preview": "# ASCII Motion Performance Analysis Report\n**Date:** November 18, 2025  \n**Site:** https://ascii-motion.app/  \n**Analysi"
  },
  {
    "path": "docs/PERFORMANCE_OPTIMIZATION.md",
    "chars": 8862,
    "preview": "# Performance Optimization Guide\n\n## Overview\nThis document covers two major performance optimization implementations:\n1"
  },
  {
    "path": "docs/PERFORMANCE_OPTIMIZATION_ACTION_PLAN.md",
    "chars": 11849,
    "preview": "# Performance Optimization Action Plan\n\n**Target:** Improve ASCII Motion performance by 30-50%  \n**Timeline:** 4-6 weeks"
  },
  {
    "path": "docs/PERFORMANCE_OPTIMIZATION_PHASE1.md",
    "chars": 4929,
    "preview": "# Performance Optimization Implementation Report\n\n## Phase 1 Complete: Render Batching & Throttling ✅\n\n### **Implemented"
  },
  {
    "path": "docs/PERMANENT_DELETE_RLS_FIX.md",
    "chars": 3094,
    "preview": "# Permanent Delete RLS Policy Fix\n\n## Issue\nPermanent delete functionality was not working because there was no DELETE R"
  },
  {
    "path": "docs/PERSISTENT_SELECTION_IMPLEMENTATION_PLAN.md",
    "chars": 25777,
    "preview": "# Persistent Selection System Implementation Plan\n\n## 📋 Overview\n\nThis document outlines the implementation plan for a m"
  },
  {
    "path": "docs/PHASE_4_ADVANCED_TOOLS_PLAN.md",
    "chars": 8677,
    "preview": "# Phase 4: Advanced Tools Implementation Plan\n\n## 🎯 **Phase Status: PARTIALLY COMPLETE** (Sept 24, 2025)\n\n### **📋 Phase "
  },
  {
    "path": "docs/POST_EFFECTS_DEVELOPER_GUIDE.md",
    "chars": 12311,
    "preview": "# Post Effects Developer Guide\n\n## 🎯 Adding New Post Effects to ASCII Motion\n\nThis guide explains how to create new GPU-"
  },
  {
    "path": "docs/POST_EFFECTS_USER_GUIDE.md",
    "chars": 5325,
    "preview": "# Post Effects User Guide\n\n## 🎨 What Are Post Effects?\n\nPost effects are GPU-accelerated visual effects that are applied"
  },
  {
    "path": "docs/PREMIUM_DOCS_MOVED.md",
    "chars": 5314,
    "preview": "# 🔐 Security & Premium Feature Documentation\n\n**Important:** Documentation for authentication, database, cloud storage, "
  },
  {
    "path": "docs/PRIVACY_POLICY.md",
    "chars": 12234,
    "preview": "# Privacy Policy\n\n**Last Updated:** October 12, 2025  \n**Effective Date:** October 12, 2025\n\n## 1. Introduction\n\nWelcome"
  },
  {
    "path": "docs/PROCEDURAL_EFFECTS_HANDOFF.md",
    "chars": 11918,
    "preview": "# Procedural Effects System — Session Handoff\n\n## Branch Status\n- **Branch:** `feature/procedural-effects` (all work mer"
  },
  {
    "path": "docs/PROJECT_MANAGEMENT_ENHANCEMENT_PLAN.md",
    "chars": 45045,
    "preview": "# Project Management Enhancement - Implementation Plan\n\n**Status:** 📋 Planned  \n**Last Updated:** October 16, 2025  \n**F"
  },
  {
    "path": "docs/REACT_COMPONENT_EXPORT_IMPLEMENTATION_PLAN.md",
    "chars": 9594,
    "preview": "# React Component Export Feature - Implementation Plan\n\n**Date**: October 4, 2025  \n**Feature**: React Component Export "
  },
  {
    "path": "docs/README.md",
    "chars": 13058,
    "preview": "# ASCII Motion Documentation\n\nThis directory contains comprehensive documentation for the ASCII Motion project, organize"
  },
  {
    "path": "docs/RESPONSIVE_TESTING_CHECKLIST.md",
    "chars": 5190,
    "preview": "# Responsive & Accessibility Testing Checklist\n\n## ✅ **Implemented Improvements**\n\n### **1. Enhanced Accessibility Featu"
  },
  {
    "path": "docs/SCATTER_BLEND_COLORS_FEATURE.md",
    "chars": 7915,
    "preview": "# Scatter Effect - Blend Colors Feature\n\n## Overview\nAdded a new \"Blend Colors\" option to the Scatter effect that blends"
  },
  {
    "path": "docs/SCATTER_EFFECT_FINAL_IMPLEMENTATION.md",
    "chars": 9228,
    "preview": "# Scatter Effect - Final Implementation Summary\n\n**Date**: October 10, 2025  \n**Status**: ✅ Complete and Production-Read"
  },
  {
    "path": "docs/SECURITY_HEADERS_INDEX.md",
    "chars": 7012,
    "preview": "# Security Headers Documentation Index\n\n## Quick Navigation\n\nChoose the document that matches your need:\n\n### 🚀 **I want"
  },
  {
    "path": "docs/SECURITY_REVIEW.md",
    "chars": 8732,
    "preview": "# Security Review: Open Source Documentation\n\n**Date:** October 12, 2025  \n**Reviewed By:** AI Security Audit  \n**Risk L"
  },
  {
    "path": "docs/SHARED_UI_COMPONENTS_PATTERN.md",
    "chars": 6057,
    "preview": "# Shared UI Components Pattern\n\n**Last Updated:** October 13, 2025  \n**Status:** Active Pattern\n\n---\n\n## Overview\n\nASCII"
  },
  {
    "path": "docs/SVG_EXPORT_IMPLEMENTATION_PLAN.md",
    "chars": 21504,
    "preview": "# SVG Export Feature - Implementation Plan\n\n**Date**: September 30, 2025  \n**Feature**: SVG Export for ASCII Motion Canv"
  },
  {
    "path": "docs/SVG_TEXT_TO_OUTLINES_IMPLEMENTATION_PLAN.md",
    "chars": 17914,
    "preview": "# SVG Text-to-Outlines Implementation Plan\n## Using opentype.js for True Vector Font Paths\n\n**Created**: 2025-09-30  \n**"
  },
  {
    "path": "docs/SVG_TEXT_TO_OUTLINES_IMPLEMENTATION_SUMMARY.md",
    "chars": 9013,
    "preview": "# SVG Text-to-Outlines Implementation Summary\n## OpenType.js Integration - COMPLETED ✅\n\n**Implementation Date**: 2025-09"
  },
  {
    "path": "docs/TAB_ORDER_STRATEGY.md",
    "chars": 5474,
    "preview": "# Tab Order Strategy for Accessibility\n\n## Overview\nThis document describes the tab order implementation for keyboard na"
  },
  {
    "path": "docs/TERMS_OF_SERVICE.md",
    "chars": 8213,
    "preview": "# Terms of Service\n\n**Last Updated:** October 12, 2025  \n**Effective Date:** October 12, 2025\n\n## 1. Acceptance of Terms"
  },
  {
    "path": "docs/TIME_EFFECTS_IMPLEMENTATION_PLAN.md",
    "chars": 29419,
    "preview": "# Time-Based Effects System - Implementation Plan\n\n**Status**: Planning Phase  \n**Date**: October 1, 2025  \n**Feature**:"
  },
  {
    "path": "docs/TOOL_BEHAVIOR_IMPLEMENTATION.md",
    "chars": 3845,
    "preview": "# Tool Behavior Settings - Implementation Summary\n\n## Overview\nAdded toggle options for all drawing tools and the eyedro"
  },
  {
    "path": "docs/TYPOGRAPHY_IMPLEMENTATION.md",
    "chars": 8622,
    "preview": "# Typography System Implementation Summary\n\n**Implementation Date**: September 6, 2025  \n**Feature Status**: ✅ **COMPLET"
  },
  {
    "path": "docs/UI_COMPONENTS_DESIGN_SYSTEM.md",
    "chars": 12124,
    "preview": "# UI Components & Design System\n\nThis document outlines the standardized UI components and design patterns used in ASCII"
  },
  {
    "path": "docs/UNDO_REDO_BUG_FIXES.md",
    "chars": 17934,
    "preview": "# Undo/Redo Bug Fixes - Cross-Frame Operations\n\n## Date\nOctober 11, 2025\n\n## CRITICAL UPDATE - Frame Auto-Save Interfere"
  },
  {
    "path": "docs/VERCEL_JSON_REFERENCE.md",
    "chars": 3813,
    "preview": "# vercel.json Configuration Reference\n\n## Overview\nThis file configures Vercel deployment settings, security headers, an"
  },
  {
    "path": "docs/WIDTH_HEIGHT_INPUT_FIX.md",
    "chars": 5244,
    "preview": "# Width/Height Input Sanitization Fix\n\n## Problem\n\nThe width and height input fields in the Media Import Panel had a use"
  },
  {
    "path": "docs/timanthes.txt",
    "chars": 1722,
    "preview": "; Paint.NET Palette File\n; Lines that start with a semicolon are comments\n; Colors are written as 8-digit hexadecimal nu"
  },
  {
    "path": "eslint.config.js",
    "chars": 1002,
    "preview": "import js from '@eslint/js'\nimport globals from 'globals'\nimport reactHooks from 'eslint-plugin-react-hooks'\nimport reac"
  },
  {
    "path": "index.html",
    "chars": 7989,
    "preview": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <!-- Favicon and Web App Icons -->\n    <link "
  },
  {
    "path": "package.json",
    "chars": 4766,
    "preview": "{\n  \"name\": \"ascii-motion\",\n  \"private\": true,\n  \"version\": \"2.1.3\",\n  \"type\": \"module\",\n  \"workspaces\": [\n    \"packages"
  },
  {
    "path": "packages/core/package.json",
    "chars": 1653,
    "preview": "{\n  \"name\": \"@ascii-motion/core\",\n  \"version\": \"0.1.45\",\n  \"type\": \"module\",\n  \"license\": \"MIT\",\n  \"description\": \"ASCII"
  },
  {
    "path": "packages/core/src/components/index.ts",
    "chars": 1079,
    "preview": "/**\n * ASCII Motion - Core Package\n * UI Components Barrel Export\n * \n * Shared shadcn/ui components used by both main a"
  },
  {
    "path": "packages/core/src/components/ui/alert.tsx",
    "chars": 1615,
    "preview": "import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/"
  },
  {
    "path": "packages/core/src/components/ui/badge.tsx",
    "chars": 1125,
    "preview": "import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/"
  },
  {
    "path": "packages/core/src/components/ui/button.tsx",
    "chars": 1886,
    "preview": "import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class"
  },
  {
    "path": "packages/core/src/components/ui/card.tsx",
    "chars": 1845,
    "preview": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Card = React.forwardRef<\n  HTMLDivElement,\n  Rea"
  },
  {
    "path": "packages/core/src/components/ui/checkbox.tsx",
    "chars": 1012,
    "preview": "import * as React from \"react\"\nimport * as CheckboxPrimitive from \"@radix-ui/react-checkbox\"\nimport { Check } from \"luci"
  },
  {
    "path": "packages/core/src/components/ui/collapsible.tsx",
    "chars": 315,
    "preview": "import * as CollapsiblePrimitive from \"@radix-ui/react-collapsible\"\n\nconst Collapsible = CollapsiblePrimitive.Root\n\ncons"
  },
  {
    "path": "packages/core/src/components/ui/dialog.tsx",
    "chars": 4062,
    "preview": "import * as React from \"react\"\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\"\nimport { VisuallyHidden } from "
  },
  {
    "path": "packages/core/src/components/ui/dropdown-menu.tsx",
    "chars": 7616,
    "preview": "\"use client\"\n\nimport * as React from \"react\"\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\"\nimpo"
  },
  {
    "path": "packages/core/src/components/ui/input.tsx",
    "chars": 768,
    "preview": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Input = React.forwardRef<HTMLInputElement, React"
  },
  {
    "path": "packages/core/src/components/ui/label.tsx",
    "chars": 710,
    "preview": "import * as React from \"react\"\nimport * as LabelPrimitive from \"@radix-ui/react-label\"\nimport { cva, type VariantProps }"
  },
  {
    "path": "packages/core/src/components/ui/menubar.tsx",
    "chars": 8608,
    "preview": "import * as React from \"react\"\nimport * as MenubarPrimitive from \"@radix-ui/react-menubar\"\nimport { Check, ChevronRight,"
  },
  {
    "path": "packages/core/src/components/ui/popover.tsx",
    "chars": 1361,
    "preview": "\"use client\"\n\nimport * as React from \"react\"\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\"\n\nimport { cn } "
  },
  {
    "path": "packages/core/src/components/ui/progress.tsx",
    "chars": 792,
    "preview": "\"use client\"\n\nimport * as React from \"react\"\nimport * as ProgressPrimitive from \"@radix-ui/react-progress\"\n\nimport { cn "
  },
  {
    "path": "packages/core/src/components/ui/scroll-area.tsx",
    "chars": 1642,
    "preview": "import * as React from \"react\"\nimport * as ScrollAreaPrimitive from \"@radix-ui/react-scroll-area\"\n\nimport { cn } from \"@"
  },
  {
    "path": "packages/core/src/components/ui/select.tsx",
    "chars": 5752,
    "preview": "import * as React from \"react\"\nimport * as SelectPrimitive from \"@radix-ui/react-select\"\nimport { Check, ChevronDown, Ch"
  },
  {
    "path": "packages/core/src/components/ui/separator.tsx",
    "chars": 770,
    "preview": "\"use client\"\n\nimport * as React from \"react\"\nimport * as SeparatorPrimitive from \"@radix-ui/react-separator\"\n\nimport { c"
  },
  {
    "path": "packages/core/src/components/ui/sheet.tsx",
    "chars": 4280,
    "preview": "\"use client\"\n\nimport * as React from \"react\"\nimport * as SheetPrimitive from \"@radix-ui/react-dialog\"\nimport { cva, type"
  },
  {
    "path": "packages/core/src/components/ui/skeleton.tsx",
    "chars": 261,
    "preview": "import { cn } from \"@/lib/utils\"\n\nfunction Skeleton({\n  className,\n  ...props\n}: React.HTMLAttributes<HTMLDivElement>) {"
  },
  {
    "path": "packages/core/src/components/ui/slider.tsx",
    "chars": 2268,
    "preview": "import React from 'react';\nimport { cn } from '@/lib/utils';\n\nexport interface SliderProps extends Omit<React.InputHTMLA"
  },
  {
    "path": "packages/core/src/components/ui/switch.tsx",
    "chars": 1148,
    "preview": "import * as React from \"react\"\nimport * as SwitchPrimitives from \"@radix-ui/react-switch\"\n\nimport { cn } from \"@/lib/uti"
  },
  {
    "path": "packages/core/src/components/ui/tabs.tsx",
    "chars": 1877,
    "preview": "import * as React from \"react\"\nimport * as TabsPrimitive from \"@radix-ui/react-tabs\"\n\nimport { cn } from \"@/lib/utils\"\n\n"
  },
  {
    "path": "packages/core/src/components/ui/textarea.tsx",
    "chars": 660,
    "preview": "import * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst Textarea = React.forwardRef<\n  HTMLTextAreaEle"
  },
  {
    "path": "packages/core/src/components/ui/toggle.tsx",
    "chars": 1470,
    "preview": "import * as React from \"react\"\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\"\nimport { cva, type VariantProps"
  },
  {
    "path": "packages/core/src/components/ui/tooltip.tsx",
    "chars": 1751,
    "preview": "import * as React from \"react\"\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\"\n\nimport { cn } from \"@/lib/ut"
  },
  {
    "path": "packages/core/src/index.ts",
    "chars": 330,
    "preview": "/**\n * ASCII Motion - Core Package\n * \n * Shared UI component library for ASCII Motion\n * Used by both main app and prem"
  },
  {
    "path": "packages/core/src/lib/utils.ts",
    "chars": 247,
    "preview": "/**\n * ASCII Motion - Core Package\n * Utility Functions\n * \n * @license MIT\n */\n\nimport { clsx, type ClassValue } from \""
  },
  {
    "path": "packages/core/tsconfig.json",
    "chars": 855,
    "preview": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"useDefineForClassFields\": true,\n    \"lib\": [\"ES2020\", \"DOM\", \"DOM."
  },
  {
    "path": "postcss.config.js",
    "chars": 80,
    "preview": "export default {\n  plugins: {\n    tailwindcss: {},\n    autoprefixer: {},\n  },\n}\n"
  }
]

// ... and 453 more files (download for full content)

About this extraction

This page contains the full source code of the CameronFoxly/Ascii-Motion GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 653 files (45.2 MB), approximately 3.8M tokens, and a symbol index with 1941 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!