tinazone commited on
Commit
21d7fc3
·
verified ·
1 Parent(s): b1711cd

Upload 44 files

Browse files
.gitattributes CHANGED
@@ -34,3 +34,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  huggingface-word-to-code/public/fonts/GoogleSans-Bold.ttf filter=lfs diff=lfs merge=lfs -text
 
 
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  huggingface-word-to-code/public/fonts/GoogleSans-Bold.ttf filter=lfs diff=lfs merge=lfs -text
37
+ public/fonts/GoogleSans-Bold.ttf filter=lfs diff=lfs merge=lfs -text
Dockerfile ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:18-alpine AS base
2
+
3
+ # Install dependencies only when needed
4
+ FROM base AS deps
5
+ RUN apk add --no-cache libc6-compat
6
+ WORKDIR /app
7
+
8
+ # Install dependencies based on the preferred package manager
9
+ COPY package.json package-lock.json* ./
10
+ RUN npm ci
11
+
12
+ # Rebuild the source code only when needed
13
+ FROM base AS builder
14
+ WORKDIR /app
15
+ COPY --from=deps /app/node_modules ./node_modules
16
+ COPY . .
17
+
18
+ # Next.js collects completely anonymous telemetry data about general usage.
19
+ # Learn more here: https://nextjs.org/telemetry
20
+ # Uncomment the following line in case you want to disable telemetry during the build.
21
+ ENV NEXT_TELEMETRY_DISABLED 1
22
+
23
+ # Create .env.local if environment variables are provided
24
+ RUN touch .env.local
25
+ RUN if [ -n "$GEMINI_API_KEY" ]; then \
26
+ echo "GEMINI_API_KEY=$GEMINI_API_KEY" >> .env.local; \
27
+ fi
28
+
29
+ RUN npm run build
30
+
31
+ # Production image, copy all the files and run next
32
+ FROM base AS runner
33
+ WORKDIR /app
34
+
35
+ ENV NODE_ENV production
36
+ ENV NEXT_TELEMETRY_DISABLED 1
37
+
38
+ RUN addgroup --system --gid 1001 nodejs
39
+ RUN adduser --system --uid 1001 nextjs
40
+
41
+ COPY --from=builder /app/public ./public
42
+ COPY --from=builder /app/.env.local ./.env.local
43
+
44
+ # Set the correct permission for prerender cache
45
+ RUN mkdir .next
46
+ RUN chown nextjs:nodejs .next
47
+
48
+ # Automatically leverage output traces to reduce image size
49
+ COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
50
+ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
51
+
52
+ USER nextjs
53
+
54
+ EXPOSE 3000
55
+
56
+ ENV PORT 3000
57
+ ENV HOSTNAME "0.0.0.0"
58
+
59
+ CMD ["node", "server.js"]
README.md CHANGED
@@ -1,10 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
- title: Word To Code
3
- emoji: 🏆
4
- colorFrom: purple
5
- colorTo: pink
6
  sdk: docker
7
  pinned: false
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Word to Code
2
+
3
+ [![Hugging Face Spaces](https://img.shields.io/badge/%F0%9F%A4%97%20Hugging%20Face-Spaces-blue)](https://huggingface.co/spaces/tinazone/word-to-code)
4
+
5
+ This is a [Next.js](https://nextjs.org) project that transforms natural language descriptions into visual code sketches.
6
+
7
+ ## 🤗 HuggingFace Space Setup
8
+
9
+ 1. Clone the repository:
10
+ ```bash
11
+ git clone https://huggingface.co/spaces/tinazone/word-to-code
12
+ cd word-to-code
13
+ ```
14
+
15
+ 2. Set up your environment variables:
16
+ - Go to your HuggingFace Space's Settings tab
17
+ - Under "Repository Secrets", add a new secret:
18
+ - Name: `GEMINI_API_KEY`
19
+ - Value: Your Gemini API key from https://ai.google.dev/
20
+ - The secret will be securely passed to the container at runtime
21
+
22
+ 3. Make your changes and push them back:
23
+ ```bash
24
+ git add .
25
+ git commit -m "Update space"
26
+ git push
27
+ ```
28
+
29
+ Note: When pushing, use a HuggingFace access token with write permissions as your password. Generate one from: https://huggingface.co/settings/tokens
30
+
31
+ ## 🎨 Space Configuration
32
+
33
  ---
34
+ title: Word to Code - Visual Code Sketch Generator
35
+ emoji: 🎨
36
+ colorFrom: blue
37
+ colorTo: purple
38
  sdk: docker
39
  pinned: false
40
+ app_port: 3000
41
  ---
42
 
43
+ ## Local Development
44
+
45
+ 1. Create a `.env.local` file in the root directory:
46
+ ```bash
47
+ GEMINI_API_KEY=your_api_key_here
48
+ ```
49
+
50
+ 2. Install dependencies:
51
+ ```bash
52
+ npm install
53
+ ```
54
+
55
+ 3. Run the development server:
56
+ ```bash
57
+ npm run dev
58
+ ```
59
+
60
+ Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
61
+
62
+ ## Features
63
+
64
+ - Transform natural language descriptions into visual code sketches
65
+ - Download sketches as GIF animations
66
+ - Real-time code generation and visualization
67
+ - Modern, responsive UI
68
+
69
+ ## Technical Stack
70
+
71
+ - Next.js 14
72
+ - React 18
73
+ - Tailwind CSS
74
+ - P5.js for sketching
75
+ - FFmpeg for GIF generation
76
+ - Gemini 2.0 for code generation
77
+
78
+ You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
79
+
80
+ [API routes](https://nextjs.org/docs/pages/building-your-application/routing/api-routes) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
81
+
82
+ The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/pages/building-your-application/routing/api-routes) instead of React pages.
83
+
84
+ This project uses [`next/font`](https://nextjs.org/docs/pages/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
85
+
86
+ ## Learn More
87
+
88
+ To learn more about Next.js, take a look at the following resources:
89
+
90
+ - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
91
+ - [Learn Next.js](https://nextjs.org/learn-pages-router) - an interactive Next.js tutorial.
92
+
93
+ You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
94
+
95
+ ## Deploy on Vercel
96
+
97
+ The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
98
+
99
+ Check out our [Next.js deployment documentation](https://nextjs.org/docs/pages/building-your-application/deploying) for more details.
app.yaml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ service: word-to-code
2
+ env: standard
3
+ runtime: nodejs18
4
+
5
+ handlers:
6
+ - url: /.*
7
+ script: auto
8
+ secure: always
components/CodePanel.js ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import CopyCodeButton from './CopyCodeButton';
2
+
3
+ export default function CodePanel({ modelResponse, generatedCode }) {
4
+ return (
5
+ <div
6
+ className="w-full max-w-[500px] lg:max-w-none lg:w-[500px] bg-gray-100 p-4 rounded-[26px] overflow-auto opacity-0 animate-fadeIn relative"
7
+ style={{
8
+ height: 'min(calc(782px), 90vh)',
9
+ animation: 'fadeIn 0.5s ease-in-out forwards'
10
+ }}
11
+ >
12
+ <pre
13
+ className="text-sm whitespace-pre-wrap break-words font-mono h-full"
14
+ style={{
15
+ fontFamily: 'Menlo, Monaco, Consolas, monospace',
16
+ padding: '16px',
17
+ overflowY: 'auto'
18
+ }}
19
+ >
20
+ {modelResponse && (
21
+ <>
22
+ <span className="font-semibold">Model Reasoning:</span>
23
+ {'\n' + modelResponse + '\n\n\n'}
24
+ </>
25
+ )}
26
+ <span className="font-semibold">Code:</span>
27
+ {'\n' + generatedCode}
28
+ </pre>
29
+ <CopyCodeButton code={generatedCode} />
30
+ </div>
31
+ );
32
+ }
components/CopyCodeButton.js ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useState } from 'react';
2
+
3
+ export default function CopyCodeButton({ code }) {
4
+ const [isCopied, setIsCopied] = useState(false);
5
+
6
+ const handleCopyCode = async () => {
7
+ try {
8
+ // Replace local font with web-hosted OpenType font and adjust text positioning
9
+ const modifiedCode = code
10
+ .replace(
11
+ /loadFont\(['"](?:\/)?fonts\/GoogleSans-Bold\.ttf['"]\)/,
12
+ "loadFont('https://cdn.jsdelivr.net/npm/@fontsource/[email protected]/files/roboto-latin-700-normal.woff')"
13
+ )
14
+ .replace(
15
+ /points = font\.textToPoints\(word, width\/2 - textW\/2, height\/2 \+ fontSize\/3, fontSize,/,
16
+ "points = font.textToPoints(word, (width + textW) / 3.5, (height - fontSize) / 1.75, fontSize,"
17
+ );
18
+
19
+ await navigator.clipboard.writeText(modifiedCode);
20
+ setIsCopied(true);
21
+ setTimeout(() => setIsCopied(false), 2000);
22
+ } catch (err) {
23
+ console.error('Failed to copy code:', err);
24
+ }
25
+ };
26
+
27
+ return (
28
+ <button
29
+ onClick={handleCopyCode}
30
+ className="sticky bottom-4 flex items-center gap-2 px-3 py-2 bg-white rounded-xl shadow-sm hover:bg-gray-50 transition-colors"
31
+ style={{
32
+ position: 'sticky',
33
+ bottom: '0rem',
34
+ float: 'right',
35
+ marginRight: '0rem',
36
+ zIndex: 10
37
+ }}
38
+ >
39
+ <svg
40
+ width="16"
41
+ height="16"
42
+ viewBox="0 0 24 24"
43
+ fill="none"
44
+ stroke="currentColor"
45
+ strokeWidth="2"
46
+ strokeLinecap="round"
47
+ strokeLinejoin="round"
48
+ >
49
+ <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
50
+ <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
51
+ </svg>
52
+ <span className="text-sm">{isCopied ? 'Copied!' : 'Copy Code'}</span>
53
+ </button>
54
+ );
55
+ }
components/ExampleChip.js ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export default function ExampleChip({ label, onClick, active }) {
2
+ return (
3
+ <button
4
+ onClick={onClick}
5
+ className={`px-4 py-1.5 rounded-full text-sm transition-colors ${
6
+ active
7
+ ? 'bg-black text-white'
8
+ : 'bg-transparent text-black border border-gray-200 hover:border-gray-400'
9
+ }`}
10
+ >
11
+ {label}
12
+ </button>
13
+ );
14
+ }
components/GenerationForm.js ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import Image from 'next/image';
2
+ import ExampleChip from './ExampleChip';
3
+ import SystemPrompt from './SystemPrompt';
4
+ import { examples } from '../sketches';
5
+
6
+ export default function GenerationForm({
7
+ word,
8
+ setWord,
9
+ instructions,
10
+ setInstructions,
11
+ isGenerating,
12
+ showSystemPrompt,
13
+ setShowSystemPrompt,
14
+ showExamples,
15
+ setShowExamples,
16
+ activeExample,
17
+ handleExampleClick,
18
+ onSubmit
19
+ }) {
20
+ return (
21
+ <div className="w-full max-w-[500px]">
22
+ <button
23
+ onClick={() => setShowExamples(!showExamples)}
24
+ className="flex items-center mt-4 gap-2 text-sm text-black hover:text-black"
25
+ >
26
+ <svg
27
+ className={`w-4 h-4 transition-transform ${showExamples ? 'rotate-180' : ''}`}
28
+ fill="none"
29
+ stroke="currentColor"
30
+ viewBox="0 0 24 24"
31
+ >
32
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
33
+ </svg>
34
+ See examples we used to teach the model
35
+ </button>
36
+
37
+ {showExamples && (
38
+ <div className="flex gap-2 flex-wrap mt-4">
39
+ {Object.keys(examples).map((example) => (
40
+ <ExampleChip
41
+ key={example}
42
+ label={example}
43
+ onClick={() => handleExampleClick(example)}
44
+ active={activeExample === example}
45
+ />
46
+ ))}
47
+ </div>
48
+ )}
49
+
50
+ {showSystemPrompt && (
51
+ <SystemPrompt onExampleClick={handleExampleClick} />
52
+ )}
53
+
54
+ <form onSubmit={onSubmit} className="w-full max-w-[500px] flex flex-col gap-4 items-center mt-4">
55
+ <div className="relative w-full">
56
+ <input
57
+ type="text"
58
+ value={word}
59
+ onChange={(e) => setWord(e.target.value)}
60
+ placeholder='Type a word like "float" ...'
61
+ className="w-full p-3 sm:p-4 bg-transparent border-[1.5px] border-gray-200 rounded-[26px] text-black placeholder-gray-400 focus:outline-none focus:border-black text-xs sm:text-base"
62
+ />
63
+ <button
64
+ type="button"
65
+ className={`group absolute right-4 top-1/2 -translate-y-1/2 text-gray-400 hover:text-black transition-colors p-1.5 rounded-full ${showSystemPrompt ? 'bg-gray-200' : 'hover:bg-gray-100'} active:bg-gray-200`}
66
+ onClick={() => setShowSystemPrompt(!showSystemPrompt)}
67
+ >
68
+ <Image
69
+ src="/info_spark.png"
70
+ alt="show system prompt"
71
+ width={20}
72
+ height={20}
73
+ className="opacity-100"
74
+ priority={false}
75
+ />
76
+ <div className="absolute bottom-full mb-1 right-0 scale-0 transition-all rounded bg-gray-100 p-2 text-xs text-black group-hover:scale-100 whitespace-nowrap">
77
+ {showSystemPrompt ? 'Hide' : 'Show'} system prompt
78
+ </div>
79
+ </button>
80
+ </div>
81
+
82
+ <textarea
83
+ value={instructions}
84
+ onChange={(e) => setInstructions(e.target.value)}
85
+ placeholder="Optional: add additional instructions for your animation."
86
+ rows={1}
87
+ className="w-full p-3 sm:p-4 bg-transparent border-[1.5px] border-gray-200 resize-none rounded-[26px] text-black placeholder-gray-400 focus:outline-none focus:border-black text-xs sm:text-base"
88
+ style={{
89
+ height: 'auto',
90
+ }}
91
+ onInput={(e) => {
92
+ e.target.style.height = 'auto';
93
+ e.target.style.height = Math.min(e.target.scrollHeight, 120) + 'px';
94
+ }}
95
+ />
96
+
97
+ <button
98
+ type="submit"
99
+ disabled={isGenerating || !word.trim()}
100
+ className={`w-44 py-3 rounded-[32px] font-medium transition-colors ${
101
+ isGenerating
102
+ ? 'bg-[#EEEEEE] text-black'
103
+ : !word.trim()
104
+ ? 'bg-gray-100 text-gray-400'
105
+ : 'bg-black text-white hover:bg-gray-900'
106
+ }`}
107
+ >
108
+ {isGenerating ? 'Generating...' : 'Generate'}
109
+ </button>
110
+ </form>
111
+ </div>
112
+ );
113
+ }
components/GifDownloadButton.js ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState } from 'react';
2
+
3
+ export default function GifDownloadButton({ onClick, title, isCapturing }) {
4
+ return (
5
+ <button
6
+ onClick={onClick}
7
+ className="absolute bottom-4 right-14 p-2 bg-black hover:bg-white/20 rounded-full transition-colors group"
8
+ title={title}
9
+ disabled={isCapturing}
10
+ >
11
+ <div className="relative">
12
+ <svg
13
+ className={`w-5 h-5 text-white ${isCapturing ? 'opacity-50' : ''}`}
14
+ fill="none"
15
+ stroke="currentColor"
16
+ viewBox="0 0 24 24"
17
+ >
18
+ <path
19
+ strokeLinecap="round"
20
+ strokeLinejoin="round"
21
+ strokeWidth={2}
22
+ d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"
23
+ />
24
+ </svg>
25
+ {isCapturing && (
26
+ <div className="absolute inset-0 flex items-center justify-center">
27
+ <div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin"></div>
28
+ </div>
29
+ )}
30
+ </div>
31
+ <div className="absolute bottom-full mb-1 right-0 scale-0 transition-all rounded bg-white/20 p-2 text-xs text-white group-hover:scale-100 whitespace-nowrap pointer-events-none">
32
+ {isCapturing ? 'Capturing GIF...' : title}
33
+ </div>
34
+ </button>
35
+ );
36
+ }
components/Header.js ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+ import { Github } from 'lucide-react';
3
+
4
+ const Header = () => {
5
+ return (
6
+ <div className="fixed top-0 left-0 right-0 w-full bg-white p-4 z-50">
7
+ <div className="w-full flex justify-between items-center text-base">
8
+ <div className="text-gray-500">
9
+ <span className="text-black font-bold text-lg mr-2">Word to Code</span>
10
+ Built with <a
11
+ href="https://ai.google.dev"
12
+ target="_blank"
13
+ rel="noopener noreferrer"
14
+ className="underline hover:text-gray-800 transition-colors"
15
+ >
16
+ Gemini 2.0
17
+ </a>
18
+ </div>
19
+
20
+ <div className="flex items-center gap-3">
21
+ <a
22
+ href="https://github.com/googlecreativelab/gemini-demos/tree/main/word-to-code"
23
+ target="_blank"
24
+ rel="noopener noreferrer"
25
+ className="flex items-center gap-2 text-sm font-medium text-gray-700 hover:text-gray-900 transition-colors"
26
+ >
27
+ <Github size={18} className="text-gray-600" />
28
+ <span>GitHub Repository</span>
29
+ </a>
30
+ </div>
31
+ </div>
32
+ </div>
33
+ );
34
+ };
35
+
36
+ export default Header;
components/ReplayButton.js ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+
3
+ const ReplayButton = ({ onClick }) => {
4
+ return (
5
+ <button
6
+ onClick={onClick}
7
+ className="group absolute bottom-4 right-4 w-8 h-8 rounded-full flex items-center justify-center transition-all hover:bg-white/20"
8
+ >
9
+ <svg
10
+ width="16"
11
+ height="16"
12
+ viewBox="0 0 24 24"
13
+ fill="none"
14
+ stroke="white"
15
+ strokeWidth="2"
16
+ strokeLinecap="round"
17
+ strokeLinejoin="round"
18
+ >
19
+ <path d="M1 4v6h6" />
20
+ <path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10" />
21
+ </svg>
22
+ <div className="absolute bottom-10 right-0 scale-0 transition-all rounded bg-white/20 p-2 text-xs text-white group-hover:scale-100 whitespace-nowrap">
23
+ Replay animation
24
+ </div>
25
+ </button>
26
+ );
27
+ };
28
+
29
+ export default ReplayButton;
components/SketchRenderer.js ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useEffect, useRef } from 'react';
2
+ import ReplayButton from './ReplayButton';
3
+ import GifDownloadButton from './GifDownloadButton';
4
+ import { loadingSketch } from '../sketches';
5
+
6
+ export default function SketchRenderer({
7
+ generatedCode,
8
+ isGenerating,
9
+ error,
10
+ showCodePanel,
11
+ onReplay,
12
+ onGifCapture,
13
+ isCapturingGif,
14
+ isInitialSketch
15
+ }) {
16
+ const sketchContainer = useRef(null);
17
+ const currentSketch = useRef(null);
18
+
19
+ useEffect(() => {
20
+ // Add message listener for GIF capture completion
21
+ const handleGifComplete = (event) => {
22
+ if (event.data.type === 'gifCaptureComplete') {
23
+ onGifCapture(false); // Signal completion
24
+ }
25
+ };
26
+ window.addEventListener('message', handleGifComplete);
27
+
28
+ return () => {
29
+ window.removeEventListener('message', handleGifComplete);
30
+ };
31
+ }, [onGifCapture]);
32
+
33
+ useEffect(() => {
34
+ if (generatedCode && window.p5 && sketchContainer.current) {
35
+ // Cleanup previous sketch if it exists
36
+ const cleanup = () => {
37
+ if (currentSketch.current) {
38
+ currentSketch.current.remove();
39
+ currentSketch.current = null;
40
+ }
41
+ };
42
+
43
+ cleanup();
44
+
45
+ try {
46
+ const formattedCodeResponse = `
47
+ <!DOCTYPE html>
48
+ <html lang="en">
49
+ <head>
50
+ <meta charset="UTF-8">
51
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
52
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.0/p5.js"></script>
53
+ <title>p5.js Sketch</title>
54
+ <style>
55
+ body {
56
+ padding: 0;
57
+ margin: 0;
58
+ display: flex;
59
+ justify-content: center;
60
+ align-items: center;
61
+ min-height: 100vh;
62
+ overflow: hidden;
63
+ background: black;
64
+ }
65
+ canvas {
66
+ max-width: 100% !important;
67
+ height: auto !important;
68
+ }
69
+ </style>
70
+ </head>
71
+ <body>
72
+ <script>
73
+ try {
74
+ ${isGenerating ? loadingSketch : generatedCode}
75
+
76
+ // Add setup wrapper
77
+ if (typeof window.setup === 'function') {
78
+ const originalSetup = window.setup;
79
+ window.setup = function() {
80
+ originalSetup();
81
+ frameRate(30); // Set consistent frame rate for GIF
82
+ };
83
+ }
84
+
85
+ // Add draw wrapper
86
+ if (typeof window.draw === 'function') {
87
+ const originalDraw = window.draw;
88
+ window.draw = function() {
89
+ originalDraw();
90
+ };
91
+ }
92
+
93
+ // Handle GIF capture message
94
+ window.addEventListener('message', function(event) {
95
+ if (event.data.type === 'startGifCapture') {
96
+ saveGif('word-to-code-animation', 5, { silent: true })
97
+ .then(() => {
98
+ window.parent.postMessage({ type: 'gifCaptureComplete' }, '*');
99
+ });
100
+ }
101
+ });
102
+
103
+ new p5();
104
+ } catch (error) {
105
+ console.error('Sketch error:', error);
106
+ document.body.innerHTML = '<div style="color: red; padding: 20px;"><h3>🔴 Error:</h3><pre>' + error.message + '</pre></div>';
107
+ }
108
+ </script>
109
+ </body>
110
+ </html>
111
+ `;
112
+
113
+ const iframe = document.createElement('iframe');
114
+ iframe.srcdoc = formattedCodeResponse;
115
+ iframe.style.width = '100%';
116
+ iframe.style.height = '100%';
117
+ iframe.style.border = 'none';
118
+ iframe.id = 'sketch-iframe';
119
+
120
+ iframe.onload = () => {
121
+ iframe.contentWindow.addEventListener('error', (e) => {
122
+ if (e.message.includes('Receiving end does not exist') ||
123
+ e.message.includes('p5.js seems to have been imported multiple times')) {
124
+ e.preventDefault();
125
+ }
126
+ });
127
+ };
128
+
129
+ sketchContainer.current.innerHTML = '';
130
+ sketchContainer.current.appendChild(iframe);
131
+
132
+ } catch (error) {
133
+ console.error('Error running p5.js sketch:', error);
134
+ setError('Error running the animation: ' + error.message);
135
+ }
136
+ }
137
+
138
+ return () => {
139
+ if (sketchContainer.current) {
140
+ sketchContainer.current.innerHTML = '';
141
+ }
142
+ };
143
+ }, [generatedCode, isGenerating]);
144
+
145
+ return (
146
+ <div className="w-full aspect-square bg-black rounded-3xl flex items-center justify-center overflow-hidden relative">
147
+ <div ref={sketchContainer} className="w-full h-full" />
148
+ {isInitialSketch && !error && !isGenerating && (
149
+ <div className="absolute inset-0 flex items-end justify-center pb-5 text-gray-300 pointer-events-none z-10">
150
+ Type a word below to get started
151
+ </div>
152
+ )}
153
+ {error && (
154
+ <div className="w-full h-full flex items-center justify-center text-red-500 p-4 text-center">
155
+ {error}
156
+ </div>
157
+ )}
158
+ {showCodePanel && !error && (
159
+ <>
160
+ <ReplayButton onClick={onReplay} title="Replay animation" />
161
+ <GifDownloadButton
162
+ onClick={() => onGifCapture(true)}
163
+ title="Download as GIF"
164
+ isCapturing={isCapturingGif}
165
+ />
166
+ </>
167
+ )}
168
+ </div>
169
+ );
170
+ }
components/SystemPrompt.js ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export default function SystemPrompt({ onExampleClick }) {
2
+ return (
3
+ <div className="w-full max-w-[500px] bg-gray-100 rounded-[26px] p-6 my-6">
4
+ <div className="font-mono text-xs sm:text-sm">
5
+ <div className="mb-4">System Prompt:</div>
6
+ <div
7
+ className="max-h-[60vh] sm:max-h-[200px] overflow-y-auto pr-4 space-y-4"
8
+ style={{ fontFamily: 'Menlo, Monaco, Consolas, monospace' }}
9
+ >
10
+ <p>
11
+ You are a creative coding expert specializing in p5.js animations. Given a single word, you create expressive looping animations that bring that word to life using particle systems.
12
+ </p>
13
+
14
+ <p>
15
+ Here are five examples of animations:
16
+ </p>
17
+
18
+ <div className="flex flex-wrap gap-2 py-2">
19
+ <button onClick={() => onExampleClick('fluid')} className="text-blue-600 hover:text-blue-800">fluid, </button>
20
+ <button onClick={() => onExampleClick('rise')} className="text-blue-600 hover:text-blue-800">rise, </button>
21
+ <button onClick={() => onExampleClick('light')} className="text-blue-600 hover:text-blue-800">light, </button>
22
+ <button onClick={() => onExampleClick('travel')} className="text-blue-600 hover:text-blue-800">travel, </button>
23
+ <button onClick={() => onExampleClick('bounce')} className="text-blue-600 hover:text-blue-800">bounce</button>
24
+ </div>
25
+
26
+ <p>
27
+ Your task is to generate a p5.js sketch that creates an animation representing the given word. The animation should:
28
+ </p>
29
+
30
+ <div className="pl-6 space-y-2">
31
+ <p>1. Use particle systems for dynamic movement</p>
32
+ <p>2. Create a seamless loop</p>
33
+ <p>3. Be visually engaging and creative</p>
34
+ <p>4. Capture the essence or meaning of the word</p>
35
+ <p>5. Use colors and effects that enhance the visualization</p>
36
+ </div>
37
+
38
+ <p>
39
+ The sketch should be self-contained and include all necessary setup, draw, and helper functions.
40
+ </p>
41
+ </div>
42
+ </div>
43
+ </div>
44
+ );
45
+ }
jsconfig.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "paths": {
4
+ "@/*": ["./*"]
5
+ }
6
+ }
7
+ }
next.config.mjs ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ reactStrictMode: true,
4
+ images: {
5
+ domains: ['localhost'],
6
+ },
7
+ webpack: (config) => {
8
+ config.module.rules.push({
9
+ test: /\.(woff|woff2|eot|ttf|otf)$/,
10
+ use: {
11
+ loader: 'file-loader',
12
+ options: {
13
+ name: '[name].[ext]',
14
+ publicPath: '/_next/static/fonts/',
15
+ outputPath: 'static/fonts/',
16
+ },
17
+ },
18
+ });
19
+ return config;
20
+ },
21
+ };
22
+
23
+ export default nextConfig;
package-lock.json ADDED
@@ -0,0 +1,2405 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "word-to-code",
3
+ "version": "0.1.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "word-to-code",
9
+ "version": "0.1.0",
10
+ "dependencies": {
11
+ "@ffmpeg/ffmpeg": "^0.12.15",
12
+ "@ffmpeg/util": "^0.12.2",
13
+ "@google/generative-ai": "^0.21.0",
14
+ "gif.js": "^0.2.0",
15
+ "lucide-react": "^0.330.0",
16
+ "next": "14.1.0",
17
+ "p5": "^1.9.0",
18
+ "react": "^18",
19
+ "react-dom": "^18",
20
+ "react-hot-toast": "^2.5.2",
21
+ "react-syntax-highlighter": "^15.5.0"
22
+ },
23
+ "devDependencies": {
24
+ "autoprefixer": "^10.0.1",
25
+ "postcss": "^8",
26
+ "tailwindcss": "^3.3.0"
27
+ }
28
+ },
29
+ "node_modules/@alloc/quick-lru": {
30
+ "version": "5.2.0",
31
+ "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
32
+ "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
33
+ "dev": true,
34
+ "license": "MIT",
35
+ "engines": {
36
+ "node": ">=10"
37
+ },
38
+ "funding": {
39
+ "url": "https://github.com/sponsors/sindresorhus"
40
+ }
41
+ },
42
+ "node_modules/@babel/runtime": {
43
+ "version": "7.26.7",
44
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.7.tgz",
45
+ "integrity": "sha512-AOPI3D+a8dXnja+iwsUqGRjr1BbZIe771sXdapOtYI531gSqpi92vXivKcq2asu/DFpdl1ceFAKZyRzK2PCVcQ==",
46
+ "license": "MIT",
47
+ "dependencies": {
48
+ "regenerator-runtime": "^0.14.0"
49
+ },
50
+ "engines": {
51
+ "node": ">=6.9.0"
52
+ }
53
+ },
54
+ "node_modules/@ffmpeg/ffmpeg": {
55
+ "version": "0.12.15",
56
+ "resolved": "https://registry.npmjs.org/@ffmpeg/ffmpeg/-/ffmpeg-0.12.15.tgz",
57
+ "integrity": "sha512-1C8Obr4GsN3xw+/1Ww6PFM84wSQAGsdoTuTWPOj2OizsRDLT4CXTaVjPhkw6ARyDus1B9X/L2LiXHqYYsGnRFw==",
58
+ "dependencies": {
59
+ "@ffmpeg/types": "^0.12.4"
60
+ },
61
+ "engines": {
62
+ "node": ">=18.x"
63
+ }
64
+ },
65
+ "node_modules/@ffmpeg/types": {
66
+ "version": "0.12.4",
67
+ "resolved": "https://registry.npmjs.org/@ffmpeg/types/-/types-0.12.4.tgz",
68
+ "integrity": "sha512-k9vJQNBGTxE5AhYDtOYR5rO5fKsspbg51gbcwtbkw2lCdoIILzklulcjJfIDwrtn7XhDeF2M+THwJ2FGrLeV6A==",
69
+ "license": "MIT",
70
+ "engines": {
71
+ "node": ">=16.x"
72
+ }
73
+ },
74
+ "node_modules/@ffmpeg/util": {
75
+ "version": "0.12.2",
76
+ "resolved": "https://registry.npmjs.org/@ffmpeg/util/-/util-0.12.2.tgz",
77
+ "integrity": "sha512-ouyoW+4JB7WxjeZ2y6KpRvB+dLp7Cp4ro8z0HIVpZVCM7AwFlHa0c4R8Y/a4M3wMqATpYKhC7lSFHQ0T11MEDw==",
78
+ "engines": {
79
+ "node": ">=18.x"
80
+ }
81
+ },
82
+ "node_modules/@google/generative-ai": {
83
+ "version": "0.21.0",
84
+ "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.21.0.tgz",
85
+ "integrity": "sha512-7XhUbtnlkSEZK15kN3t+tzIMxsbKm/dSkKBFalj+20NvPKe1kBY7mR2P7vuijEn+f06z5+A8bVGKO0v39cr6Wg==",
86
+ "engines": {
87
+ "node": ">=18.0.0"
88
+ }
89
+ },
90
+ "node_modules/@isaacs/cliui": {
91
+ "version": "8.0.2",
92
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
93
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
94
+ "dev": true,
95
+ "license": "ISC",
96
+ "dependencies": {
97
+ "string-width": "^5.1.2",
98
+ "string-width-cjs": "npm:string-width@^4.2.0",
99
+ "strip-ansi": "^7.0.1",
100
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
101
+ "wrap-ansi": "^8.1.0",
102
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
103
+ },
104
+ "engines": {
105
+ "node": ">=12"
106
+ }
107
+ },
108
+ "node_modules/@jridgewell/gen-mapping": {
109
+ "version": "0.3.8",
110
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
111
+ "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
112
+ "dev": true,
113
+ "license": "MIT",
114
+ "dependencies": {
115
+ "@jridgewell/set-array": "^1.2.1",
116
+ "@jridgewell/sourcemap-codec": "^1.4.10",
117
+ "@jridgewell/trace-mapping": "^0.3.24"
118
+ },
119
+ "engines": {
120
+ "node": ">=6.0.0"
121
+ }
122
+ },
123
+ "node_modules/@jridgewell/resolve-uri": {
124
+ "version": "3.1.2",
125
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
126
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
127
+ "dev": true,
128
+ "license": "MIT",
129
+ "engines": {
130
+ "node": ">=6.0.0"
131
+ }
132
+ },
133
+ "node_modules/@jridgewell/set-array": {
134
+ "version": "1.2.1",
135
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
136
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
137
+ "dev": true,
138
+ "license": "MIT",
139
+ "engines": {
140
+ "node": ">=6.0.0"
141
+ }
142
+ },
143
+ "node_modules/@jridgewell/sourcemap-codec": {
144
+ "version": "1.5.0",
145
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
146
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
147
+ "dev": true,
148
+ "license": "MIT"
149
+ },
150
+ "node_modules/@jridgewell/trace-mapping": {
151
+ "version": "0.3.25",
152
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
153
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
154
+ "dev": true,
155
+ "license": "MIT",
156
+ "dependencies": {
157
+ "@jridgewell/resolve-uri": "^3.1.0",
158
+ "@jridgewell/sourcemap-codec": "^1.4.14"
159
+ }
160
+ },
161
+ "node_modules/@next/env": {
162
+ "version": "14.1.0",
163
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.0.tgz",
164
+ "integrity": "sha512-Py8zIo+02ht82brwwhTg36iogzFqGLPXlRGKQw5s+qP/kMNc4MAyDeEwBKDijk6zTIbegEgu8Qy7C1LboslQAw==",
165
+ "license": "MIT"
166
+ },
167
+ "node_modules/@next/swc-darwin-arm64": {
168
+ "version": "14.1.0",
169
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.0.tgz",
170
+ "integrity": "sha512-nUDn7TOGcIeyQni6lZHfzNoo9S0euXnu0jhsbMOmMJUBfgsnESdjN97kM7cBqQxZa8L/bM9om/S5/1dzCrW6wQ==",
171
+ "cpu": [
172
+ "arm64"
173
+ ],
174
+ "license": "MIT",
175
+ "optional": true,
176
+ "os": [
177
+ "darwin"
178
+ ],
179
+ "engines": {
180
+ "node": ">= 10"
181
+ }
182
+ },
183
+ "node_modules/@next/swc-darwin-x64": {
184
+ "version": "14.1.0",
185
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.0.tgz",
186
+ "integrity": "sha512-1jgudN5haWxiAl3O1ljUS2GfupPmcftu2RYJqZiMJmmbBT5M1XDffjUtRUzP4W3cBHsrvkfOFdQ71hAreNQP6g==",
187
+ "cpu": [
188
+ "x64"
189
+ ],
190
+ "license": "MIT",
191
+ "optional": true,
192
+ "os": [
193
+ "darwin"
194
+ ],
195
+ "engines": {
196
+ "node": ">= 10"
197
+ }
198
+ },
199
+ "node_modules/@next/swc-linux-arm64-gnu": {
200
+ "version": "14.1.0",
201
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.0.tgz",
202
+ "integrity": "sha512-RHo7Tcj+jllXUbK7xk2NyIDod3YcCPDZxj1WLIYxd709BQ7WuRYl3OWUNG+WUfqeQBds6kvZYlc42NJJTNi4tQ==",
203
+ "cpu": [
204
+ "arm64"
205
+ ],
206
+ "license": "MIT",
207
+ "optional": true,
208
+ "os": [
209
+ "linux"
210
+ ],
211
+ "engines": {
212
+ "node": ">= 10"
213
+ }
214
+ },
215
+ "node_modules/@next/swc-linux-arm64-musl": {
216
+ "version": "14.1.0",
217
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.0.tgz",
218
+ "integrity": "sha512-v6kP8sHYxjO8RwHmWMJSq7VZP2nYCkRVQ0qolh2l6xroe9QjbgV8siTbduED4u0hlk0+tjS6/Tuy4n5XCp+l6g==",
219
+ "cpu": [
220
+ "arm64"
221
+ ],
222
+ "license": "MIT",
223
+ "optional": true,
224
+ "os": [
225
+ "linux"
226
+ ],
227
+ "engines": {
228
+ "node": ">= 10"
229
+ }
230
+ },
231
+ "node_modules/@next/swc-linux-x64-gnu": {
232
+ "version": "14.1.0",
233
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.0.tgz",
234
+ "integrity": "sha512-zJ2pnoFYB1F4vmEVlb/eSe+VH679zT1VdXlZKX+pE66grOgjmKJHKacf82g/sWE4MQ4Rk2FMBCRnX+l6/TVYzQ==",
235
+ "cpu": [
236
+ "x64"
237
+ ],
238
+ "license": "MIT",
239
+ "optional": true,
240
+ "os": [
241
+ "linux"
242
+ ],
243
+ "engines": {
244
+ "node": ">= 10"
245
+ }
246
+ },
247
+ "node_modules/@next/swc-linux-x64-musl": {
248
+ "version": "14.1.0",
249
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.0.tgz",
250
+ "integrity": "sha512-rbaIYFt2X9YZBSbH/CwGAjbBG2/MrACCVu2X0+kSykHzHnYH5FjHxwXLkcoJ10cX0aWCEynpu+rP76x0914atg==",
251
+ "cpu": [
252
+ "x64"
253
+ ],
254
+ "license": "MIT",
255
+ "optional": true,
256
+ "os": [
257
+ "linux"
258
+ ],
259
+ "engines": {
260
+ "node": ">= 10"
261
+ }
262
+ },
263
+ "node_modules/@next/swc-win32-arm64-msvc": {
264
+ "version": "14.1.0",
265
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.0.tgz",
266
+ "integrity": "sha512-o1N5TsYc8f/HpGt39OUQpQ9AKIGApd3QLueu7hXk//2xq5Z9OxmV6sQfNp8C7qYmiOlHYODOGqNNa0e9jvchGQ==",
267
+ "cpu": [
268
+ "arm64"
269
+ ],
270
+ "license": "MIT",
271
+ "optional": true,
272
+ "os": [
273
+ "win32"
274
+ ],
275
+ "engines": {
276
+ "node": ">= 10"
277
+ }
278
+ },
279
+ "node_modules/@next/swc-win32-ia32-msvc": {
280
+ "version": "14.1.0",
281
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.0.tgz",
282
+ "integrity": "sha512-XXIuB1DBRCFwNO6EEzCTMHT5pauwaSj4SWs7CYnME57eaReAKBXCnkUE80p/pAZcewm7hs+vGvNqDPacEXHVkw==",
283
+ "cpu": [
284
+ "ia32"
285
+ ],
286
+ "license": "MIT",
287
+ "optional": true,
288
+ "os": [
289
+ "win32"
290
+ ],
291
+ "engines": {
292
+ "node": ">= 10"
293
+ }
294
+ },
295
+ "node_modules/@next/swc-win32-x64-msvc": {
296
+ "version": "14.1.0",
297
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.0.tgz",
298
+ "integrity": "sha512-9WEbVRRAqJ3YFVqEZIxUqkiO8l1nool1LmNxygr5HWF8AcSYsEpneUDhmjUVJEzO2A04+oPtZdombzzPPkTtgg==",
299
+ "cpu": [
300
+ "x64"
301
+ ],
302
+ "license": "MIT",
303
+ "optional": true,
304
+ "os": [
305
+ "win32"
306
+ ],
307
+ "engines": {
308
+ "node": ">= 10"
309
+ }
310
+ },
311
+ "node_modules/@nodelib/fs.scandir": {
312
+ "version": "2.1.5",
313
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
314
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
315
+ "dev": true,
316
+ "license": "MIT",
317
+ "dependencies": {
318
+ "@nodelib/fs.stat": "2.0.5",
319
+ "run-parallel": "^1.1.9"
320
+ },
321
+ "engines": {
322
+ "node": ">= 8"
323
+ }
324
+ },
325
+ "node_modules/@nodelib/fs.stat": {
326
+ "version": "2.0.5",
327
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
328
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
329
+ "dev": true,
330
+ "license": "MIT",
331
+ "engines": {
332
+ "node": ">= 8"
333
+ }
334
+ },
335
+ "node_modules/@nodelib/fs.walk": {
336
+ "version": "1.2.8",
337
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
338
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
339
+ "dev": true,
340
+ "license": "MIT",
341
+ "dependencies": {
342
+ "@nodelib/fs.scandir": "2.1.5",
343
+ "fastq": "^1.6.0"
344
+ },
345
+ "engines": {
346
+ "node": ">= 8"
347
+ }
348
+ },
349
+ "node_modules/@pkgjs/parseargs": {
350
+ "version": "0.11.0",
351
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
352
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
353
+ "dev": true,
354
+ "license": "MIT",
355
+ "optional": true,
356
+ "engines": {
357
+ "node": ">=14"
358
+ }
359
+ },
360
+ "node_modules/@swc/helpers": {
361
+ "version": "0.5.2",
362
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz",
363
+ "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==",
364
+ "license": "Apache-2.0",
365
+ "dependencies": {
366
+ "tslib": "^2.4.0"
367
+ }
368
+ },
369
+ "node_modules/@types/hast": {
370
+ "version": "2.3.10",
371
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz",
372
+ "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==",
373
+ "license": "MIT",
374
+ "dependencies": {
375
+ "@types/unist": "^2"
376
+ }
377
+ },
378
+ "node_modules/@types/unist": {
379
+ "version": "2.0.11",
380
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
381
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
382
+ "license": "MIT"
383
+ },
384
+ "node_modules/ansi-regex": {
385
+ "version": "6.1.0",
386
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
387
+ "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
388
+ "dev": true,
389
+ "license": "MIT",
390
+ "engines": {
391
+ "node": ">=12"
392
+ },
393
+ "funding": {
394
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
395
+ }
396
+ },
397
+ "node_modules/ansi-styles": {
398
+ "version": "6.2.1",
399
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
400
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
401
+ "dev": true,
402
+ "license": "MIT",
403
+ "engines": {
404
+ "node": ">=12"
405
+ },
406
+ "funding": {
407
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
408
+ }
409
+ },
410
+ "node_modules/any-promise": {
411
+ "version": "1.3.0",
412
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
413
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
414
+ "dev": true,
415
+ "license": "MIT"
416
+ },
417
+ "node_modules/anymatch": {
418
+ "version": "3.1.3",
419
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
420
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
421
+ "dev": true,
422
+ "license": "ISC",
423
+ "dependencies": {
424
+ "normalize-path": "^3.0.0",
425
+ "picomatch": "^2.0.4"
426
+ },
427
+ "engines": {
428
+ "node": ">= 8"
429
+ }
430
+ },
431
+ "node_modules/arg": {
432
+ "version": "5.0.2",
433
+ "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
434
+ "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
435
+ "dev": true,
436
+ "license": "MIT"
437
+ },
438
+ "node_modules/autoprefixer": {
439
+ "version": "10.4.20",
440
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz",
441
+ "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==",
442
+ "dev": true,
443
+ "funding": [
444
+ {
445
+ "type": "opencollective",
446
+ "url": "https://opencollective.com/postcss/"
447
+ },
448
+ {
449
+ "type": "tidelift",
450
+ "url": "https://tidelift.com/funding/github/npm/autoprefixer"
451
+ },
452
+ {
453
+ "type": "github",
454
+ "url": "https://github.com/sponsors/ai"
455
+ }
456
+ ],
457
+ "license": "MIT",
458
+ "dependencies": {
459
+ "browserslist": "^4.23.3",
460
+ "caniuse-lite": "^1.0.30001646",
461
+ "fraction.js": "^4.3.7",
462
+ "normalize-range": "^0.1.2",
463
+ "picocolors": "^1.0.1",
464
+ "postcss-value-parser": "^4.2.0"
465
+ },
466
+ "bin": {
467
+ "autoprefixer": "bin/autoprefixer"
468
+ },
469
+ "engines": {
470
+ "node": "^10 || ^12 || >=14"
471
+ },
472
+ "peerDependencies": {
473
+ "postcss": "^8.1.0"
474
+ }
475
+ },
476
+ "node_modules/balanced-match": {
477
+ "version": "1.0.2",
478
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
479
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
480
+ "dev": true,
481
+ "license": "MIT"
482
+ },
483
+ "node_modules/binary-extensions": {
484
+ "version": "2.3.0",
485
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
486
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
487
+ "dev": true,
488
+ "license": "MIT",
489
+ "engines": {
490
+ "node": ">=8"
491
+ },
492
+ "funding": {
493
+ "url": "https://github.com/sponsors/sindresorhus"
494
+ }
495
+ },
496
+ "node_modules/brace-expansion": {
497
+ "version": "2.0.1",
498
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
499
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
500
+ "dev": true,
501
+ "license": "MIT",
502
+ "dependencies": {
503
+ "balanced-match": "^1.0.0"
504
+ }
505
+ },
506
+ "node_modules/braces": {
507
+ "version": "3.0.3",
508
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
509
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
510
+ "dev": true,
511
+ "license": "MIT",
512
+ "dependencies": {
513
+ "fill-range": "^7.1.1"
514
+ },
515
+ "engines": {
516
+ "node": ">=8"
517
+ }
518
+ },
519
+ "node_modules/browserslist": {
520
+ "version": "4.24.4",
521
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz",
522
+ "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==",
523
+ "dev": true,
524
+ "funding": [
525
+ {
526
+ "type": "opencollective",
527
+ "url": "https://opencollective.com/browserslist"
528
+ },
529
+ {
530
+ "type": "tidelift",
531
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
532
+ },
533
+ {
534
+ "type": "github",
535
+ "url": "https://github.com/sponsors/ai"
536
+ }
537
+ ],
538
+ "license": "MIT",
539
+ "dependencies": {
540
+ "caniuse-lite": "^1.0.30001688",
541
+ "electron-to-chromium": "^1.5.73",
542
+ "node-releases": "^2.0.19",
543
+ "update-browserslist-db": "^1.1.1"
544
+ },
545
+ "bin": {
546
+ "browserslist": "cli.js"
547
+ },
548
+ "engines": {
549
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
550
+ }
551
+ },
552
+ "node_modules/busboy": {
553
+ "version": "1.6.0",
554
+ "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
555
+ "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
556
+ "dependencies": {
557
+ "streamsearch": "^1.1.0"
558
+ },
559
+ "engines": {
560
+ "node": ">=10.16.0"
561
+ }
562
+ },
563
+ "node_modules/camelcase-css": {
564
+ "version": "2.0.1",
565
+ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
566
+ "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
567
+ "dev": true,
568
+ "license": "MIT",
569
+ "engines": {
570
+ "node": ">= 6"
571
+ }
572
+ },
573
+ "node_modules/caniuse-lite": {
574
+ "version": "1.0.30001699",
575
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001699.tgz",
576
+ "integrity": "sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w==",
577
+ "funding": [
578
+ {
579
+ "type": "opencollective",
580
+ "url": "https://opencollective.com/browserslist"
581
+ },
582
+ {
583
+ "type": "tidelift",
584
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
585
+ },
586
+ {
587
+ "type": "github",
588
+ "url": "https://github.com/sponsors/ai"
589
+ }
590
+ ],
591
+ "license": "CC-BY-4.0"
592
+ },
593
+ "node_modules/character-entities": {
594
+ "version": "1.2.4",
595
+ "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz",
596
+ "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==",
597
+ "license": "MIT",
598
+ "funding": {
599
+ "type": "github",
600
+ "url": "https://github.com/sponsors/wooorm"
601
+ }
602
+ },
603
+ "node_modules/character-entities-legacy": {
604
+ "version": "1.1.4",
605
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz",
606
+ "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==",
607
+ "license": "MIT",
608
+ "funding": {
609
+ "type": "github",
610
+ "url": "https://github.com/sponsors/wooorm"
611
+ }
612
+ },
613
+ "node_modules/character-reference-invalid": {
614
+ "version": "1.1.4",
615
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz",
616
+ "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==",
617
+ "license": "MIT",
618
+ "funding": {
619
+ "type": "github",
620
+ "url": "https://github.com/sponsors/wooorm"
621
+ }
622
+ },
623
+ "node_modules/chokidar": {
624
+ "version": "3.6.0",
625
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
626
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
627
+ "dev": true,
628
+ "license": "MIT",
629
+ "dependencies": {
630
+ "anymatch": "~3.1.2",
631
+ "braces": "~3.0.2",
632
+ "glob-parent": "~5.1.2",
633
+ "is-binary-path": "~2.1.0",
634
+ "is-glob": "~4.0.1",
635
+ "normalize-path": "~3.0.0",
636
+ "readdirp": "~3.6.0"
637
+ },
638
+ "engines": {
639
+ "node": ">= 8.10.0"
640
+ },
641
+ "funding": {
642
+ "url": "https://paulmillr.com/funding/"
643
+ },
644
+ "optionalDependencies": {
645
+ "fsevents": "~2.3.2"
646
+ }
647
+ },
648
+ "node_modules/chokidar/node_modules/glob-parent": {
649
+ "version": "5.1.2",
650
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
651
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
652
+ "dev": true,
653
+ "license": "ISC",
654
+ "dependencies": {
655
+ "is-glob": "^4.0.1"
656
+ },
657
+ "engines": {
658
+ "node": ">= 6"
659
+ }
660
+ },
661
+ "node_modules/client-only": {
662
+ "version": "0.0.1",
663
+ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
664
+ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
665
+ "license": "MIT"
666
+ },
667
+ "node_modules/color-convert": {
668
+ "version": "2.0.1",
669
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
670
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
671
+ "dev": true,
672
+ "license": "MIT",
673
+ "dependencies": {
674
+ "color-name": "~1.1.4"
675
+ },
676
+ "engines": {
677
+ "node": ">=7.0.0"
678
+ }
679
+ },
680
+ "node_modules/color-name": {
681
+ "version": "1.1.4",
682
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
683
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
684
+ "dev": true,
685
+ "license": "MIT"
686
+ },
687
+ "node_modules/comma-separated-tokens": {
688
+ "version": "1.0.8",
689
+ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz",
690
+ "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==",
691
+ "license": "MIT",
692
+ "funding": {
693
+ "type": "github",
694
+ "url": "https://github.com/sponsors/wooorm"
695
+ }
696
+ },
697
+ "node_modules/commander": {
698
+ "version": "4.1.1",
699
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
700
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
701
+ "dev": true,
702
+ "license": "MIT",
703
+ "engines": {
704
+ "node": ">= 6"
705
+ }
706
+ },
707
+ "node_modules/cross-spawn": {
708
+ "version": "7.0.6",
709
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
710
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
711
+ "dev": true,
712
+ "license": "MIT",
713
+ "dependencies": {
714
+ "path-key": "^3.1.0",
715
+ "shebang-command": "^2.0.0",
716
+ "which": "^2.0.1"
717
+ },
718
+ "engines": {
719
+ "node": ">= 8"
720
+ }
721
+ },
722
+ "node_modules/cssesc": {
723
+ "version": "3.0.0",
724
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
725
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
726
+ "dev": true,
727
+ "license": "MIT",
728
+ "bin": {
729
+ "cssesc": "bin/cssesc"
730
+ },
731
+ "engines": {
732
+ "node": ">=4"
733
+ }
734
+ },
735
+ "node_modules/csstype": {
736
+ "version": "3.1.3",
737
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
738
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
739
+ "license": "MIT"
740
+ },
741
+ "node_modules/didyoumean": {
742
+ "version": "1.2.2",
743
+ "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
744
+ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
745
+ "dev": true,
746
+ "license": "Apache-2.0"
747
+ },
748
+ "node_modules/dlv": {
749
+ "version": "1.1.3",
750
+ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
751
+ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
752
+ "dev": true,
753
+ "license": "MIT"
754
+ },
755
+ "node_modules/eastasianwidth": {
756
+ "version": "0.2.0",
757
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
758
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
759
+ "dev": true,
760
+ "license": "MIT"
761
+ },
762
+ "node_modules/electron-to-chromium": {
763
+ "version": "1.5.99",
764
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.99.tgz",
765
+ "integrity": "sha512-77c/+fCyL2U+aOyqfIFi89wYLBeSTCs55xCZL0oFH0KjqsvSvyh6AdQ+UIl1vgpnQQE6g+/KK8hOIupH6VwPtg==",
766
+ "dev": true,
767
+ "license": "ISC"
768
+ },
769
+ "node_modules/emoji-regex": {
770
+ "version": "9.2.2",
771
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
772
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
773
+ "dev": true,
774
+ "license": "MIT"
775
+ },
776
+ "node_modules/escalade": {
777
+ "version": "3.2.0",
778
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
779
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
780
+ "dev": true,
781
+ "license": "MIT",
782
+ "engines": {
783
+ "node": ">=6"
784
+ }
785
+ },
786
+ "node_modules/fast-glob": {
787
+ "version": "3.3.3",
788
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
789
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
790
+ "dev": true,
791
+ "license": "MIT",
792
+ "dependencies": {
793
+ "@nodelib/fs.stat": "^2.0.2",
794
+ "@nodelib/fs.walk": "^1.2.3",
795
+ "glob-parent": "^5.1.2",
796
+ "merge2": "^1.3.0",
797
+ "micromatch": "^4.0.8"
798
+ },
799
+ "engines": {
800
+ "node": ">=8.6.0"
801
+ }
802
+ },
803
+ "node_modules/fast-glob/node_modules/glob-parent": {
804
+ "version": "5.1.2",
805
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
806
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
807
+ "dev": true,
808
+ "license": "ISC",
809
+ "dependencies": {
810
+ "is-glob": "^4.0.1"
811
+ },
812
+ "engines": {
813
+ "node": ">= 6"
814
+ }
815
+ },
816
+ "node_modules/fastq": {
817
+ "version": "1.19.0",
818
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz",
819
+ "integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==",
820
+ "dev": true,
821
+ "license": "ISC",
822
+ "dependencies": {
823
+ "reusify": "^1.0.4"
824
+ }
825
+ },
826
+ "node_modules/fault": {
827
+ "version": "1.0.4",
828
+ "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz",
829
+ "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==",
830
+ "license": "MIT",
831
+ "dependencies": {
832
+ "format": "^0.2.0"
833
+ },
834
+ "funding": {
835
+ "type": "github",
836
+ "url": "https://github.com/sponsors/wooorm"
837
+ }
838
+ },
839
+ "node_modules/fill-range": {
840
+ "version": "7.1.1",
841
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
842
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
843
+ "dev": true,
844
+ "license": "MIT",
845
+ "dependencies": {
846
+ "to-regex-range": "^5.0.1"
847
+ },
848
+ "engines": {
849
+ "node": ">=8"
850
+ }
851
+ },
852
+ "node_modules/foreground-child": {
853
+ "version": "3.3.0",
854
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
855
+ "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
856
+ "dev": true,
857
+ "license": "ISC",
858
+ "dependencies": {
859
+ "cross-spawn": "^7.0.0",
860
+ "signal-exit": "^4.0.1"
861
+ },
862
+ "engines": {
863
+ "node": ">=14"
864
+ },
865
+ "funding": {
866
+ "url": "https://github.com/sponsors/isaacs"
867
+ }
868
+ },
869
+ "node_modules/format": {
870
+ "version": "0.2.2",
871
+ "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
872
+ "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==",
873
+ "engines": {
874
+ "node": ">=0.4.x"
875
+ }
876
+ },
877
+ "node_modules/fraction.js": {
878
+ "version": "4.3.7",
879
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
880
+ "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
881
+ "dev": true,
882
+ "license": "MIT",
883
+ "engines": {
884
+ "node": "*"
885
+ },
886
+ "funding": {
887
+ "type": "patreon",
888
+ "url": "https://github.com/sponsors/rawify"
889
+ }
890
+ },
891
+ "node_modules/fsevents": {
892
+ "version": "2.3.3",
893
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
894
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
895
+ "dev": true,
896
+ "hasInstallScript": true,
897
+ "license": "MIT",
898
+ "optional": true,
899
+ "os": [
900
+ "darwin"
901
+ ],
902
+ "engines": {
903
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
904
+ }
905
+ },
906
+ "node_modules/function-bind": {
907
+ "version": "1.1.2",
908
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
909
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
910
+ "dev": true,
911
+ "license": "MIT",
912
+ "funding": {
913
+ "url": "https://github.com/sponsors/ljharb"
914
+ }
915
+ },
916
+ "node_modules/gif.js": {
917
+ "version": "0.2.0",
918
+ "resolved": "https://registry.npmjs.org/gif.js/-/gif.js-0.2.0.tgz",
919
+ "integrity": "sha512-bYxCoT8OZKmbxY8RN4qDiYuj4nrQDTzgLRcFVovyona1PTWNePzI4nzOmotnlOFIzTk/ZxAHtv+TfVLiBWj/hw==",
920
+ "license": "MIT"
921
+ },
922
+ "node_modules/glob": {
923
+ "version": "10.4.5",
924
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
925
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
926
+ "dev": true,
927
+ "license": "ISC",
928
+ "dependencies": {
929
+ "foreground-child": "^3.1.0",
930
+ "jackspeak": "^3.1.2",
931
+ "minimatch": "^9.0.4",
932
+ "minipass": "^7.1.2",
933
+ "package-json-from-dist": "^1.0.0",
934
+ "path-scurry": "^1.11.1"
935
+ },
936
+ "bin": {
937
+ "glob": "dist/esm/bin.mjs"
938
+ },
939
+ "funding": {
940
+ "url": "https://github.com/sponsors/isaacs"
941
+ }
942
+ },
943
+ "node_modules/glob-parent": {
944
+ "version": "6.0.2",
945
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
946
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
947
+ "dev": true,
948
+ "license": "ISC",
949
+ "dependencies": {
950
+ "is-glob": "^4.0.3"
951
+ },
952
+ "engines": {
953
+ "node": ">=10.13.0"
954
+ }
955
+ },
956
+ "node_modules/goober": {
957
+ "version": "2.1.16",
958
+ "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.16.tgz",
959
+ "integrity": "sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==",
960
+ "license": "MIT",
961
+ "peerDependencies": {
962
+ "csstype": "^3.0.10"
963
+ }
964
+ },
965
+ "node_modules/graceful-fs": {
966
+ "version": "4.2.11",
967
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
968
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
969
+ "license": "ISC"
970
+ },
971
+ "node_modules/hasown": {
972
+ "version": "2.0.2",
973
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
974
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
975
+ "dev": true,
976
+ "license": "MIT",
977
+ "dependencies": {
978
+ "function-bind": "^1.1.2"
979
+ },
980
+ "engines": {
981
+ "node": ">= 0.4"
982
+ }
983
+ },
984
+ "node_modules/hast-util-parse-selector": {
985
+ "version": "2.2.5",
986
+ "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz",
987
+ "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==",
988
+ "license": "MIT",
989
+ "funding": {
990
+ "type": "opencollective",
991
+ "url": "https://opencollective.com/unified"
992
+ }
993
+ },
994
+ "node_modules/hastscript": {
995
+ "version": "6.0.0",
996
+ "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz",
997
+ "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==",
998
+ "license": "MIT",
999
+ "dependencies": {
1000
+ "@types/hast": "^2.0.0",
1001
+ "comma-separated-tokens": "^1.0.0",
1002
+ "hast-util-parse-selector": "^2.0.0",
1003
+ "property-information": "^5.0.0",
1004
+ "space-separated-tokens": "^1.0.0"
1005
+ },
1006
+ "funding": {
1007
+ "type": "opencollective",
1008
+ "url": "https://opencollective.com/unified"
1009
+ }
1010
+ },
1011
+ "node_modules/highlight.js": {
1012
+ "version": "10.7.3",
1013
+ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
1014
+ "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==",
1015
+ "license": "BSD-3-Clause",
1016
+ "engines": {
1017
+ "node": "*"
1018
+ }
1019
+ },
1020
+ "node_modules/highlightjs-vue": {
1021
+ "version": "1.0.0",
1022
+ "resolved": "https://registry.npmjs.org/highlightjs-vue/-/highlightjs-vue-1.0.0.tgz",
1023
+ "integrity": "sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA==",
1024
+ "license": "CC0-1.0"
1025
+ },
1026
+ "node_modules/is-alphabetical": {
1027
+ "version": "1.0.4",
1028
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
1029
+ "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==",
1030
+ "license": "MIT",
1031
+ "funding": {
1032
+ "type": "github",
1033
+ "url": "https://github.com/sponsors/wooorm"
1034
+ }
1035
+ },
1036
+ "node_modules/is-alphanumerical": {
1037
+ "version": "1.0.4",
1038
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
1039
+ "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
1040
+ "license": "MIT",
1041
+ "dependencies": {
1042
+ "is-alphabetical": "^1.0.0",
1043
+ "is-decimal": "^1.0.0"
1044
+ },
1045
+ "funding": {
1046
+ "type": "github",
1047
+ "url": "https://github.com/sponsors/wooorm"
1048
+ }
1049
+ },
1050
+ "node_modules/is-binary-path": {
1051
+ "version": "2.1.0",
1052
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
1053
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
1054
+ "dev": true,
1055
+ "license": "MIT",
1056
+ "dependencies": {
1057
+ "binary-extensions": "^2.0.0"
1058
+ },
1059
+ "engines": {
1060
+ "node": ">=8"
1061
+ }
1062
+ },
1063
+ "node_modules/is-core-module": {
1064
+ "version": "2.16.1",
1065
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
1066
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
1067
+ "dev": true,
1068
+ "license": "MIT",
1069
+ "dependencies": {
1070
+ "hasown": "^2.0.2"
1071
+ },
1072
+ "engines": {
1073
+ "node": ">= 0.4"
1074
+ },
1075
+ "funding": {
1076
+ "url": "https://github.com/sponsors/ljharb"
1077
+ }
1078
+ },
1079
+ "node_modules/is-decimal": {
1080
+ "version": "1.0.4",
1081
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
1082
+ "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==",
1083
+ "license": "MIT",
1084
+ "funding": {
1085
+ "type": "github",
1086
+ "url": "https://github.com/sponsors/wooorm"
1087
+ }
1088
+ },
1089
+ "node_modules/is-extglob": {
1090
+ "version": "2.1.1",
1091
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
1092
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
1093
+ "dev": true,
1094
+ "license": "MIT",
1095
+ "engines": {
1096
+ "node": ">=0.10.0"
1097
+ }
1098
+ },
1099
+ "node_modules/is-fullwidth-code-point": {
1100
+ "version": "3.0.0",
1101
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
1102
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
1103
+ "dev": true,
1104
+ "license": "MIT",
1105
+ "engines": {
1106
+ "node": ">=8"
1107
+ }
1108
+ },
1109
+ "node_modules/is-glob": {
1110
+ "version": "4.0.3",
1111
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
1112
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
1113
+ "dev": true,
1114
+ "license": "MIT",
1115
+ "dependencies": {
1116
+ "is-extglob": "^2.1.1"
1117
+ },
1118
+ "engines": {
1119
+ "node": ">=0.10.0"
1120
+ }
1121
+ },
1122
+ "node_modules/is-hexadecimal": {
1123
+ "version": "1.0.4",
1124
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz",
1125
+ "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==",
1126
+ "license": "MIT",
1127
+ "funding": {
1128
+ "type": "github",
1129
+ "url": "https://github.com/sponsors/wooorm"
1130
+ }
1131
+ },
1132
+ "node_modules/is-number": {
1133
+ "version": "7.0.0",
1134
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
1135
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
1136
+ "dev": true,
1137
+ "license": "MIT",
1138
+ "engines": {
1139
+ "node": ">=0.12.0"
1140
+ }
1141
+ },
1142
+ "node_modules/isexe": {
1143
+ "version": "2.0.0",
1144
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1145
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
1146
+ "dev": true,
1147
+ "license": "ISC"
1148
+ },
1149
+ "node_modules/jackspeak": {
1150
+ "version": "3.4.3",
1151
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
1152
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
1153
+ "dev": true,
1154
+ "license": "BlueOak-1.0.0",
1155
+ "dependencies": {
1156
+ "@isaacs/cliui": "^8.0.2"
1157
+ },
1158
+ "funding": {
1159
+ "url": "https://github.com/sponsors/isaacs"
1160
+ },
1161
+ "optionalDependencies": {
1162
+ "@pkgjs/parseargs": "^0.11.0"
1163
+ }
1164
+ },
1165
+ "node_modules/jiti": {
1166
+ "version": "1.21.7",
1167
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
1168
+ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
1169
+ "dev": true,
1170
+ "license": "MIT",
1171
+ "bin": {
1172
+ "jiti": "bin/jiti.js"
1173
+ }
1174
+ },
1175
+ "node_modules/js-tokens": {
1176
+ "version": "4.0.0",
1177
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
1178
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
1179
+ "license": "MIT"
1180
+ },
1181
+ "node_modules/lilconfig": {
1182
+ "version": "3.1.3",
1183
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
1184
+ "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
1185
+ "dev": true,
1186
+ "license": "MIT",
1187
+ "engines": {
1188
+ "node": ">=14"
1189
+ },
1190
+ "funding": {
1191
+ "url": "https://github.com/sponsors/antonk52"
1192
+ }
1193
+ },
1194
+ "node_modules/lines-and-columns": {
1195
+ "version": "1.2.4",
1196
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
1197
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
1198
+ "dev": true,
1199
+ "license": "MIT"
1200
+ },
1201
+ "node_modules/loose-envify": {
1202
+ "version": "1.4.0",
1203
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
1204
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
1205
+ "license": "MIT",
1206
+ "dependencies": {
1207
+ "js-tokens": "^3.0.0 || ^4.0.0"
1208
+ },
1209
+ "bin": {
1210
+ "loose-envify": "cli.js"
1211
+ }
1212
+ },
1213
+ "node_modules/lowlight": {
1214
+ "version": "1.20.0",
1215
+ "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz",
1216
+ "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==",
1217
+ "license": "MIT",
1218
+ "dependencies": {
1219
+ "fault": "^1.0.0",
1220
+ "highlight.js": "~10.7.0"
1221
+ },
1222
+ "funding": {
1223
+ "type": "github",
1224
+ "url": "https://github.com/sponsors/wooorm"
1225
+ }
1226
+ },
1227
+ "node_modules/lru-cache": {
1228
+ "version": "10.4.3",
1229
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
1230
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
1231
+ "dev": true,
1232
+ "license": "ISC"
1233
+ },
1234
+ "node_modules/lucide-react": {
1235
+ "version": "0.330.0",
1236
+ "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.330.0.tgz",
1237
+ "integrity": "sha512-CQwY+Fpbt2kxCoVhuN0RCZDCYlbYnqB870Bl/vIQf3ER/cnDDQ6moLmEkguRyruAUGd4j3Lc4mtnJosXnqHheA==",
1238
+ "license": "ISC",
1239
+ "peerDependencies": {
1240
+ "react": "^16.5.1 || ^17.0.0 || ^18.0.0"
1241
+ }
1242
+ },
1243
+ "node_modules/merge2": {
1244
+ "version": "1.4.1",
1245
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
1246
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
1247
+ "dev": true,
1248
+ "license": "MIT",
1249
+ "engines": {
1250
+ "node": ">= 8"
1251
+ }
1252
+ },
1253
+ "node_modules/micromatch": {
1254
+ "version": "4.0.8",
1255
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
1256
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
1257
+ "dev": true,
1258
+ "license": "MIT",
1259
+ "dependencies": {
1260
+ "braces": "^3.0.3",
1261
+ "picomatch": "^2.3.1"
1262
+ },
1263
+ "engines": {
1264
+ "node": ">=8.6"
1265
+ }
1266
+ },
1267
+ "node_modules/minimatch": {
1268
+ "version": "9.0.5",
1269
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
1270
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
1271
+ "dev": true,
1272
+ "license": "ISC",
1273
+ "dependencies": {
1274
+ "brace-expansion": "^2.0.1"
1275
+ },
1276
+ "engines": {
1277
+ "node": ">=16 || 14 >=14.17"
1278
+ },
1279
+ "funding": {
1280
+ "url": "https://github.com/sponsors/isaacs"
1281
+ }
1282
+ },
1283
+ "node_modules/minipass": {
1284
+ "version": "7.1.2",
1285
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
1286
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
1287
+ "dev": true,
1288
+ "license": "ISC",
1289
+ "engines": {
1290
+ "node": ">=16 || 14 >=14.17"
1291
+ }
1292
+ },
1293
+ "node_modules/mz": {
1294
+ "version": "2.7.0",
1295
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
1296
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
1297
+ "dev": true,
1298
+ "license": "MIT",
1299
+ "dependencies": {
1300
+ "any-promise": "^1.0.0",
1301
+ "object-assign": "^4.0.1",
1302
+ "thenify-all": "^1.0.0"
1303
+ }
1304
+ },
1305
+ "node_modules/nanoid": {
1306
+ "version": "3.3.8",
1307
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
1308
+ "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
1309
+ "funding": [
1310
+ {
1311
+ "type": "github",
1312
+ "url": "https://github.com/sponsors/ai"
1313
+ }
1314
+ ],
1315
+ "license": "MIT",
1316
+ "bin": {
1317
+ "nanoid": "bin/nanoid.cjs"
1318
+ },
1319
+ "engines": {
1320
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
1321
+ }
1322
+ },
1323
+ "node_modules/next": {
1324
+ "version": "14.1.0",
1325
+ "resolved": "https://registry.npmjs.org/next/-/next-14.1.0.tgz",
1326
+ "integrity": "sha512-wlzrsbfeSU48YQBjZhDzOwhWhGsy+uQycR8bHAOt1LY1bn3zZEcDyHQOEoN3aWzQ8LHCAJ1nqrWCc9XF2+O45Q==",
1327
+ "license": "MIT",
1328
+ "dependencies": {
1329
+ "@next/env": "14.1.0",
1330
+ "@swc/helpers": "0.5.2",
1331
+ "busboy": "1.6.0",
1332
+ "caniuse-lite": "^1.0.30001579",
1333
+ "graceful-fs": "^4.2.11",
1334
+ "postcss": "8.4.31",
1335
+ "styled-jsx": "5.1.1"
1336
+ },
1337
+ "bin": {
1338
+ "next": "dist/bin/next"
1339
+ },
1340
+ "engines": {
1341
+ "node": ">=18.17.0"
1342
+ },
1343
+ "optionalDependencies": {
1344
+ "@next/swc-darwin-arm64": "14.1.0",
1345
+ "@next/swc-darwin-x64": "14.1.0",
1346
+ "@next/swc-linux-arm64-gnu": "14.1.0",
1347
+ "@next/swc-linux-arm64-musl": "14.1.0",
1348
+ "@next/swc-linux-x64-gnu": "14.1.0",
1349
+ "@next/swc-linux-x64-musl": "14.1.0",
1350
+ "@next/swc-win32-arm64-msvc": "14.1.0",
1351
+ "@next/swc-win32-ia32-msvc": "14.1.0",
1352
+ "@next/swc-win32-x64-msvc": "14.1.0"
1353
+ },
1354
+ "peerDependencies": {
1355
+ "@opentelemetry/api": "^1.1.0",
1356
+ "react": "^18.2.0",
1357
+ "react-dom": "^18.2.0",
1358
+ "sass": "^1.3.0"
1359
+ },
1360
+ "peerDependenciesMeta": {
1361
+ "@opentelemetry/api": {
1362
+ "optional": true
1363
+ },
1364
+ "sass": {
1365
+ "optional": true
1366
+ }
1367
+ }
1368
+ },
1369
+ "node_modules/next/node_modules/postcss": {
1370
+ "version": "8.4.31",
1371
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
1372
+ "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
1373
+ "funding": [
1374
+ {
1375
+ "type": "opencollective",
1376
+ "url": "https://opencollective.com/postcss/"
1377
+ },
1378
+ {
1379
+ "type": "tidelift",
1380
+ "url": "https://tidelift.com/funding/github/npm/postcss"
1381
+ },
1382
+ {
1383
+ "type": "github",
1384
+ "url": "https://github.com/sponsors/ai"
1385
+ }
1386
+ ],
1387
+ "license": "MIT",
1388
+ "dependencies": {
1389
+ "nanoid": "^3.3.6",
1390
+ "picocolors": "^1.0.0",
1391
+ "source-map-js": "^1.0.2"
1392
+ },
1393
+ "engines": {
1394
+ "node": "^10 || ^12 || >=14"
1395
+ }
1396
+ },
1397
+ "node_modules/node-releases": {
1398
+ "version": "2.0.19",
1399
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
1400
+ "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
1401
+ "dev": true,
1402
+ "license": "MIT"
1403
+ },
1404
+ "node_modules/normalize-path": {
1405
+ "version": "3.0.0",
1406
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
1407
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
1408
+ "dev": true,
1409
+ "license": "MIT",
1410
+ "engines": {
1411
+ "node": ">=0.10.0"
1412
+ }
1413
+ },
1414
+ "node_modules/normalize-range": {
1415
+ "version": "0.1.2",
1416
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
1417
+ "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
1418
+ "dev": true,
1419
+ "license": "MIT",
1420
+ "engines": {
1421
+ "node": ">=0.10.0"
1422
+ }
1423
+ },
1424
+ "node_modules/object-assign": {
1425
+ "version": "4.1.1",
1426
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1427
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
1428
+ "dev": true,
1429
+ "license": "MIT",
1430
+ "engines": {
1431
+ "node": ">=0.10.0"
1432
+ }
1433
+ },
1434
+ "node_modules/object-hash": {
1435
+ "version": "3.0.0",
1436
+ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
1437
+ "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
1438
+ "dev": true,
1439
+ "license": "MIT",
1440
+ "engines": {
1441
+ "node": ">= 6"
1442
+ }
1443
+ },
1444
+ "node_modules/p5": {
1445
+ "version": "1.11.3",
1446
+ "resolved": "https://registry.npmjs.org/p5/-/p5-1.11.3.tgz",
1447
+ "integrity": "sha512-5eiyuZ3Pvo6ucr3nr8AzD+qwpoleiIEF2a2HmiO6PJM1tnbD0LmLlckZyYGJATs0tdmRjc37Muh6KPS4d1FHHg==",
1448
+ "license": "LGPL-2.1"
1449
+ },
1450
+ "node_modules/package-json-from-dist": {
1451
+ "version": "1.0.1",
1452
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
1453
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
1454
+ "dev": true,
1455
+ "license": "BlueOak-1.0.0"
1456
+ },
1457
+ "node_modules/parse-entities": {
1458
+ "version": "2.0.0",
1459
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz",
1460
+ "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==",
1461
+ "license": "MIT",
1462
+ "dependencies": {
1463
+ "character-entities": "^1.0.0",
1464
+ "character-entities-legacy": "^1.0.0",
1465
+ "character-reference-invalid": "^1.0.0",
1466
+ "is-alphanumerical": "^1.0.0",
1467
+ "is-decimal": "^1.0.0",
1468
+ "is-hexadecimal": "^1.0.0"
1469
+ },
1470
+ "funding": {
1471
+ "type": "github",
1472
+ "url": "https://github.com/sponsors/wooorm"
1473
+ }
1474
+ },
1475
+ "node_modules/path-key": {
1476
+ "version": "3.1.1",
1477
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
1478
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
1479
+ "dev": true,
1480
+ "license": "MIT",
1481
+ "engines": {
1482
+ "node": ">=8"
1483
+ }
1484
+ },
1485
+ "node_modules/path-parse": {
1486
+ "version": "1.0.7",
1487
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
1488
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
1489
+ "dev": true,
1490
+ "license": "MIT"
1491
+ },
1492
+ "node_modules/path-scurry": {
1493
+ "version": "1.11.1",
1494
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
1495
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
1496
+ "dev": true,
1497
+ "license": "BlueOak-1.0.0",
1498
+ "dependencies": {
1499
+ "lru-cache": "^10.2.0",
1500
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
1501
+ },
1502
+ "engines": {
1503
+ "node": ">=16 || 14 >=14.18"
1504
+ },
1505
+ "funding": {
1506
+ "url": "https://github.com/sponsors/isaacs"
1507
+ }
1508
+ },
1509
+ "node_modules/picocolors": {
1510
+ "version": "1.1.1",
1511
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
1512
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
1513
+ "license": "ISC"
1514
+ },
1515
+ "node_modules/picomatch": {
1516
+ "version": "2.3.1",
1517
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
1518
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
1519
+ "dev": true,
1520
+ "license": "MIT",
1521
+ "engines": {
1522
+ "node": ">=8.6"
1523
+ },
1524
+ "funding": {
1525
+ "url": "https://github.com/sponsors/jonschlinkert"
1526
+ }
1527
+ },
1528
+ "node_modules/pify": {
1529
+ "version": "2.3.0",
1530
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
1531
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
1532
+ "dev": true,
1533
+ "license": "MIT",
1534
+ "engines": {
1535
+ "node": ">=0.10.0"
1536
+ }
1537
+ },
1538
+ "node_modules/pirates": {
1539
+ "version": "4.0.6",
1540
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
1541
+ "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
1542
+ "dev": true,
1543
+ "license": "MIT",
1544
+ "engines": {
1545
+ "node": ">= 6"
1546
+ }
1547
+ },
1548
+ "node_modules/postcss": {
1549
+ "version": "8.5.2",
1550
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.2.tgz",
1551
+ "integrity": "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==",
1552
+ "dev": true,
1553
+ "funding": [
1554
+ {
1555
+ "type": "opencollective",
1556
+ "url": "https://opencollective.com/postcss/"
1557
+ },
1558
+ {
1559
+ "type": "tidelift",
1560
+ "url": "https://tidelift.com/funding/github/npm/postcss"
1561
+ },
1562
+ {
1563
+ "type": "github",
1564
+ "url": "https://github.com/sponsors/ai"
1565
+ }
1566
+ ],
1567
+ "license": "MIT",
1568
+ "dependencies": {
1569
+ "nanoid": "^3.3.8",
1570
+ "picocolors": "^1.1.1",
1571
+ "source-map-js": "^1.2.1"
1572
+ },
1573
+ "engines": {
1574
+ "node": "^10 || ^12 || >=14"
1575
+ }
1576
+ },
1577
+ "node_modules/postcss-import": {
1578
+ "version": "15.1.0",
1579
+ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
1580
+ "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
1581
+ "dev": true,
1582
+ "license": "MIT",
1583
+ "dependencies": {
1584
+ "postcss-value-parser": "^4.0.0",
1585
+ "read-cache": "^1.0.0",
1586
+ "resolve": "^1.1.7"
1587
+ },
1588
+ "engines": {
1589
+ "node": ">=14.0.0"
1590
+ },
1591
+ "peerDependencies": {
1592
+ "postcss": "^8.0.0"
1593
+ }
1594
+ },
1595
+ "node_modules/postcss-js": {
1596
+ "version": "4.0.1",
1597
+ "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
1598
+ "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
1599
+ "dev": true,
1600
+ "license": "MIT",
1601
+ "dependencies": {
1602
+ "camelcase-css": "^2.0.1"
1603
+ },
1604
+ "engines": {
1605
+ "node": "^12 || ^14 || >= 16"
1606
+ },
1607
+ "funding": {
1608
+ "type": "opencollective",
1609
+ "url": "https://opencollective.com/postcss/"
1610
+ },
1611
+ "peerDependencies": {
1612
+ "postcss": "^8.4.21"
1613
+ }
1614
+ },
1615
+ "node_modules/postcss-load-config": {
1616
+ "version": "4.0.2",
1617
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
1618
+ "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
1619
+ "dev": true,
1620
+ "funding": [
1621
+ {
1622
+ "type": "opencollective",
1623
+ "url": "https://opencollective.com/postcss/"
1624
+ },
1625
+ {
1626
+ "type": "github",
1627
+ "url": "https://github.com/sponsors/ai"
1628
+ }
1629
+ ],
1630
+ "license": "MIT",
1631
+ "dependencies": {
1632
+ "lilconfig": "^3.0.0",
1633
+ "yaml": "^2.3.4"
1634
+ },
1635
+ "engines": {
1636
+ "node": ">= 14"
1637
+ },
1638
+ "peerDependencies": {
1639
+ "postcss": ">=8.0.9",
1640
+ "ts-node": ">=9.0.0"
1641
+ },
1642
+ "peerDependenciesMeta": {
1643
+ "postcss": {
1644
+ "optional": true
1645
+ },
1646
+ "ts-node": {
1647
+ "optional": true
1648
+ }
1649
+ }
1650
+ },
1651
+ "node_modules/postcss-nested": {
1652
+ "version": "6.2.0",
1653
+ "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
1654
+ "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
1655
+ "dev": true,
1656
+ "funding": [
1657
+ {
1658
+ "type": "opencollective",
1659
+ "url": "https://opencollective.com/postcss/"
1660
+ },
1661
+ {
1662
+ "type": "github",
1663
+ "url": "https://github.com/sponsors/ai"
1664
+ }
1665
+ ],
1666
+ "license": "MIT",
1667
+ "dependencies": {
1668
+ "postcss-selector-parser": "^6.1.1"
1669
+ },
1670
+ "engines": {
1671
+ "node": ">=12.0"
1672
+ },
1673
+ "peerDependencies": {
1674
+ "postcss": "^8.2.14"
1675
+ }
1676
+ },
1677
+ "node_modules/postcss-selector-parser": {
1678
+ "version": "6.1.2",
1679
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
1680
+ "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
1681
+ "dev": true,
1682
+ "license": "MIT",
1683
+ "dependencies": {
1684
+ "cssesc": "^3.0.0",
1685
+ "util-deprecate": "^1.0.2"
1686
+ },
1687
+ "engines": {
1688
+ "node": ">=4"
1689
+ }
1690
+ },
1691
+ "node_modules/postcss-value-parser": {
1692
+ "version": "4.2.0",
1693
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
1694
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
1695
+ "dev": true,
1696
+ "license": "MIT"
1697
+ },
1698
+ "node_modules/prismjs": {
1699
+ "version": "1.29.0",
1700
+ "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
1701
+ "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==",
1702
+ "license": "MIT",
1703
+ "engines": {
1704
+ "node": ">=6"
1705
+ }
1706
+ },
1707
+ "node_modules/property-information": {
1708
+ "version": "5.6.0",
1709
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz",
1710
+ "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==",
1711
+ "license": "MIT",
1712
+ "dependencies": {
1713
+ "xtend": "^4.0.0"
1714
+ },
1715
+ "funding": {
1716
+ "type": "github",
1717
+ "url": "https://github.com/sponsors/wooorm"
1718
+ }
1719
+ },
1720
+ "node_modules/queue-microtask": {
1721
+ "version": "1.2.3",
1722
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
1723
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
1724
+ "dev": true,
1725
+ "funding": [
1726
+ {
1727
+ "type": "github",
1728
+ "url": "https://github.com/sponsors/feross"
1729
+ },
1730
+ {
1731
+ "type": "patreon",
1732
+ "url": "https://www.patreon.com/feross"
1733
+ },
1734
+ {
1735
+ "type": "consulting",
1736
+ "url": "https://feross.org/support"
1737
+ }
1738
+ ],
1739
+ "license": "MIT"
1740
+ },
1741
+ "node_modules/react": {
1742
+ "version": "18.3.1",
1743
+ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
1744
+ "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
1745
+ "license": "MIT",
1746
+ "dependencies": {
1747
+ "loose-envify": "^1.1.0"
1748
+ },
1749
+ "engines": {
1750
+ "node": ">=0.10.0"
1751
+ }
1752
+ },
1753
+ "node_modules/react-dom": {
1754
+ "version": "18.3.1",
1755
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
1756
+ "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
1757
+ "license": "MIT",
1758
+ "dependencies": {
1759
+ "loose-envify": "^1.1.0",
1760
+ "scheduler": "^0.23.2"
1761
+ },
1762
+ "peerDependencies": {
1763
+ "react": "^18.3.1"
1764
+ }
1765
+ },
1766
+ "node_modules/react-hot-toast": {
1767
+ "version": "2.5.2",
1768
+ "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.5.2.tgz",
1769
+ "integrity": "sha512-Tun3BbCxzmXXM7C+NI4qiv6lT0uwGh4oAfeJyNOjYUejTsm35mK9iCaYLGv8cBz9L5YxZLx/2ii7zsIwPtPUdw==",
1770
+ "dependencies": {
1771
+ "csstype": "^3.1.3",
1772
+ "goober": "^2.1.16"
1773
+ },
1774
+ "engines": {
1775
+ "node": ">=10"
1776
+ },
1777
+ "peerDependencies": {
1778
+ "react": ">=16",
1779
+ "react-dom": ">=16"
1780
+ }
1781
+ },
1782
+ "node_modules/react-syntax-highlighter": {
1783
+ "version": "15.6.1",
1784
+ "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.6.1.tgz",
1785
+ "integrity": "sha512-OqJ2/vL7lEeV5zTJyG7kmARppUjiB9h9udl4qHQjjgEos66z00Ia0OckwYfRxCSFrW8RJIBnsBwQsHZbVPspqg==",
1786
+ "license": "MIT",
1787
+ "dependencies": {
1788
+ "@babel/runtime": "^7.3.1",
1789
+ "highlight.js": "^10.4.1",
1790
+ "highlightjs-vue": "^1.0.0",
1791
+ "lowlight": "^1.17.0",
1792
+ "prismjs": "^1.27.0",
1793
+ "refractor": "^3.6.0"
1794
+ },
1795
+ "peerDependencies": {
1796
+ "react": ">= 0.14.0"
1797
+ }
1798
+ },
1799
+ "node_modules/read-cache": {
1800
+ "version": "1.0.0",
1801
+ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
1802
+ "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
1803
+ "dev": true,
1804
+ "license": "MIT",
1805
+ "dependencies": {
1806
+ "pify": "^2.3.0"
1807
+ }
1808
+ },
1809
+ "node_modules/readdirp": {
1810
+ "version": "3.6.0",
1811
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
1812
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
1813
+ "dev": true,
1814
+ "license": "MIT",
1815
+ "dependencies": {
1816
+ "picomatch": "^2.2.1"
1817
+ },
1818
+ "engines": {
1819
+ "node": ">=8.10.0"
1820
+ }
1821
+ },
1822
+ "node_modules/refractor": {
1823
+ "version": "3.6.0",
1824
+ "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz",
1825
+ "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==",
1826
+ "license": "MIT",
1827
+ "dependencies": {
1828
+ "hastscript": "^6.0.0",
1829
+ "parse-entities": "^2.0.0",
1830
+ "prismjs": "~1.27.0"
1831
+ },
1832
+ "funding": {
1833
+ "type": "github",
1834
+ "url": "https://github.com/sponsors/wooorm"
1835
+ }
1836
+ },
1837
+ "node_modules/refractor/node_modules/prismjs": {
1838
+ "version": "1.27.0",
1839
+ "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz",
1840
+ "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==",
1841
+ "license": "MIT",
1842
+ "engines": {
1843
+ "node": ">=6"
1844
+ }
1845
+ },
1846
+ "node_modules/regenerator-runtime": {
1847
+ "version": "0.14.1",
1848
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
1849
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
1850
+ "license": "MIT"
1851
+ },
1852
+ "node_modules/resolve": {
1853
+ "version": "1.22.10",
1854
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
1855
+ "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
1856
+ "dev": true,
1857
+ "license": "MIT",
1858
+ "dependencies": {
1859
+ "is-core-module": "^2.16.0",
1860
+ "path-parse": "^1.0.7",
1861
+ "supports-preserve-symlinks-flag": "^1.0.0"
1862
+ },
1863
+ "bin": {
1864
+ "resolve": "bin/resolve"
1865
+ },
1866
+ "engines": {
1867
+ "node": ">= 0.4"
1868
+ },
1869
+ "funding": {
1870
+ "url": "https://github.com/sponsors/ljharb"
1871
+ }
1872
+ },
1873
+ "node_modules/reusify": {
1874
+ "version": "1.0.4",
1875
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
1876
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
1877
+ "dev": true,
1878
+ "license": "MIT",
1879
+ "engines": {
1880
+ "iojs": ">=1.0.0",
1881
+ "node": ">=0.10.0"
1882
+ }
1883
+ },
1884
+ "node_modules/run-parallel": {
1885
+ "version": "1.2.0",
1886
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
1887
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
1888
+ "dev": true,
1889
+ "funding": [
1890
+ {
1891
+ "type": "github",
1892
+ "url": "https://github.com/sponsors/feross"
1893
+ },
1894
+ {
1895
+ "type": "patreon",
1896
+ "url": "https://www.patreon.com/feross"
1897
+ },
1898
+ {
1899
+ "type": "consulting",
1900
+ "url": "https://feross.org/support"
1901
+ }
1902
+ ],
1903
+ "license": "MIT",
1904
+ "dependencies": {
1905
+ "queue-microtask": "^1.2.2"
1906
+ }
1907
+ },
1908
+ "node_modules/scheduler": {
1909
+ "version": "0.23.2",
1910
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
1911
+ "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
1912
+ "license": "MIT",
1913
+ "dependencies": {
1914
+ "loose-envify": "^1.1.0"
1915
+ }
1916
+ },
1917
+ "node_modules/shebang-command": {
1918
+ "version": "2.0.0",
1919
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
1920
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
1921
+ "dev": true,
1922
+ "license": "MIT",
1923
+ "dependencies": {
1924
+ "shebang-regex": "^3.0.0"
1925
+ },
1926
+ "engines": {
1927
+ "node": ">=8"
1928
+ }
1929
+ },
1930
+ "node_modules/shebang-regex": {
1931
+ "version": "3.0.0",
1932
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
1933
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
1934
+ "dev": true,
1935
+ "license": "MIT",
1936
+ "engines": {
1937
+ "node": ">=8"
1938
+ }
1939
+ },
1940
+ "node_modules/signal-exit": {
1941
+ "version": "4.1.0",
1942
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
1943
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
1944
+ "dev": true,
1945
+ "license": "ISC",
1946
+ "engines": {
1947
+ "node": ">=14"
1948
+ },
1949
+ "funding": {
1950
+ "url": "https://github.com/sponsors/isaacs"
1951
+ }
1952
+ },
1953
+ "node_modules/source-map-js": {
1954
+ "version": "1.2.1",
1955
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
1956
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
1957
+ "license": "BSD-3-Clause",
1958
+ "engines": {
1959
+ "node": ">=0.10.0"
1960
+ }
1961
+ },
1962
+ "node_modules/space-separated-tokens": {
1963
+ "version": "1.1.5",
1964
+ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz",
1965
+ "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==",
1966
+ "license": "MIT",
1967
+ "funding": {
1968
+ "type": "github",
1969
+ "url": "https://github.com/sponsors/wooorm"
1970
+ }
1971
+ },
1972
+ "node_modules/streamsearch": {
1973
+ "version": "1.1.0",
1974
+ "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
1975
+ "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
1976
+ "engines": {
1977
+ "node": ">=10.0.0"
1978
+ }
1979
+ },
1980
+ "node_modules/string-width": {
1981
+ "version": "5.1.2",
1982
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
1983
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
1984
+ "dev": true,
1985
+ "license": "MIT",
1986
+ "dependencies": {
1987
+ "eastasianwidth": "^0.2.0",
1988
+ "emoji-regex": "^9.2.2",
1989
+ "strip-ansi": "^7.0.1"
1990
+ },
1991
+ "engines": {
1992
+ "node": ">=12"
1993
+ },
1994
+ "funding": {
1995
+ "url": "https://github.com/sponsors/sindresorhus"
1996
+ }
1997
+ },
1998
+ "node_modules/string-width-cjs": {
1999
+ "name": "string-width",
2000
+ "version": "4.2.3",
2001
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
2002
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
2003
+ "dev": true,
2004
+ "license": "MIT",
2005
+ "dependencies": {
2006
+ "emoji-regex": "^8.0.0",
2007
+ "is-fullwidth-code-point": "^3.0.0",
2008
+ "strip-ansi": "^6.0.1"
2009
+ },
2010
+ "engines": {
2011
+ "node": ">=8"
2012
+ }
2013
+ },
2014
+ "node_modules/string-width-cjs/node_modules/ansi-regex": {
2015
+ "version": "5.0.1",
2016
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
2017
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
2018
+ "dev": true,
2019
+ "license": "MIT",
2020
+ "engines": {
2021
+ "node": ">=8"
2022
+ }
2023
+ },
2024
+ "node_modules/string-width-cjs/node_modules/emoji-regex": {
2025
+ "version": "8.0.0",
2026
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
2027
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
2028
+ "dev": true,
2029
+ "license": "MIT"
2030
+ },
2031
+ "node_modules/string-width-cjs/node_modules/strip-ansi": {
2032
+ "version": "6.0.1",
2033
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2034
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2035
+ "dev": true,
2036
+ "license": "MIT",
2037
+ "dependencies": {
2038
+ "ansi-regex": "^5.0.1"
2039
+ },
2040
+ "engines": {
2041
+ "node": ">=8"
2042
+ }
2043
+ },
2044
+ "node_modules/strip-ansi": {
2045
+ "version": "7.1.0",
2046
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
2047
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
2048
+ "dev": true,
2049
+ "license": "MIT",
2050
+ "dependencies": {
2051
+ "ansi-regex": "^6.0.1"
2052
+ },
2053
+ "engines": {
2054
+ "node": ">=12"
2055
+ },
2056
+ "funding": {
2057
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
2058
+ }
2059
+ },
2060
+ "node_modules/strip-ansi-cjs": {
2061
+ "name": "strip-ansi",
2062
+ "version": "6.0.1",
2063
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2064
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2065
+ "dev": true,
2066
+ "license": "MIT",
2067
+ "dependencies": {
2068
+ "ansi-regex": "^5.0.1"
2069
+ },
2070
+ "engines": {
2071
+ "node": ">=8"
2072
+ }
2073
+ },
2074
+ "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
2075
+ "version": "5.0.1",
2076
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
2077
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
2078
+ "dev": true,
2079
+ "license": "MIT",
2080
+ "engines": {
2081
+ "node": ">=8"
2082
+ }
2083
+ },
2084
+ "node_modules/styled-jsx": {
2085
+ "version": "5.1.1",
2086
+ "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz",
2087
+ "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==",
2088
+ "license": "MIT",
2089
+ "dependencies": {
2090
+ "client-only": "0.0.1"
2091
+ },
2092
+ "engines": {
2093
+ "node": ">= 12.0.0"
2094
+ },
2095
+ "peerDependencies": {
2096
+ "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0"
2097
+ },
2098
+ "peerDependenciesMeta": {
2099
+ "@babel/core": {
2100
+ "optional": true
2101
+ },
2102
+ "babel-plugin-macros": {
2103
+ "optional": true
2104
+ }
2105
+ }
2106
+ },
2107
+ "node_modules/sucrase": {
2108
+ "version": "3.35.0",
2109
+ "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
2110
+ "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
2111
+ "dev": true,
2112
+ "license": "MIT",
2113
+ "dependencies": {
2114
+ "@jridgewell/gen-mapping": "^0.3.2",
2115
+ "commander": "^4.0.0",
2116
+ "glob": "^10.3.10",
2117
+ "lines-and-columns": "^1.1.6",
2118
+ "mz": "^2.7.0",
2119
+ "pirates": "^4.0.1",
2120
+ "ts-interface-checker": "^0.1.9"
2121
+ },
2122
+ "bin": {
2123
+ "sucrase": "bin/sucrase",
2124
+ "sucrase-node": "bin/sucrase-node"
2125
+ },
2126
+ "engines": {
2127
+ "node": ">=16 || 14 >=14.17"
2128
+ }
2129
+ },
2130
+ "node_modules/supports-preserve-symlinks-flag": {
2131
+ "version": "1.0.0",
2132
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
2133
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
2134
+ "dev": true,
2135
+ "license": "MIT",
2136
+ "engines": {
2137
+ "node": ">= 0.4"
2138
+ },
2139
+ "funding": {
2140
+ "url": "https://github.com/sponsors/ljharb"
2141
+ }
2142
+ },
2143
+ "node_modules/tailwindcss": {
2144
+ "version": "3.4.17",
2145
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz",
2146
+ "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==",
2147
+ "dev": true,
2148
+ "license": "MIT",
2149
+ "dependencies": {
2150
+ "@alloc/quick-lru": "^5.2.0",
2151
+ "arg": "^5.0.2",
2152
+ "chokidar": "^3.6.0",
2153
+ "didyoumean": "^1.2.2",
2154
+ "dlv": "^1.1.3",
2155
+ "fast-glob": "^3.3.2",
2156
+ "glob-parent": "^6.0.2",
2157
+ "is-glob": "^4.0.3",
2158
+ "jiti": "^1.21.6",
2159
+ "lilconfig": "^3.1.3",
2160
+ "micromatch": "^4.0.8",
2161
+ "normalize-path": "^3.0.0",
2162
+ "object-hash": "^3.0.0",
2163
+ "picocolors": "^1.1.1",
2164
+ "postcss": "^8.4.47",
2165
+ "postcss-import": "^15.1.0",
2166
+ "postcss-js": "^4.0.1",
2167
+ "postcss-load-config": "^4.0.2",
2168
+ "postcss-nested": "^6.2.0",
2169
+ "postcss-selector-parser": "^6.1.2",
2170
+ "resolve": "^1.22.8",
2171
+ "sucrase": "^3.35.0"
2172
+ },
2173
+ "bin": {
2174
+ "tailwind": "lib/cli.js",
2175
+ "tailwindcss": "lib/cli.js"
2176
+ },
2177
+ "engines": {
2178
+ "node": ">=14.0.0"
2179
+ }
2180
+ },
2181
+ "node_modules/thenify": {
2182
+ "version": "3.3.1",
2183
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
2184
+ "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
2185
+ "dev": true,
2186
+ "license": "MIT",
2187
+ "dependencies": {
2188
+ "any-promise": "^1.0.0"
2189
+ }
2190
+ },
2191
+ "node_modules/thenify-all": {
2192
+ "version": "1.6.0",
2193
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
2194
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
2195
+ "dev": true,
2196
+ "license": "MIT",
2197
+ "dependencies": {
2198
+ "thenify": ">= 3.1.0 < 4"
2199
+ },
2200
+ "engines": {
2201
+ "node": ">=0.8"
2202
+ }
2203
+ },
2204
+ "node_modules/to-regex-range": {
2205
+ "version": "5.0.1",
2206
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
2207
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
2208
+ "dev": true,
2209
+ "license": "MIT",
2210
+ "dependencies": {
2211
+ "is-number": "^7.0.0"
2212
+ },
2213
+ "engines": {
2214
+ "node": ">=8.0"
2215
+ }
2216
+ },
2217
+ "node_modules/ts-interface-checker": {
2218
+ "version": "0.1.13",
2219
+ "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
2220
+ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
2221
+ "dev": true,
2222
+ "license": "Apache-2.0"
2223
+ },
2224
+ "node_modules/tslib": {
2225
+ "version": "2.8.1",
2226
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
2227
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
2228
+ "license": "0BSD"
2229
+ },
2230
+ "node_modules/update-browserslist-db": {
2231
+ "version": "1.1.2",
2232
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz",
2233
+ "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==",
2234
+ "dev": true,
2235
+ "funding": [
2236
+ {
2237
+ "type": "opencollective",
2238
+ "url": "https://opencollective.com/browserslist"
2239
+ },
2240
+ {
2241
+ "type": "tidelift",
2242
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
2243
+ },
2244
+ {
2245
+ "type": "github",
2246
+ "url": "https://github.com/sponsors/ai"
2247
+ }
2248
+ ],
2249
+ "license": "MIT",
2250
+ "dependencies": {
2251
+ "escalade": "^3.2.0",
2252
+ "picocolors": "^1.1.1"
2253
+ },
2254
+ "bin": {
2255
+ "update-browserslist-db": "cli.js"
2256
+ },
2257
+ "peerDependencies": {
2258
+ "browserslist": ">= 4.21.0"
2259
+ }
2260
+ },
2261
+ "node_modules/util-deprecate": {
2262
+ "version": "1.0.2",
2263
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
2264
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
2265
+ "dev": true,
2266
+ "license": "MIT"
2267
+ },
2268
+ "node_modules/which": {
2269
+ "version": "2.0.2",
2270
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
2271
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
2272
+ "dev": true,
2273
+ "license": "ISC",
2274
+ "dependencies": {
2275
+ "isexe": "^2.0.0"
2276
+ },
2277
+ "bin": {
2278
+ "node-which": "bin/node-which"
2279
+ },
2280
+ "engines": {
2281
+ "node": ">= 8"
2282
+ }
2283
+ },
2284
+ "node_modules/wrap-ansi": {
2285
+ "version": "8.1.0",
2286
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
2287
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
2288
+ "dev": true,
2289
+ "license": "MIT",
2290
+ "dependencies": {
2291
+ "ansi-styles": "^6.1.0",
2292
+ "string-width": "^5.0.1",
2293
+ "strip-ansi": "^7.0.1"
2294
+ },
2295
+ "engines": {
2296
+ "node": ">=12"
2297
+ },
2298
+ "funding": {
2299
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
2300
+ }
2301
+ },
2302
+ "node_modules/wrap-ansi-cjs": {
2303
+ "name": "wrap-ansi",
2304
+ "version": "7.0.0",
2305
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
2306
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
2307
+ "dev": true,
2308
+ "license": "MIT",
2309
+ "dependencies": {
2310
+ "ansi-styles": "^4.0.0",
2311
+ "string-width": "^4.1.0",
2312
+ "strip-ansi": "^6.0.0"
2313
+ },
2314
+ "engines": {
2315
+ "node": ">=10"
2316
+ },
2317
+ "funding": {
2318
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
2319
+ }
2320
+ },
2321
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
2322
+ "version": "5.0.1",
2323
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
2324
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
2325
+ "dev": true,
2326
+ "license": "MIT",
2327
+ "engines": {
2328
+ "node": ">=8"
2329
+ }
2330
+ },
2331
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
2332
+ "version": "4.3.0",
2333
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
2334
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
2335
+ "dev": true,
2336
+ "license": "MIT",
2337
+ "dependencies": {
2338
+ "color-convert": "^2.0.1"
2339
+ },
2340
+ "engines": {
2341
+ "node": ">=8"
2342
+ },
2343
+ "funding": {
2344
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
2345
+ }
2346
+ },
2347
+ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
2348
+ "version": "8.0.0",
2349
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
2350
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
2351
+ "dev": true,
2352
+ "license": "MIT"
2353
+ },
2354
+ "node_modules/wrap-ansi-cjs/node_modules/string-width": {
2355
+ "version": "4.2.3",
2356
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
2357
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
2358
+ "dev": true,
2359
+ "license": "MIT",
2360
+ "dependencies": {
2361
+ "emoji-regex": "^8.0.0",
2362
+ "is-fullwidth-code-point": "^3.0.0",
2363
+ "strip-ansi": "^6.0.1"
2364
+ },
2365
+ "engines": {
2366
+ "node": ">=8"
2367
+ }
2368
+ },
2369
+ "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
2370
+ "version": "6.0.1",
2371
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2372
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2373
+ "dev": true,
2374
+ "license": "MIT",
2375
+ "dependencies": {
2376
+ "ansi-regex": "^5.0.1"
2377
+ },
2378
+ "engines": {
2379
+ "node": ">=8"
2380
+ }
2381
+ },
2382
+ "node_modules/xtend": {
2383
+ "version": "4.0.2",
2384
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
2385
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
2386
+ "license": "MIT",
2387
+ "engines": {
2388
+ "node": ">=0.4"
2389
+ }
2390
+ },
2391
+ "node_modules/yaml": {
2392
+ "version": "2.7.0",
2393
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz",
2394
+ "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==",
2395
+ "dev": true,
2396
+ "license": "ISC",
2397
+ "bin": {
2398
+ "yaml": "bin.mjs"
2399
+ },
2400
+ "engines": {
2401
+ "node": ">= 14"
2402
+ }
2403
+ }
2404
+ }
2405
+ }
package.json ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "word-to-code",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev",
7
+ "build": "next build",
8
+ "start": "next start",
9
+ "lint": "next lint"
10
+ },
11
+ "dependencies": {
12
+ "@ffmpeg/ffmpeg": "^0.12.15",
13
+ "@ffmpeg/util": "^0.12.2",
14
+ "@google/generative-ai": "^0.21.0",
15
+ "gif.js": "^0.2.0",
16
+ "lucide-react": "^0.330.0",
17
+ "next": "14.1.0",
18
+ "p5": "^1.9.0",
19
+ "react": "^18",
20
+ "react-dom": "^18",
21
+ "react-hot-toast": "^2.5.2",
22
+ "react-syntax-highlighter": "^15.5.0"
23
+ },
24
+ "devDependencies": {
25
+ "autoprefixer": "^10.0.1",
26
+ "postcss": "^8",
27
+ "tailwindcss": "^3.3.0"
28
+ }
29
+ }
pages/_app.js ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import '@/styles/globals.css';
2
+ import { Inter } from 'next/font/google';
3
+
4
+ const inter = Inter({
5
+ subsets: ['latin'],
6
+ display: 'swap',
7
+ variable: '--font-inter',
8
+ });
9
+
10
+ export default function App({ Component, pageProps }) {
11
+ return (
12
+ <div className={`${inter.variable} font-sans`}>
13
+ <Component {...pageProps} />
14
+ </div>
15
+ );
16
+ }
pages/_document.js ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Html, Head, Main, NextScript } from "next/document";
2
+
3
+ export default function Document() {
4
+ return (
5
+ <Html lang="en">
6
+ <Head />
7
+ <body className="antialiased">
8
+ <Main />
9
+ <NextScript />
10
+ </body>
11
+ </Html>
12
+ );
13
+ }
pages/api/generate.js ADDED
@@ -0,0 +1,792 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const {
2
+ GoogleGenerativeAI,
3
+ HarmCategory,
4
+ HarmBlockThreshold,
5
+ } = require("@google/generative-ai");
6
+
7
+ const apiKey = process.env.GEMINI_API_KEY;
8
+ const genAI = new GoogleGenerativeAI(apiKey);
9
+
10
+ const model = genAI.getGenerativeModel({
11
+ model: "gemini-2.0-flash-thinking-exp-01-21",
12
+ safetySettings: [
13
+ {
14
+ category: HarmCategory.HARM_CATEGORY_HARASSMENT,
15
+ threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
16
+ },
17
+ {
18
+ category: HarmCategory.HARM_CATEGORY_HATE_SPEECH,
19
+ threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
20
+ },
21
+ {
22
+ category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT,
23
+ threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
24
+ },
25
+ {
26
+ category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
27
+ threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
28
+ },
29
+ ],
30
+ });
31
+
32
+ const generationConfig = {
33
+ temperature: 0.7,
34
+ topP: 0.95,
35
+ topK: 64,
36
+ maxOutputTokens: 65536,
37
+ };
38
+
39
+ const systemPrompt = `You are a creative coding expert specializing in p5.js animations. Given a single word, you create expressive looping animations that bring that word to life using particle systems.
40
+
41
+ Here are example animations that show different particle behaviors, along with the reasoning behind each approach:
42
+
43
+ EXAMPLE 1 - "fluid":
44
+ Reasoning: To capture the essence of "fluid", I'll use Perlin noise to create smooth, organic movement of particles. The particles will flow like water or liquid, with each particle following its own noise-based path while maintaining a cohesive, flowing appearance. The blue gradient colors reinforce the liquid feeling, and the screen blend mode creates a glowing effect that enhances the fluid motion.
45
+
46
+ Code:
47
+ let font;
48
+ let fontSize = 200;
49
+ let word = "fluid";
50
+ let points;
51
+ let particles = [];
52
+ let particleMinSize = 3;
53
+ let particleMaxSize = 7;
54
+
55
+ // Fluid effect parameters
56
+ let noiseScale = 0.015; // Scale of the Perlin noise - adjust for wave size
57
+ let noiseStrength = 20; // Intensity of the noise displacement
58
+ let noiseSpeed = 0.002; // Speed of the noise evolution
59
+
60
+ // Colors for gradient
61
+ let color1 = "#217BFE";
62
+ let color2 = "#078BFE";
63
+ let color3 = "#AC87EB";
64
+
65
+ function preload() {
66
+ font = loadFont('/fonts/GoogleSans-Bold.ttf');
67
+ }
68
+
69
+ function setup() {
70
+ createCanvas(500, 500);
71
+ background(0);
72
+ textFont(font);
73
+ textSize(fontSize);
74
+ textAlign(CENTER, CENTER);
75
+
76
+ // Get the width of the text
77
+ let textW = textWidth(word);
78
+
79
+ // If text is too wide, scale down fontSize
80
+ if (textW > width * 0.8) {
81
+ fontSize = fontSize * (width * 0.8) / textW;
82
+ textSize(fontSize);
83
+ textW = textWidth(word);
84
+ }
85
+
86
+ points = font.textToPoints(word, width/2 - textW/2, height/2 + fontSize/3, fontSize, {
87
+ sampleFactor: 0.1
88
+ });
89
+
90
+ for (let i = 0; i < points.length; i++) {
91
+ particles.push(new Particle(points[i].x, points[i].y, i, points.length));
92
+ }
93
+ }
94
+
95
+ function draw() {
96
+ blendMode(BLEND); // Reset to default blend mode first
97
+ background(0); // Clear with black background
98
+ blendMode(SCREEN); // Then set screen blend mode for particles
99
+
100
+ for (let particle of particles) {
101
+ particle.update();
102
+ particle.display();
103
+ }
104
+ }
105
+
106
+ class Particle {
107
+ constructor(x, y, index, totalParticles) {
108
+ this.pos = createVector(x, y);
109
+ this.originalPos = createVector(x, y);
110
+ this.originalX = x;
111
+ this.originalY = y;
112
+ this.size = random(particleMinSize, particleMaxSize);
113
+ this.alpha = 255;
114
+ this.colorValue = this.getColor(index, totalParticles);
115
+ }
116
+
117
+ getColor(index, totalParticles) {
118
+ let normalizedIndex = index / (totalParticles - 1);
119
+ let particleColor;
120
+ if (normalizedIndex < 0.5) {
121
+ particleColor = lerpColor(color(color1), color(color2), normalizedIndex * 2);
122
+ } else {
123
+ particleColor = lerpColor(color(color2), color(color3), (normalizedIndex - 0.5) * 2);
124
+ }
125
+ return particleColor;
126
+ }
127
+
128
+ update() {
129
+ let noiseValueX = noise((this.originalX + frameCount) * noiseScale,
130
+ this.originalY * noiseScale,
131
+ frameCount * noiseSpeed);
132
+ let noiseValueY = noise(this.originalX * noiseScale,
133
+ this.originalY * noiseScale,
134
+ frameCount * noiseSpeed + 1000);
135
+
136
+ let offsetX = map(noiseValueX, 0, 1, -noiseStrength, noiseStrength);
137
+ let offsetY = map(noiseValueY, 0, 1, -noiseStrength, noiseStrength);
138
+
139
+ this.pos.x = this.originalPos.x + offsetX;
140
+ this.pos.y = this.originalPos.y + offsetY;
141
+ }
142
+
143
+ display() {
144
+ noStroke();
145
+ fill(this.colorValue);
146
+ ellipse(this.pos.x, this.pos.y, this.size, this.size);
147
+ }
148
+ }
149
+
150
+ EXAMPLE 2 - "rise":
151
+ Reasoning: For "rise", I'll create a staged animation where particles gradually appear, pause briefly, then float upward. This creates a sense of emergence and ascension. Each particle follows this sequence independently with slight timing variations, creating a continuous cycle of rising elements. The fade-in adds a gentle, ethereal quality that matches the upward motion.
152
+
153
+ Code:
154
+ let font;
155
+ let fontSize = 200;
156
+ let word = "rise";
157
+ let points;
158
+ let particles = [];
159
+ let floatSpeed = 4;
160
+ let fadeInSpeed = 10;
161
+ let minWaitTime = 50;
162
+ let maxWaitTime = 200;
163
+ let particleMinSize = 3;
164
+ let particleMaxSize = 7;
165
+
166
+ let color1 = "#217BFE";
167
+ let color2 = "#078BFE";
168
+ let color3 = "#AC87EB";
169
+
170
+ function preload() {
171
+ font = loadFont('/fonts/GoogleSans-Bold.ttf');
172
+ }
173
+
174
+ function setup() {
175
+ createCanvas(500, 500);
176
+ background(0);
177
+ textFont(font);
178
+ textSize(fontSize);
179
+ textAlign(CENTER, CENTER);
180
+
181
+ // Get the width of the text
182
+ let textW = textWidth(word);
183
+
184
+ // If text is too wide, scale down fontSize
185
+ if (textW > width * 0.8) {
186
+ fontSize = fontSize * (width * 0.8) / textW;
187
+ textSize(fontSize);
188
+ textW = textWidth(word);
189
+ }
190
+
191
+ points = font.textToPoints(word, width/2 - textW/2, height/2 + fontSize/3, fontSize, {
192
+ sampleFactor: 0.1
193
+ });
194
+
195
+ // Find min and max x positions for color gradient
196
+ let minX = points[0].x;
197
+ let maxX = points[0].x;
198
+ for (let pt of points) {
199
+ minX = min(minX, pt.x);
200
+ maxX = max(maxX, pt.x);
201
+ }
202
+ let xRange = maxX - minX;
203
+
204
+ for (let pt of points) {
205
+ particles.push(new Particle(pt.x, pt.y, pt.x, minX, xRange));
206
+ }
207
+ }
208
+
209
+ function draw() {
210
+ blendMode(BLEND);
211
+ background(0);
212
+ blendMode(SCREEN);
213
+
214
+ for (let particle of particles) {
215
+ particle.update();
216
+ particle.display();
217
+ }
218
+ }
219
+
220
+ class Particle {
221
+ constructor(x, y, particleX, minX, xRange) {
222
+ this.pos = createVector(x, y);
223
+ this.originalPos = createVector(x, y);
224
+ this.size = random(particleMinSize, particleMaxSize);
225
+ this.alpha = 255;
226
+ this.floatSpeedVariation = random(0.5, 2.0);
227
+ this.isFadingIn = true;
228
+ this.isWaiting = false;
229
+ this.waitTime = 0;
230
+ this.particleX = particleX;
231
+ this.minX = minX;
232
+ this.xRange = xRange;
233
+ this.color = this.getColorForPosition();
234
+ }
235
+
236
+ getColorForPosition() {
237
+ let normalizedX = 0;
238
+ if (this.xRange > 0) {
239
+ normalizedX = constrain((this.particleX - this.minX) / this.xRange, 0, 1);
240
+ }
241
+
242
+ let particleColor;
243
+ if (normalizedX < 0.5) {
244
+ particleColor = lerpColor(color(color1), color(color2), normalizedX * 2);
245
+ } else {
246
+ particleColor = lerpColor(color(color2), color(color3), (normalizedX - 0.5) * 2);
247
+ }
248
+ return particleColor;
249
+ }
250
+
251
+ update() {
252
+ if (this.isFadingIn) {
253
+ this.alpha += fadeInSpeed;
254
+ if (this.alpha >= 255) {
255
+ this.alpha = 255;
256
+ this.isFadingIn = false;
257
+ this.isWaiting = true;
258
+ this.waitTime = floor(random(minWaitTime, maxWaitTime));
259
+ }
260
+ } else if (this.isWaiting) {
261
+ this.waitTime--;
262
+ if (this.waitTime <= 0) {
263
+ this.isWaiting = false;
264
+ }
265
+ } else {
266
+ this.pos.y -= floatSpeed * this.floatSpeedVariation;
267
+ if (this.pos.y < -this.size) {
268
+ this.respawn();
269
+ }
270
+ }
271
+ }
272
+
273
+ respawn() {
274
+ this.pos.y = this.originalPos.y;
275
+ this.pos.x = this.originalPos.x;
276
+ this.alpha = 0;
277
+ this.isFadingIn = true;
278
+ this.isWaiting = false;
279
+ this.waitTime = 0;
280
+ this.size = random(particleMinSize, particleMaxSize);
281
+ this.floatSpeedVariation = random(0.5, 2.0);
282
+ this.color = this.getColorForPosition();
283
+ }
284
+
285
+ display() {
286
+ noStroke();
287
+ fill(red(this.color), green(this.color), blue(this.color), this.alpha);
288
+ ellipse(this.pos.x, this.pos.y, this.size, this.size);
289
+ }
290
+ }
291
+
292
+ EXAMPLE 3 - "light":
293
+ Reasoning: To visualize "light", I'll make particles that pulse and glow like twinkling lights. Each particle will cycle through brightness levels independently, creating a sparkling effect. Adding blur and glow effects when particles are at peak brightness enhances the illuminated feeling. The gradient colors blend into white at maximum brightness for a true lighting effect.
294
+
295
+ Code:
296
+ let font;
297
+ let fontSize = 200;
298
+ let word = "light";
299
+ let points;
300
+ let particles = [];
301
+ let lightCycleSpeed = 0.02;
302
+ let particleMinSize = 5;
303
+ let particleMaxSize = 5;
304
+ let shadowBlurAmount = 30;
305
+ let minX, maxX;
306
+
307
+ let color1 = "#217BFE";
308
+ let color2 = "#078BFE";
309
+ let color3 = "#AC87EB";
310
+ let lightColor;
311
+
312
+ function preload() {
313
+ font = loadFont('/fonts/GoogleSans-Bold.ttf');
314
+ }
315
+
316
+ function setup() {
317
+ createCanvas(500, 500);
318
+ background(0);
319
+
320
+ lightColor = color(255, 255, 255);
321
+
322
+ textFont(font);
323
+ textSize(fontSize);
324
+ textAlign(CENTER, CENTER);
325
+
326
+ // Get the width of the text
327
+ let textW = textWidth(word);
328
+
329
+ // If text is too wide, scale down fontSize
330
+ if (textW > width * 0.8) {
331
+ fontSize = fontSize * (width * 0.8) / textW;
332
+ textSize(fontSize);
333
+ textW = textWidth(word);
334
+ }
335
+
336
+ points = font.textToPoints(word, width/2 - textW/2, height/2 + fontSize/3, fontSize, {
337
+ sampleFactor: 0.1
338
+ });
339
+
340
+ minX = width;
341
+ maxX = 0;
342
+ for (let pt of points) {
343
+ minX = min(minX, pt.x);
344
+ maxX = max(maxX, pt.x);
345
+ }
346
+
347
+ for (let i = 0; i < points.length; i++) {
348
+ let pt = points[i];
349
+ particles.push(new Particle(pt.x, pt.y, i));
350
+ }
351
+ }
352
+
353
+ function draw() {
354
+ blendMode(BLEND); // Reset to default blend mode first
355
+ background(0); // Clear with black background
356
+ blendMode(SCREEN); // Then set screen blend mode for particles
357
+
358
+ for (let particle of particles) {
359
+ particle.update();
360
+ particle.display();
361
+ }
362
+ }
363
+
364
+ class Particle {
365
+ constructor(x, y, index) {
366
+ this.pos = createVector(x, y);
367
+ this.size = random(particleMinSize, particleMaxSize);
368
+ this.alpha = 255;
369
+ this.lightOffset = index * 0.1;
370
+ }
371
+
372
+ update() {
373
+ // No position update needed for light animation
374
+ }
375
+
376
+ getBaseColor() {
377
+ let normalizedX = map(this.pos.x, minX, maxX, 0, 1);
378
+ let baseParticleColor;
379
+
380
+ if (normalizedX < 0.5) {
381
+ baseParticleColor = lerpColor(color(color1), color(color2), normalizedX * 2);
382
+ } else {
383
+ baseParticleColor = lerpColor(color(color2), color(color3), (normalizedX - 0.5) * 2);
384
+ }
385
+ return baseParticleColor;
386
+ }
387
+
388
+ display() {
389
+ let brightness = sin(frameCount * lightCycleSpeed + this.lightOffset);
390
+ brightness = map(brightness, -1, 1, 0, 1);
391
+ brightness = constrain(brightness, 0, 1);
392
+
393
+ let baseParticleColor = this.getBaseColor();
394
+ let particleColor = lerpColor(baseParticleColor, lightColor, brightness);
395
+
396
+ noStroke();
397
+
398
+ if (brightness > 0.8) {
399
+ drawingContext.shadowBlur = shadowBlurAmount;
400
+ drawingContext.shadowColor = color(255);
401
+ fill(particleColor);
402
+ ellipse(this.pos.x, this.pos.y, this.size * 1.5, this.size * 1.5);
403
+ drawingContext.shadowBlur = 0;
404
+ } else {
405
+ drawingContext.shadowBlur = 0;
406
+ fill(particleColor);
407
+ ellipse(this.pos.x, this.pos.y, this.size, this.size);
408
+ }
409
+ }
410
+ }
411
+
412
+ EXAMPLE 4 - "travel":
413
+ Reasoning: For "travel", particles will journey along the letter contours, creating a sense of continuous movement and exploration. Each particle follows the path of letter points, creating flowing trails that highlight the shape of the text. The movement speed and particle size are tuned to maintain legibility while conveying constant motion.
414
+
415
+ Code:
416
+ let font;
417
+ let fontSize = 200;
418
+ let word = "travel";
419
+ let points;
420
+ let particles = [];
421
+ let travelSpeed = 0.8;
422
+ let particleMinSize = 4;
423
+ let particleMaxSize = 4;
424
+ let minX, maxX;
425
+
426
+ let color1 = "#217BFE";
427
+ let color2 = "#078BFE";
428
+ let color3 = "#AC87EB";
429
+
430
+ function preload() {
431
+ font = loadFont('/fonts/GoogleSans-Bold.ttf');
432
+ }
433
+
434
+ function setup() {
435
+ createCanvas(500, 500);
436
+ background(0);
437
+ textFont(font);
438
+ textSize(fontSize);
439
+ textAlign(CENTER, CENTER);
440
+
441
+ // Get the width of the text
442
+ let textW = textWidth(word);
443
+
444
+ // If text is too wide, scale down fontSize
445
+ if (textW > width * 0.8) {
446
+ fontSize = fontSize * (width * 0.8) / textW;
447
+ textSize(fontSize);
448
+ textW = textWidth(word);
449
+ }
450
+
451
+ points = font.textToPoints(word, width/2 - textW/2, height/2 + fontSize/3, fontSize, {
452
+ sampleFactor: 0.1
453
+ });
454
+
455
+ minX = width;
456
+ maxX = 0;
457
+ for (let pt of points) {
458
+ minX = min(minX, pt.x);
459
+ maxX = max(maxX, pt.x);
460
+ }
461
+
462
+ for (let i = 0; i < points.length; i++) {
463
+ let pt = points[i];
464
+ particles.push(new Particle(pt.x, pt.y, i, points));
465
+ }
466
+ }
467
+
468
+ function draw() {
469
+ blendMode(BLEND); // Reset to default blend mode first
470
+ background(0); // Clear with black background
471
+ blendMode(SCREEN); // Then set screen blend mode for particles
472
+
473
+ for (let particle of particles) {
474
+ particle.update();
475
+ particle.display();
476
+ }
477
+ }
478
+
479
+ class Particle {
480
+ constructor(x, y, index, allPoints) {
481
+ this.pos = createVector(x, y);
482
+ this.size = random(particleMinSize, particleMaxSize);
483
+ this.alpha = 255;
484
+ this.pointIndex = index;
485
+ this.points = allPoints;
486
+ this.targetPoint = this.getNextTargetPoint();
487
+ }
488
+
489
+ getNextTargetPoint() {
490
+ if (this.points.length === 0) return this.pos;
491
+
492
+ this.pointIndex++;
493
+ if (this.pointIndex >= this.points.length) {
494
+ this.pointIndex = 0;
495
+ }
496
+ return createVector(this.points[this.pointIndex].x, this.points[this.pointIndex].y);
497
+ }
498
+
499
+ update() {
500
+ if (!this.targetPoint) return;
501
+
502
+ let direction = p5.Vector.sub(this.targetPoint, this.pos);
503
+ let distance = direction.mag();
504
+
505
+ if (distance < 1) {
506
+ this.targetPoint = this.getNextTargetPoint();
507
+ if (!this.targetPoint) return;
508
+ direction = p5.Vector.sub(this.targetPoint, this.pos);
509
+ }
510
+
511
+ direction.normalize();
512
+ direction.mult(travelSpeed);
513
+ this.pos.add(direction);
514
+ }
515
+
516
+ display() {
517
+ noStroke();
518
+ let normalizedX = map(this.pos.x, minX, maxX, 0, 1, true);
519
+ let particleColor = this.getColorBlend(normalizedX);
520
+ fill(particleColor);
521
+ ellipse(this.pos.x, this.pos.y, this.size, this.size);
522
+ }
523
+
524
+ getColorBlend(normalizedX) {
525
+ if (normalizedX < 0.5) {
526
+ return lerpColor(color(color1), color(color2), normalizedX * 2);
527
+ } else {
528
+ return lerpColor(color(color2), color(color3), (normalizedX - 0.5) * 2);
529
+ }
530
+ }
531
+ }
532
+
533
+ EXAMPLE 5 - "bounce":
534
+ Reasoning: To represent "bounce", I'll implement simple physics with gravity and elastic collision. Particles fall and bounce off surfaces with dampening, creating a playful and dynamic animation. The varying particle sizes and bounce heights add visual interest while maintaining the word's readability.
535
+
536
+ Code:
537
+ let font;
538
+ let fontSize = 200;
539
+ let word = "bounce";
540
+ let points;
541
+ let particles = [];
542
+ let gravity = 0.5;
543
+ let bounce = -0.7;
544
+ let friction = 0.99;
545
+ let particleMinSize = 3;
546
+ let particleMaxSize = 7;
547
+
548
+ let color1 = "#217BFE";
549
+ let color2 = "#078BFE";
550
+ let color3 = "#AC87EB";
551
+
552
+ function preload() {
553
+ font = loadFont('/fonts/GoogleSans-Bold.ttf');
554
+ }
555
+
556
+ function setup() {
557
+ createCanvas(500, 500);
558
+ background(0);
559
+ textFont(font);
560
+ textSize(fontSize);
561
+ textAlign(CENTER, CENTER);
562
+
563
+ // Get the width of the text
564
+ let textW = textWidth(word);
565
+
566
+ // If text is too wide, scale down fontSize
567
+ if (textW > width * 0.8) {
568
+ fontSize = fontSize * (width * 0.8) / textW;
569
+ textSize(fontSize);
570
+ textW = textWidth(word);
571
+ }
572
+
573
+ points = font.textToPoints(word, width/2 - textW/2, height/2 + fontSize/3, fontSize, {
574
+ sampleFactor: 0.1
575
+ });
576
+
577
+ // Find min and max x positions for color gradient
578
+ let minX = points[0].x;
579
+ let maxX = points[0].x;
580
+ for (let pt of points) {
581
+ minX = min(minX, pt.x);
582
+ maxX = max(maxX, pt.x);
583
+ }
584
+
585
+ for (let pt of points) {
586
+ let normalizedX = map(pt.x, minX, maxX, 0, 1);
587
+ particles.push(new Particle(pt.x, pt.y, normalizedX));
588
+ }
589
+ }
590
+
591
+ function draw() {
592
+ blendMode(BLEND);
593
+ background(0);
594
+ blendMode(SCREEN);
595
+
596
+ for (let particle of particles) {
597
+ particle.update();
598
+ particle.display();
599
+ }
600
+ }
601
+
602
+ class Particle {
603
+ constructor(x, y, normalizedX) {
604
+ this.pos = createVector(x, y);
605
+ this.vel = createVector(random(-2, 2), random(-10, -5));
606
+ this.acc = createVector(0, gravity);
607
+ this.size = random(particleMinSize, particleMaxSize);
608
+ this.originalY = y;
609
+ this.colorValue = this.getColor(normalizedX);
610
+ }
611
+
612
+ getColor(normalizedX) {
613
+ let particleColor;
614
+ if (normalizedX < 0.5) {
615
+ particleColor = lerpColor(color(color1), color(color2), normalizedX * 2);
616
+ } else {
617
+ particleColor = lerpColor(color(color2), color(color3), (normalizedX - 0.5) * 2);
618
+ }
619
+ return particleColor;
620
+ }
621
+
622
+ update() {
623
+ this.vel.add(this.acc);
624
+ this.pos.add(this.vel);
625
+ this.vel.x *= friction;
626
+
627
+ if (this.pos.y > height - this.size/2) {
628
+ this.pos.y = height - this.size/2;
629
+ this.vel.y *= bounce;
630
+ }
631
+
632
+ if (this.pos.x < this.size/2) {
633
+ this.pos.x = this.size/2;
634
+ this.vel.x *= bounce;
635
+ } else if (this.pos.x > width - this.size/2) {
636
+ this.pos.x = width - this.size/2;
637
+ this.vel.x *= bounce;
638
+ }
639
+
640
+ // Reset particle if it goes too far down
641
+ if (this.pos.y > height + 100) {
642
+ this.pos.y = this.originalY;
643
+ this.vel.y = random(-10, -5);
644
+ }
645
+ }
646
+
647
+ display() {
648
+ noStroke();
649
+ fill(this.colorValue);
650
+ ellipse(this.pos.x, this.pos.y, this.size, this.size);
651
+ }
652
+ }
653
+
654
+ Your task is to create a similar p5.js sketch for the given word. Follow these rules:
655
+ Keep all the consistent elements:
656
+ - Looping
657
+ - Canvas size: 500x500
658
+ - Font: GoogleSans-Bold.ttf
659
+ - Initial fontSize: 200 (will adjust automatically)
660
+ - ALWAYS Colors: #217BFE, #078BFE, #AC87EB gradient
661
+ - Text alignment: CENTER, CENTER
662
+ - Proper text centering using textWidth()
663
+ - IMPORTANT: Always position text vertically using: height/2 + fontSize/3
664
+
665
+ Return ONLY the complete p5.js code in global mode format, with all necessary functions (preload, setup, draw) and variables defined globally.`;
666
+
667
+ export default async function handler(req, res) {
668
+ if (req.method !== 'POST') {
669
+ return res.status(405).json({ message: 'Method not allowed' });
670
+ }
671
+
672
+ try {
673
+ const { word, instructions } = req.body;
674
+
675
+ if (!word) {
676
+ return res.status(400).json({ message: 'Word is required' });
677
+ }
678
+
679
+ const prompt = `Create a p5.js animation for the word "${word}"${instructions ? ` with these additional requirements: ${instructions}` : ''}.
680
+
681
+ First, explain your creative approach:
682
+ - How will you animate this word to reflect its meaning?
683
+ - What particle behaviors and effects will you use?
684
+ - How will these choices enhance the viewer's understanding of the word?
685
+
686
+ Then provide the complete p5.js sketch code using these requirements:
687
+ - Canvas size of 500x500
688
+ - Black background
689
+ - Font loading from '/fonts/GoogleSans-Bold.ttf'
690
+ - Gradient colors using #217BFE, #078BFE, and #AC87EB
691
+ - Screen blend mode for particles
692
+ - Responsive text sizing
693
+ - Global mode format (no instance mode wrapper)
694
+
695
+ Animation timing requirements:
696
+ - Start with particles clearly forming the word on the screen
697
+ - If particles move away from the word, they should do so gradually
698
+ - For any cycling animations, ensure each cycle is slow enough to read the word
699
+
700
+ Your response MUST follow this exact format:
701
+
702
+ Reasoning:
703
+ [Your explanation here]
704
+
705
+ Code:
706
+ [Your code here in global mode format]
707
+
708
+ Make sure your code is complete and properly closed with all necessary brackets.`;
709
+
710
+ const result = await model.generateContent([systemPrompt, prompt], generationConfig);
711
+ const response = await result.response;
712
+ const text = response.text();
713
+
714
+ console.log('Raw model response:', text); // Debug log
715
+
716
+ // Extract reasoning and code using multiple fallback approaches
717
+ let reasoning = '';
718
+ let code = '';
719
+
720
+ // Helper function to clean code
721
+ const cleanCode = (str) => {
722
+ return str
723
+ .replace(/```javascript\s*/g, '')
724
+ .replace(/```js\s*/g, '')
725
+ .replace(/```\s*/g, '')
726
+ .replace(/^Code:\s*/g, '')
727
+ .trim();
728
+ };
729
+
730
+ // Helper function to validate global mode code
731
+ const isValidCode = (str) => {
732
+ return str.includes('function setup()') &&
733
+ str.includes('function draw()') &&
734
+ str.includes('function preload()') &&
735
+ (str.match(/{/g) || []).length === (str.match(/}/g) || []).length; // Check balanced braces
736
+ };
737
+
738
+ // Approach 1: Try to extract from markdown code blocks
739
+ const codeBlockMatch = text.match(/```(?:javascript|js)?\s*(let\s+font[\s\S]*?class\s+Particle[\s\S]*?})\s*```/);
740
+ if (codeBlockMatch) {
741
+ code = cleanCode(codeBlockMatch[1]);
742
+ reasoning = text.split('```')[0].replace(/^Reasoning:\s*/i, '').trim();
743
+ }
744
+
745
+ // Approach 2: Try to split by explicit "Reasoning:" and "Code:" markers
746
+ if (!code && text.includes('Reasoning:') && text.includes('Code:')) {
747
+ const [reasoningPart, codePart] = text.split(/Code:\s*/i);
748
+ reasoning = reasoningPart.replace(/^Reasoning:\s*/i, '').trim();
749
+ code = cleanCode(codePart);
750
+ }
751
+
752
+ // Approach 3: Look for global mode function declarations
753
+ if (!code) {
754
+ const functionMatch = text.match(/(let\s+font[\s\S]*function\s+setup\(\)[\s\S]*function\s+draw\(\)[\s\S]*class\s+Particle[\s\S]*$)/);
755
+ if (functionMatch) {
756
+ code = cleanCode(functionMatch[1]);
757
+ reasoning = text.split(functionMatch[1])[0].replace(/^Reasoning:\s*/i, '').trim();
758
+ }
759
+ }
760
+
761
+ // Approach 4: Most aggressive - find anything that looks like the global mode structure
762
+ if (!code) {
763
+ const lastResortMatch = text.match(/let\s+font[\s\S]*?class\s+Particle[\s\S]*?}/);
764
+ if (lastResortMatch) {
765
+ code = cleanCode(lastResortMatch[0]);
766
+ reasoning = text.replace(lastResortMatch[0], '').replace(/^Reasoning:\s*/i, '').trim();
767
+ }
768
+ }
769
+
770
+ // Final validation
771
+ if (!code || !isValidCode(code)) {
772
+ console.error('Invalid code structure:', { code: code?.substring(0, 100) });
773
+ throw new Error('Could not extract valid p5.js sketch code from the response');
774
+ }
775
+
776
+ console.log('Successfully parsed response:', {
777
+ reasoningPreview: reasoning?.substring(0, 100) + '...',
778
+ codePreview: code?.substring(0, 100) + '...',
779
+ });
780
+
781
+ return res.status(200).json({
782
+ code,
783
+ fullResponse: reasoning || 'No explanation provided'
784
+ });
785
+ } catch (error) {
786
+ console.error('Error generating animation:', error);
787
+ return res.status(500).json({
788
+ message: 'Error generating animation',
789
+ error: error.message
790
+ });
791
+ }
792
+ }
pages/api/hello.js ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2
+
3
+ export default function handler(req, res) {
4
+ res.status(200).json({ name: "John Doe" });
5
+ }
pages/index.js ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useState } from 'react';
2
+ import Script from 'next/script';
3
+ import { Inter } from 'next/font/google';
4
+ import SketchRenderer from '../components/SketchRenderer';
5
+ import GenerationForm from '../components/GenerationForm';
6
+ import CodePanel from '../components/CodePanel';
7
+ import { initialSketch, examples, exampleReasonings } from '../sketches';
8
+
9
+ const inter = Inter({
10
+ subsets: ['latin'],
11
+ variable: '--font-inter',
12
+ });
13
+
14
+ export default function Home() {
15
+ const [word, setWord] = useState('');
16
+ const [instructions, setInstructions] = useState('');
17
+ const [isGenerating, setIsGenerating] = useState(false);
18
+ const [generatedCode, setGeneratedCode] = useState(initialSketch);
19
+ const [showCodePanel, setShowCodePanel] = useState(false);
20
+ const [error, setError] = useState(null);
21
+ const [activeExample, setActiveExample] = useState(null);
22
+ const [showExamples, setShowExamples] = useState(false);
23
+ const [modelResponse, setModelResponse] = useState('');
24
+ const [showSystemPrompt, setShowSystemPrompt] = useState(false);
25
+ const [isCapturingGif, setIsCapturingGif] = useState(false);
26
+
27
+ const handleExampleClick = (example) => {
28
+ setActiveExample(example);
29
+ setGeneratedCode(examples[example]);
30
+ setShowCodePanel(true);
31
+ setModelResponse(exampleReasonings[example]);
32
+ };
33
+
34
+ const handleSubmit = async (e) => {
35
+ e.preventDefault();
36
+ setIsGenerating(true);
37
+ setError(null);
38
+ setActiveExample(null);
39
+
40
+ try {
41
+ const response = await fetch('/api/generate', {
42
+ method: 'POST',
43
+ headers: {
44
+ 'Content-Type': 'application/json',
45
+ },
46
+ body: JSON.stringify({ word, instructions }),
47
+ });
48
+
49
+ const data = await response.json();
50
+
51
+ if (!response.ok) {
52
+ throw new Error(data.message || `API error: ${response.status}`);
53
+ }
54
+
55
+ if (!data || data.error) {
56
+ throw new Error(data.error || 'No data received from API');
57
+ }
58
+
59
+ if (!data.code || !data.code.includes('function setup()')) {
60
+ throw new Error('Generated code is not in the correct format');
61
+ }
62
+
63
+ setGeneratedCode(data.code);
64
+ setModelResponse(data.fullResponse || '');
65
+ setShowCodePanel(true);
66
+ } catch (error) {
67
+ console.error('Generation error:', error);
68
+ setError(error.message);
69
+ } finally {
70
+ setIsGenerating(false);
71
+ }
72
+ };
73
+
74
+ const handleReplay = () => {
75
+ setGeneratedCode(prevCode => prevCode + ' ');
76
+ requestAnimationFrame(() => {
77
+ setGeneratedCode(prevCode => prevCode.slice(0, -1));
78
+ });
79
+ };
80
+
81
+ const handleGifCapture = async (startCapture) => {
82
+ if (startCapture) {
83
+ setIsCapturingGif(true);
84
+ try {
85
+ const iframe = document.getElementById('sketch-iframe');
86
+ if (iframe) {
87
+ iframe.contentWindow.postMessage({ type: 'startGifCapture' }, '*');
88
+ }
89
+ } catch (error) {
90
+ console.error('GIF capture error:', error);
91
+ setIsCapturingGif(false);
92
+ }
93
+ } else {
94
+ setIsCapturingGif(false);
95
+ }
96
+ };
97
+
98
+ return (
99
+ <div className={`min-h-screen bg-white text-black flex flex-col items-center p-4 sm:p-8 ${inter.variable}`}>
100
+ <Script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.0/p5.js" strategy="beforeInteractive" />
101
+
102
+ <header className="w-full flex items-center mb-8 pl-4 sm:pl-8">
103
+ <div className="flex items-center gap-2">
104
+ <h1
105
+ className="text-xl font-medium cursor-pointer hover:opacity-80 transition-opacity"
106
+ onClick={() => window.location.reload()}
107
+ >
108
+ Word to Code
109
+ </h1>
110
+ <div className="text-sm text-gray-500">
111
+ Built with <a href="https://ai.google.dev/docs" target="_blank" rel="noopener noreferrer" className="underline hover:text-black">Gemini 2.0</a>
112
+ </div>
113
+ </div>
114
+ </header>
115
+
116
+ <main className={`w-full max-w-[1200px] flex flex-col gap-6 mx-auto transition-all duration-500 ease-in-out ${showCodePanel ? '' : 'items-center'}`}>
117
+ <div className={`flex flex-col lg:flex-row gap-8 items-start w-full transition-all duration-500 ease-in-out ${
118
+ showCodePanel ? 'justify-center translate-x-0' : 'justify-center'
119
+ }`}>
120
+ <div className={`flex flex-col gap-6 w-full max-w-[500px] transition-all duration-500 ease-in-out ${showCodePanel ? '' : 'items-center'}`}>
121
+ <SketchRenderer
122
+ generatedCode={generatedCode}
123
+ isGenerating={isGenerating}
124
+ error={error}
125
+ showCodePanel={showCodePanel}
126
+ onReplay={handleReplay}
127
+ onGifCapture={handleGifCapture}
128
+ isCapturingGif={isCapturingGif}
129
+ isInitialSketch={generatedCode === initialSketch}
130
+ />
131
+
132
+ <GenerationForm
133
+ word={word}
134
+ setWord={setWord}
135
+ instructions={instructions}
136
+ setInstructions={setInstructions}
137
+ isGenerating={isGenerating}
138
+ showSystemPrompt={showSystemPrompt}
139
+ setShowSystemPrompt={setShowSystemPrompt}
140
+ showExamples={showExamples}
141
+ setShowExamples={setShowExamples}
142
+ activeExample={activeExample}
143
+ handleExampleClick={handleExampleClick}
144
+ onSubmit={handleSubmit}
145
+ />
146
+ </div>
147
+
148
+ {showCodePanel && (
149
+ <CodePanel
150
+ modelResponse={modelResponse}
151
+ generatedCode={generatedCode}
152
+ />
153
+ )}
154
+ </div>
155
+ </main>
156
+
157
+ <style jsx global>{`
158
+ ::-webkit-scrollbar {
159
+ display: none;
160
+ }
161
+
162
+ @keyframes fadeIn {
163
+ from {
164
+ opacity: 0;
165
+ transform: translateY(10px);
166
+ }
167
+ to {
168
+ opacity: 1;
169
+ transform: translateY(0);
170
+ }
171
+ }
172
+
173
+ @media (min-width: 1024px) {
174
+ @keyframes fadeIn {
175
+ from {
176
+ opacity: 0;
177
+ transform: translateX(10px);
178
+ }
179
+ to {
180
+ opacity: 1;
181
+ transform: translateX(0);
182
+ }
183
+ }
184
+ }
185
+ `}</style>
186
+ </div>
187
+ );
188
+ }
postcss.config.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ module.exports = {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ }
postcss.config.mjs ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ /** @type {import('postcss-load-config').Config} */
2
+ export default {
3
+ plugins: {
4
+ 'tailwindcss': {},
5
+ 'autoprefixer': {},
6
+ },
7
+ };
public/favicon.ico ADDED
public/file.svg ADDED
public/fonts/GoogleSans-Bold.ttf ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6c43148fe7f70f806c23335672fc1590896f08aebc765f35a3702c83e7956f23
3
+ size 177184
public/globe.svg ADDED
public/info_spark.png ADDED
public/js/CCapture.all.min.js ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ "use strict";function download(t,e,i){function n(t){var e=t.split(/[:;,]/),i=e[1],n="base64"==e[2]?atob:decodeURIComponent,r=n(e.pop()),o=r.length,a=0,s=new Uint8Array(o);for(a;a<o;++a)s[a]=r.charCodeAt(a);return new m([s],{type:i})}function r(t,e){if("download"in c)return c.href=t,c.setAttribute("download",g),c.innerHTML="downloading...",c.style.display="none",l.body.appendChild(c),setTimeout(function(){c.click(),l.body.removeChild(c),e===!0&&setTimeout(function(){h.URL.revokeObjectURL(c.href)},250)},66),!0;var i=l.createElement("iframe");l.body.appendChild(i),e||(t="data:"+t.replace(/^data:([\w\/\-\+]+)/,f)),i.src=t,setTimeout(function(){l.body.removeChild(i)},333)}var o,a,s,h=window,f="application/octet-stream",u=i||f,d=t,l=document,c=l.createElement("a"),p=function(t){return String(t)},m=h.Blob||h.MozBlob||h.WebKitBlob||p,w=h.MSBlobBuilder||h.WebKitBlobBuilder||h.BlobBuilder,g=e||"download";if("true"===String(this)&&(d=[d,u],u=d[0],d=d[1]),String(d).match(/^data\:[\w+\-]+\/[\w+\-]+[,;]/))return navigator.msSaveBlob?navigator.msSaveBlob(n(d),g):r(d);try{o=d instanceof m?d:new m([d],{type:u})}catch(t){w&&(a=new w,a.append([d]),o=a.getBlob(u))}if(navigator.msSaveBlob)return navigator.msSaveBlob(o,g);if(h.URL)r(h.URL.createObjectURL(o),!0);else{if("string"==typeof o||o.constructor===p)try{return r("data:"+u+";base64,"+h.btoa(o))}catch(t){return r("data:"+u+","+encodeURIComponent(o))}s=new FileReader,s.onload=function(t){r(this.result)},s.readAsDataURL(o)}return!0}!function(){var t=function(t){this.data=new Uint8Array(t),this.pos=0};t.prototype.seek=function(t){this.pos=t},t.prototype.writeBytes=function(t){for(var e=0;e<t.length;e++)this.data[this.pos++]=t[e]},t.prototype.writeByte=function(t){this.data[this.pos++]=t},t.prototype.writeU8=t.prototype.writeByte,t.prototype.writeU16BE=function(t){this.data[this.pos++]=t>>8,this.data[this.pos++]=t},t.prototype.writeDoubleBE=function(t){for(var e=new Uint8Array(new Float64Array([t]).buffer),i=e.length-1;i>=0;i--)this.writeByte(e[i])},t.prototype.writeFloatBE=function(t){for(var e=new Uint8Array(new Float32Array([t]).buffer),i=e.length-1;i>=0;i--)this.writeByte(e[i])},t.prototype.writeString=function(t){for(var e=0;e<t.length;e++)this.data[this.pos++]=t.charCodeAt(e)},t.prototype.writeEBMLVarIntWidth=function(t,e){switch(e){case 1:this.writeU8(128|t);break;case 2:this.writeU8(64|t>>8),this.writeU8(t);break;case 3:this.writeU8(32|t>>16),this.writeU8(t>>8),this.writeU8(t);break;case 4:this.writeU8(16|t>>24),this.writeU8(t>>16),this.writeU8(t>>8),this.writeU8(t);break;case 5:this.writeU8(8|t/4294967296&7),this.writeU8(t>>24),this.writeU8(t>>16),this.writeU8(t>>8),this.writeU8(t);break;default:throw new RuntimeException("Bad EBML VINT size "+e)}},t.prototype.measureEBMLVarInt=function(t){if(t<127)return 1;if(t<16383)return 2;if(t<2097151)return 3;if(t<268435455)return 4;if(t<34359738367)return 5;throw new RuntimeException("EBML VINT size not supported "+t)},t.prototype.writeEBMLVarInt=function(t){this.writeEBMLVarIntWidth(t,this.measureEBMLVarInt(t))},t.prototype.writeUnsignedIntBE=function(t,e){switch(void 0===e&&(e=this.measureUnsignedInt(t)),e){case 5:this.writeU8(Math.floor(t/4294967296));case 4:this.writeU8(t>>24);case 3:this.writeU8(t>>16);case 2:this.writeU8(t>>8);case 1:this.writeU8(t);break;default:throw new RuntimeException("Bad UINT size "+e)}},t.prototype.measureUnsignedInt=function(t){return t<256?1:t<65536?2:t<1<<24?3:t<4294967296?4:5},t.prototype.getAsDataArray=function(){if(this.pos<this.data.byteLength)return this.data.subarray(0,this.pos);if(this.pos==this.data.byteLength)return this.data;throw"ArrayBufferDataStream's pos lies beyond end of buffer"},"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=t:window.ArrayBufferDataStream=t}(),function(){var t=function(t){return function(e){function i(t){return new Promise(function(e,i){var n=new FileReader;n.addEventListener("loadend",function(){e(n.result)}),n.readAsArrayBuffer(t)})}function n(t){return new Promise(function(e,n){e(t instanceof Uint8Array?t:t instanceof ArrayBuffer||ArrayBuffer.isView(t)?new Uint8Array(t):t instanceof Blob?i(t).then(function(t){return new Uint8Array(t)}):i(new Blob([t])).then(function(t){return new Uint8Array(t)}))})}function r(t){var e=t.byteLength||t.length||t.size;if(!Number.isInteger(e))throw"Failed to determine size of element";return e}var o=[],a=Promise.resolve(),s=null,h=null;"undefined"!=typeof FileWriter&&e instanceof FileWriter?s=e:t&&e&&(h=e),this.pos=0,this.length=0,this.seek=function(t){if(t<0)throw"Offset may not be negative";if(isNaN(t))throw"Offset may not be NaN";if(t>this.length)throw"Seeking beyond the end of file is not allowed";this.pos=t},this.write=function(e){var i={offset:this.pos,data:e,length:r(e)},f=i.offset>=this.length;this.pos+=i.length,this.length=Math.max(this.length,this.pos),a=a.then(function(){if(h)return new Promise(function(e,r){n(i.data).then(function(n){var r=0,o=Buffer.from(n.buffer),a=function(n,o,s){r+=o,r>=s.length?e():t.write(h,s,r,s.length-r,i.offset+r,a)};t.write(h,o,0,o.length,i.offset,a)})});if(s)return new Promise(function(t,e){s.onwriteend=t,s.seek(i.offset),s.write(new Blob([i.data]))});if(!f)for(var e=0;e<o.length;e++){var r=o[e];if(!(i.offset+i.length<=r.offset||i.offset>=r.offset+r.length)){if(i.offset<r.offset||i.offset+i.length>r.offset+r.length)throw new Error("Overwrite crosses blob boundaries");return i.offset==r.offset&&i.length==r.length?void(r.data=i.data):n(r.data).then(function(t){return r.data=t,n(i.data)}).then(function(t){i.data=t,r.data.set(i.data,i.offset-r.offset)})}}o.push(i)})},this.complete=function(t){return a=h||s?a.then(function(){return null}):a.then(function(){for(var e=[],i=0;i<o.length;i++)e.push(o[i].data);return new Blob(e,{mimeType:t})})}}};"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=t(require("fs")):window.BlobBuffer=t(null)}(),function(){var t=function(t,e){function i(t,e){var i={};return[t,e].forEach(function(t){for(var e in t)Object.prototype.hasOwnProperty.call(t,e)&&(i[e]=t[e])}),i}function n(t){return!("string"!=typeof t||!t.match(/^data:image\/webp;base64,/i))&&window.atob(t.substring("data:image/webp;base64,".length))}function r(t,e){var i=t.toDataURL("image/webp",{quality:e});return n(i)}function o(t){var e=t.indexOf("VP8 ");if(e==-1)throw"Failed to identify beginning of keyframe in WebP image";return e+="VP8 ".length+4,t.substring(e)}function a(t){this.value=t}function s(t){this.value=t}function h(t,e,i){if(Array.isArray(i))for(var n=0;n<i.length;n++)h(t,e,i[n]);else if("string"==typeof i)t.writeString(i);else if(i instanceof Uint8Array)t.writeBytes(i);else{if(!i.id)throw"Bad EBML datatype "+typeof i.data;if(i.offset=t.pos+e,t.writeUnsignedIntBE(i.id),Array.isArray(i.data)){var r,o,f;i.size===-1?t.writeByte(255):(r=t.pos,t.writeBytes([0,0,0,0])),o=t.pos,i.dataOffset=o+e,h(t,e,i.data),i.size!==-1&&(f=t.pos,i.size=f-o,t.seek(r),t.writeEBMLVarIntWidth(i.size,4),t.seek(f))}else if("string"==typeof i.data)t.writeEBMLVarInt(i.data.length),i.dataOffset=t.pos+e,t.writeString(i.data);else if("number"==typeof i.data)i.size||(i.size=t.measureUnsignedInt(i.data)),t.writeEBMLVarInt(i.size),i.dataOffset=t.pos+e,t.writeUnsignedIntBE(i.data,i.size);else if(i.data instanceof s)t.writeEBMLVarInt(8),i.dataOffset=t.pos+e,t.writeDoubleBE(i.data.value);else if(i.data instanceof a)t.writeEBMLVarInt(4),i.dataOffset=t.pos+e,t.writeFloatBE(i.data.value);else{if(!(i.data instanceof Uint8Array))throw"Bad EBML datatype "+typeof i.data;t.writeEBMLVarInt(i.data.byteLength),i.dataOffset=t.pos+e,t.writeBytes(i.data)}}}return function(n){function a(t){return t-B.dataOffset}function f(){var t={id:21420,size:5,data:0},e={id:290298740,data:[]};for(var i in D){var n=D[i];n.positionEBML=Object.create(t),e.data.push({id:19899,data:[{id:21419,data:n.id},n.positionEBML]})}return e}function u(){x=f();var e={id:440786851,data:[{id:17030,data:1},{id:17143,data:1},{id:17138,data:4},{id:17139,data:8},{id:17026,data:"webm"},{id:17031,data:2},{id:17029,data:2}]},i={id:357149030,data:[{id:2807729,data:1e6},{id:19840,data:"webm-writer-js"},{id:22337,data:"webm-writer-js"},M]},n={id:374648427,data:[{id:174,data:[{id:215,data:A},{id:29637,data:A},{id:156,data:0},{id:2274716,data:"und"},{id:134,data:"V_VP8"},{id:2459272,data:"VP8"},{id:131,data:1},{id:224,data:[{id:176,data:b},{id:186,data:k}]}]}]};B={id:408125543,size:-1,data:[x,i,n]};var r=new t(256);h(r,S.pos,[e,B]),S.write(r.getAsDataArray()),D.SegmentInfo.positionEBML.data=a(i.offset),D.Tracks.positionEBML.data=a(n.offset)}function d(e){var i=new t(4);if(!(e.trackNumber>0&&e.trackNumber<127))throw"TrackNumber must be > 0 and < 127";return i.writeEBMLVarInt(e.trackNumber),i.writeU16BE(e.timecode),i.writeByte(128),{id:163,data:[i.getAsDataArray(),e.frame]}}function l(t){return{id:524531317,data:[{id:231,data:Math.round(t.timecode)}]}}function c(t,e,i){_.push({id:187,data:[{id:179,data:e},{id:183,data:[{id:247,data:t},{id:241,data:a(i)}]}]})}function p(){var e={id:475249515,data:_},i=new t(16+32*_.length);h(i,S.pos,e),S.write(i.getAsDataArray()),D.Cues.positionEBML.data=a(e.offset)}function m(){if(0!=T.length){for(var e=0,i=0;i<T.length;i++)e+=T[i].frame.length;for(var n=new t(e+32*T.length),r=l({timecode:Math.round(U)}),i=0;i<T.length;i++)r.data.push(d(T[i]));h(n,S.pos,r),S.write(n.getAsDataArray()),c(A,Math.round(U),r.offset),T=[],U+=F,F=0}}function w(){if(!n.frameDuration){if(!n.frameRate)throw"Missing required frameDuration or frameRate setting";n.frameDuration=1e3/n.frameRate}}function g(t){t.trackNumber=A,t.timecode=Math.round(F),T.push(t),F+=t.duration,F>=E&&m()}function y(){var e=new t(x.size),i=S.pos;h(e,x.dataOffset,x.data),S.seek(x.dataOffset),S.write(e.getAsDataArray()),S.seek(i)}function v(){var e=new t(8),i=S.pos;e.writeDoubleBE(U),S.seek(M.dataOffset),S.write(e.getAsDataArray()),S.seek(i)}var b,k,B,x,E=5e3,A=1,L=!1,T=[],U=0,F=0,I={quality:.95,fileWriter:null,fd:null,frameDuration:null,frameRate:null},D={Cues:{id:new Uint8Array([28,83,187,107]),positionEBML:null},SegmentInfo:{id:new Uint8Array([21,73,169,102]),positionEBML:null},Tracks:{id:new Uint8Array([22,84,174,107]),positionEBML:null}},M={id:17545,data:new s(0)},_=[],S=new e(n.fileWriter||n.fd);this.addFrame=function(t){if(L){if(t.width!=b||t.height!=k)throw"Frame size differs from previous frames"}else b=t.width,k=t.height,u(),L=!0;var e=r(t,{quality:n.quality});if(!e)throw"Couldn't decode WebP frame, does the browser support WebP?";g({frame:o(e),duration:n.frameDuration})},this.complete=function(){return m(),p(),y(),v(),S.complete("video/webm")},this.getWrittenSize=function(){return S.length},n=i(I,n||{}),w()}};"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=t(require("./ArrayBufferDataStream"),require("./BlobBuffer")):window.WebMWriter=t(ArrayBufferDataStream,BlobBuffer)}(),function(){function t(t){var e,i=new Uint8Array(t);for(e=0;e<t;e+=1)i[e]=0;return i}function e(e,i,n,r){var o=i+n,a=t((parseInt(o/r)+1)*r);return a.set(e),a}function i(t,e,i){return t=t.toString(i||8),"000000000000".substr(t.length+12-e)+t}function n(e,i,n){var r,o;for(i=i||t(e.length),n=n||0,r=0,o=e.length;r<o;r+=1)i[n]=e.charCodeAt(r),n+=1;return i}function r(t){function e(t){return o[t>>18&63]+o[t>>12&63]+o[t>>6&63]+o[63&t]}var i,n,r,a=t.length%3,s="";for(i=0,r=t.length-a;i<r;i+=3)n=(t[i]<<16)+(t[i+1]<<8)+t[i+2],s+=e(n);switch(s.length%4){case 1:s+="=";break;case 2:s+="=="}return s}var o=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9","+","/"];window.utils={},window.utils.clean=t,window.utils.pad=i,window.utils.extend=e,window.utils.stringToUint8=n,window.utils.uint8ToBase64=r}(),function(){function t(t,n){var r=i.clean(512),o=0;return e.forEach(function(e){var i,n,a=t[e.field]||"";for(i=0,n=a.length;i<n;i+=1)r[o]=a.charCodeAt(i),o+=1;o+=e.length-i}),"function"==typeof n?n(r,o):r}var e,i=window.utils;e=[{field:"fileName",length:100},{field:"fileMode",length:8},{field:"uid",length:8},{field:"gid",length:8},{field:"fileSize",length:12},{field:"mtime",length:12},{field:"checksum",length:8},{field:"type",length:1},{field:"linkName",length:100},{field:"ustar",length:8},{field:"owner",length:32},{field:"group",length:32},{field:"majorNumber",length:8},{field:"minorNumber",length:8},{field:"filenamePrefix",length:155},{field:"padding",length:12}],window.header={},window.header.structure=e,window.header.format=t}(),function(){function t(t){this.written=0,e=(t||20)*r,this.out=n.clean(e),this.blocks=[],this.length=0}var e,i=window.header,n=window.utils,r=512;t.prototype.append=function(t,e,o,a){var s,h,f,u,d,l,c;if("string"==typeof e)e=n.stringToUint8(e);else if(e.constructor!==Uint8Array.prototype.constructor)throw"Invalid input type. You gave me: "+e.constructor.toString().match(/function\s*([$A-Za-z_][0-9A-Za-z_]*)\s*\(/)[1];"function"==typeof o&&(a=o,o={}),o=o||{},f=o.mode||4095&parseInt("777",8),u=o.mtime||Math.floor(+new Date/1e3),d=o.uid||0,l=o.gid||0,s={fileName:t,fileMode:n.pad(f,7),uid:n.pad(d,7),gid:n.pad(l,7),fileSize:n.pad(e.length,11),mtime:n.pad(u,11),checksum:" ",type:"0",ustar:"ustar ",owner:o.owner||"",group:o.group||""},h=0,Object.keys(s).forEach(function(t){var e,i,n=s[t];for(e=0,i=n.length;e<i;e+=1)h+=n.charCodeAt(e)}),s.checksum=n.pad(h,6)+"\0 ",c=i.format(s);var p=Math.ceil(c.length/r)*r,m=Math.ceil(e.length/r)*r;this.blocks.push({header:c,input:e,headerLength:p,inputLength:m})},t.prototype.save=function(){var t=[],e=[],i=0,n=Math.pow(2,20),o=[];return this.blocks.forEach(function(t){i+t.headerLength+t.inputLength>n&&(e.push({blocks:o,length:i}),o=[],i=0),o.push(t),i+=t.headerLength+t.inputLength}),e.push({blocks:o,length:i}),e.forEach(function(e){var i=new Uint8Array(e.length),n=0;e.blocks.forEach(function(t){i.set(t.header,n),n+=t.headerLength,i.set(t.input,n),n+=t.inputLength}),t.push(i)}),t.push(new Uint8Array(2*r)),new Blob(t,{type:"octet/stream"})},t.prototype.clear=function(){this.written=0,this.out=n.clean(e)},window.Tar=t}(),function(t){function e(t,i){if({}.hasOwnProperty.call(e.cache,t))return e.cache[t];var n=e.resolve(t);if(!n)throw new Error("Failed to resolve module "+t);var r={id:t,require:e,filename:t,exports:{},loaded:!1,parent:i,children:[]};i&&i.children.push(r);var o=t.slice(0,t.lastIndexOf("/")+1);return e.cache[t]=r.exports,n.call(r.exports,r,r.exports,o,t),r.loaded=!0,e.cache[t]=r.exports}e.modules={},e.cache={},e.resolve=function(t){return{}.hasOwnProperty.call(e.modules,t)?e.modules[t]:void 0},e.define=function(t,i){e.modules[t]=i};var i=function(e){return e="/",{title:"browser",version:"v0.10.26",browser:!0,env:{},argv:[],nextTick:t.setImmediate||function(t){setTimeout(t,0)},cwd:function(){return e},chdir:function(t){e=t}}}();e.define("/gif.coffee",function(t,i,n,r){function o(t,e){return{}.hasOwnProperty.call(t,e)}function a(t,e){for(var i=0,n=e.length;i<n;++i)if(i in e&&e[i]===t)return!0;return!1}function s(t,e){function i(){this.constructor=t}for(var n in e)o(e,n)&&(t[n]=e[n]);return i.prototype=e.prototype,t.prototype=new i,t.__super__=e.prototype,t}var h,f,u,d,l;u=e("events",t).EventEmitter,h=e("/browser.coffee",t),l=function(t){function e(t){var e,i;this.running=!1,this.options={},this.frames=[],this.freeWorkers=[],this.activeWorkers=[],this.setOptions(t);for(e in f)i=f[e],null!=this.options[e]?this.options[e]:this.options[e]=i}return s(e,t),f={workerScript:"gif.worker.js",workers:2,repeat:0,background:"#fff",quality:10,width:null,height:null,transparent:null},d={delay:500,copy:!1},e.prototype.setOption=function(t,e){return this.options[t]=e,null==this._canvas||"width"!==t&&"height"!==t?void 0:this._canvas[t]=e},e.prototype.setOptions=function(t){var e,i;return function(n){for(e in t)o(t,e)&&(i=t[e],n.push(this.setOption(e,i)));return n}.call(this,[])},e.prototype.addFrame=function(t,e){var i,n;null==e&&(e={}),i={},i.transparent=this.options.transparent;for(n in d)i[n]=e[n]||d[n];if(null!=this.options.width||this.setOption("width",t.width),null!=this.options.height||this.setOption("height",t.height),"undefined"!=typeof ImageData&&null!=ImageData&&t instanceof ImageData)i.data=t.data;else if("undefined"!=typeof CanvasRenderingContext2D&&null!=CanvasRenderingContext2D&&t instanceof CanvasRenderingContext2D||"undefined"!=typeof WebGLRenderingContext&&null!=WebGLRenderingContext&&t instanceof WebGLRenderingContext)e.copy?i.data=this.getContextData(t):i.context=t;else{if(null==t.childNodes)throw new Error("Invalid image");e.copy?i.data=this.getImageData(t):i.image=t}return this.frames.push(i)},e.prototype.render=function(){var t,e;if(this.running)throw new Error("Already running");if(null==this.options.width||null==this.options.height)throw new Error("Width and height must be set prior to rendering");this.running=!0,this.nextFrame=0,this.finishedFrames=0,this.imageParts=function(e){for(var i=function(){var t;t=[];for(var e=0;0<=this.frames.length?e<this.frames.length:e>this.frames.length;0<=this.frames.length?++e:--e)t.push(e);return t}.apply(this,arguments),n=0,r=i.length;n<r;++n)t=i[n],e.push(null);return e}.call(this,[]),e=this.spawnWorkers();for(var i=function(){var t;t=[];for(var i=0;0<=e?i<e:i>e;0<=e?++i:--i)t.push(i);return t}.apply(this,arguments),n=0,r=i.length;n<r;++n)t=i[n],this.renderNextFrame();return this.emit("start"),this.emit("progress",0)},e.prototype.abort=function(){for(var t;;){if(t=this.activeWorkers.shift(),!(null!=t))break;console.log("killing active worker"),t.terminate()}return this.running=!1,this.emit("abort")},e.prototype.spawnWorkers=function(){var t;return t=Math.min(this.options.workers,this.frames.length),function(){var e;e=[];for(var i=this.freeWorkers.length;this.freeWorkers.length<=t?i<t:i>t;this.freeWorkers.length<=t?++i:--i)e.push(i);return e}.apply(this,arguments).forEach(function(t){return function(e){var i;return console.log("spawning worker "+e),i=new Worker(t.options.workerScript),i.onmessage=function(t){return function(e){return t.activeWorkers.splice(t.activeWorkers.indexOf(i),1),t.freeWorkers.push(i),t.frameFinished(e.data)}}(t),t.freeWorkers.push(i)}}(this)),t},e.prototype.frameFinished=function(t){return console.log("frame "+t.index+" finished - "+this.activeWorkers.length+" active"),this.finishedFrames++,this.emit("progress",this.finishedFrames/this.frames.length),this.imageParts[t.index]=t,a(null,this.imageParts)?this.renderNextFrame():this.finishRendering()},e.prototype.finishRendering=function(){var t,e,i,n,r,o,a;r=0;for(var s=0,h=this.imageParts.length;s<h;++s)e=this.imageParts[s],r+=(e.data.length-1)*e.pageSize+e.cursor;r+=e.pageSize-e.cursor,console.log("rendering finished - filesize "+Math.round(r/1e3)+"kb"),t=new Uint8Array(r),o=0;for(var f=0,u=this.imageParts.length;f<u;++f){e=this.imageParts[f];for(var d=0,l=e.data.length;d<l;++d)a=e.data[d],i=d,t.set(a,o),o+=i===e.data.length-1?e.cursor:e.pageSize}return n=new Blob([t],{type:"image/gif"}),this.emit("finished",n,t)},e.prototype.renderNextFrame=function(){var t,e,i;if(0===this.freeWorkers.length)throw new Error("No free workers");return this.nextFrame>=this.frames.length?void 0:(t=this.frames[this.nextFrame++],i=this.freeWorkers.shift(),e=this.getTask(t),console.log("starting frame "+(e.index+1)+" of "+this.frames.length),this.activeWorkers.push(i),i.postMessage(e))},e.prototype.getContextData=function(t){return t.getImageData(0,0,this.options.width,this.options.height).data},e.prototype.getImageData=function(t){var e;return null!=this._canvas||(this._canvas=document.createElement("canvas"),this._canvas.width=this.options.width,this._canvas.height=this.options.height),e=this._canvas.getContext("2d"),e.setFill=this.options.background,e.fillRect(0,0,this.options.width,this.options.height),e.drawImage(t,0,0),this.getContextData(e)},e.prototype.getTask=function(t){var e,i;if(e=this.frames.indexOf(t),i={index:e,last:e===this.frames.length-1,delay:t.delay,transparent:t.transparent,width:this.options.width,height:this.options.height,quality:this.options.quality,repeat:this.options.repeat,canTransfer:"chrome"===h.name},null!=t.data)i.data=t.data;else if(null!=t.context)i.data=this.getContextData(t.context);else{if(null==t.image)throw new Error("Invalid frame");i.data=this.getImageData(t.image)}return i},e}(u),t.exports=l}),e.define("/browser.coffee",function(t,e,i,n){var r,o,a,s,h;s=navigator.userAgent.toLowerCase(),a=navigator.platform.toLowerCase(),h=s.match(/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/)||[null,"unknown",0],o="ie"===h[1]&&document.documentMode,r={name:"version"===h[1]?h[3]:h[1],version:o||parseFloat("opera"===h[1]&&h[4]?h[4]:h[2]),platform:{name:s.match(/ip(?:ad|od|hone)/)?"ios":(s.match(/(?:webos|android)/)||a.match(/mac|win|linux/)||["other"])[0]}},r[r.name]=!0,r[r.name+parseInt(r.version,10)]=!0,r.platform[r.platform.name]=!0,t.exports=r}),e.define("events",function(t,e,n,r){i.EventEmitter||(i.EventEmitter=function(){});var o=e.EventEmitter=i.EventEmitter,a="function"==typeof Array.isArray?Array.isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)},s=10;o.prototype.setMaxListeners=function(t){this._events||(this._events={}),this._events.maxListeners=t},o.prototype.emit=function(t){if("error"===t&&(!this._events||!this._events.error||a(this._events.error)&&!this._events.error.length))throw arguments[1]instanceof Error?arguments[1]:new Error("Uncaught, unspecified 'error' event.");if(!this._events)return!1;var e=this._events[t];if(!e)return!1;if("function"!=typeof e){if(a(e)){for(var i=Array.prototype.slice.call(arguments,1),n=e.slice(),r=0,o=n.length;r<o;r++)n[r].apply(this,i);return!0}return!1}switch(arguments.length){case 1:e.call(this);break;case 2:e.call(this,arguments[1]);break;case 3:e.call(this,arguments[1],arguments[2]);break;default:var i=Array.prototype.slice.call(arguments,1);e.apply(this,i)}return!0},o.prototype.addListener=function(t,e){if("function"!=typeof e)throw new Error("addListener only takes instances of Function");if(this._events||(this._events={}),this.emit("newListener",t,e),this._events[t])if(a(this._events[t])){if(!this._events[t].warned){var i;i=void 0!==this._events.maxListeners?this._events.maxListeners:s,i&&i>0&&this._events[t].length>i&&(this._events[t].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[t].length),console.trace())}this._events[t].push(e)}else this._events[t]=[this._events[t],e];else this._events[t]=e;return this},o.prototype.on=o.prototype.addListener,o.prototype.once=function(t,e){var i=this;return i.on(t,function n(){i.removeListener(t,n),e.apply(this,arguments)}),this},o.prototype.removeListener=function(t,e){if("function"!=typeof e)throw new Error("removeListener only takes instances of Function");if(!this._events||!this._events[t])return this;var i=this._events[t];if(a(i)){var n=i.indexOf(e);if(n<0)return this;i.splice(n,1),0==i.length&&delete this._events[t]}else this._events[t]===e&&delete this._events[t];return this},o.prototype.removeAllListeners=function(t){return t&&this._events&&this._events[t]&&(this._events[t]=null),this},o.prototype.listeners=function(t){return this._events||(this._events={}),this._events[t]||(this._events[t]=[]),a(this._events[t])||(this._events[t]=[this._events[t]]),this._events[t]}}),t.GIF=e("/gif.coffee")}.call(this,this),function(){function t(t){return t&&t.Object===Object?t:null}function e(t){return String("0000000"+t).slice(-7)}function i(){function t(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)}return t()+t()+"-"+t()+"-"+t()+"-"+t()+"-"+t()+t()+t()}function n(t){var e={};this.settings=t,this.on=function(t,i){e[t]=i},this.emit=function(t){var i=e[t];i&&i.apply(null,Array.prototype.slice.call(arguments,1))},this.filename=t.name||i(),this.extension="",this.mimeType=""}function r(t){n.call(this,t),this.extension=".tar",this.mimeType="application/x-tar",this.fileExtension="",this.baseFilename=this.filename,this.tape=null,this.count=0,this.part=1,this.frames=0}function o(t){r.call(this,t),this.type="image/png",this.fileExtension=".png"}function a(t){r.call(this,t),this.type="image/jpeg",this.fileExtension=".jpg",this.quality=t.quality/100||.8}function s(t){var e=document.createElement("canvas");"image/webp"!==e.toDataURL("image/webp").substr(5,10)&&console.log("WebP not supported - try another export format"),n.call(this,t),this.quality=t.quality/100||.8,this.extension=".webm",this.mimeType="video/webm",this.baseFilename=this.filename,this.framerate=t.framerate,this.frames=0,this.part=1,this.videoWriter=new WebMWriter({quality:this.quality,fileWriter:null,fd:null,frameRate:this.framerate})}function h(t){n.call(this,t),t.quality=t.quality/100||.8,this.encoder=new FFMpegServer.Video(t),this.encoder.on("process",function(){this.emit("process")}.bind(this)),this.encoder.on("finished",function(t,e){var i=this.callback;i&&(this.callback=void 0,i(t,e))}.bind(this)),this.encoder.on("progress",function(t){this.settings.onProgress&&this.settings.onProgress(t)}.bind(this)),this.encoder.on("error",function(t){alert(JSON.stringify(t,null,2))}.bind(this))}function f(t){n.call(this,t),this.framerate=this.settings.framerate,this.type="video/webm",this.extension=".webm",this.stream=null,this.mediaRecorder=null,this.chunks=[]}function u(t){n.call(this,t),t.quality=31-(30*t.quality/100||10),t.workers=t.workers||4,this.extension=".gif",this.mimeType="image/gif",this.canvas=document.createElement("canvas"),this.ctx=this.canvas.getContext("2d"),this.sizeSet=!1,this.encoder=new GIF({workers:t.workers,quality:t.quality,workerScript:t.workersPath+"gif.worker.js"}),this.encoder.on("progress",function(t){this.settings.onProgress&&this.settings.onProgress(t)}.bind(this)),this.encoder.on("finished",function(t){var e=this.callback;e&&(this.callback=void 0,e(t))}.bind(this))}function d(t){function e(){function t(){return this._hooked||(this._hooked=!0,this._hookedTime=this.currentTime||0,this.pause(),it.push(this)),this._hookedTime+M.startTime}b("Capturer start"),U=window.Date.now(),T=U+M.startTime,I=window.performance.now(),F=I+M.startTime,window.Date.prototype.getTime=function(){return T},window.Date.now=function(){return T},window.setTimeout=function(t,e){var i={callback:t,time:e,triggerTime:T+e};return _.push(i),b("Timeout set to "+i.time),i},window.clearTimeout=function(t){for(var e=0;e<_.length;e++)_[e]!=t||(_.splice(e,1),b("Timeout cleared"))},window.setInterval=function(t,e){var i={callback:t,time:e,triggerTime:T+e};return S.push(i),b("Interval set to "+i.time),i},window.clearInterval=function(t){return b("clear Interval"),null},window.requestAnimationFrame=function(t){W.push(t)},window.performance.now=function(){return F};try{Object.defineProperty(HTMLVideoElement.prototype,"currentTime",{get:t}),Object.defineProperty(HTMLAudioElement.prototype,"currentTime",{get:t})}catch(t){b(t)}}function i(){e(),D.start(),R=!0}function n(){R=!1,D.stop(),l()}function r(t,e){Z(t,0,e)}function d(){r(y)}function l(){b("Capturer stop"),window.setTimeout=Z,window.setInterval=J,window.clearInterval=Y,window.clearTimeout=$,window.requestAnimationFrame=Q,window.Date.prototype.getTime=et,window.Date.now=X,window.performance.now=tt}function c(){var t=C/M.framerate;(M.frameLimit&&C>=M.frameLimit||M.timeLimit&&t>=M.timeLimit)&&(n(),v());var e=new Date(null);e.setSeconds(t),M.motionBlurFrames>2?j.textContent="CCapture "+M.format+" | "+C+" frames ("+O+" inter) | "+e.toISOString().substr(11,8):j.textContent="CCapture "+M.format+" | "+C+" frames | "+e.toISOString().substr(11,8)}function p(t){N.width===t.width&&N.height===t.height||(N.width=t.width,N.height=t.height,z=new Uint16Array(N.height*N.width*4),V.fillStyle="#0",V.fillRect(0,0,N.width,N.height))}function m(t){V.drawImage(t,0,0),q=V.getImageData(0,0,N.width,N.height);for(var e=0;e<z.length;e+=4)z[e]+=q.data[e],z[e+1]+=q.data[e+1],z[e+2]+=q.data[e+2];O++}function w(){for(var t=q.data,e=0;e<z.length;e+=4)t[e]=2*z[e]/M.motionBlurFrames,t[e+1]=2*z[e+1]/M.motionBlurFrames,t[e+2]=2*z[e+2]/M.motionBlurFrames;V.putImageData(q,0,0),D.add(N),C++,O=0,b("Full MB Frame! "+C+" "+T);for(var e=0;e<z.length;e+=4)z[e]=0,z[e+1]=0,z[e+2]=0;gc()}function g(t){R&&(M.motionBlurFrames>2?(p(t),m(t),O>=.5*M.motionBlurFrames?w():d()):(D.add(t),C++,b("Full Frame! "+C)))}function y(){var t=1e3/M.framerate,e=(C+O/M.motionBlurFrames)*t;T=U+e,F=I+e,it.forEach(function(t){t._hookedTime=e/1e3}),c(),b("Frame: "+C+" "+O);for(var i=0;i<_.length;i++)T>=_[i].triggerTime&&(r(_[i].callback),_.splice(i,1));for(var i=0;i<S.length;i++)T>=S[i].triggerTime&&(r(S[i].callback),S[i].triggerTime+=S[i].time);W.forEach(function(t){r(t,T-k)}),W=[]}function v(t){t||(t=function(t){return download(t,D.filename+D.extension,D.mimeType),!1}),D.save(t)}function b(t){A&&console.log(t)}function B(t,e){P[t]=e}function x(t){var e=P[t];e&&e.apply(null,Array.prototype.slice.call(arguments,1))}function E(t){x("progress",t)}var A,L,T,U,F,I,d,D,M=t||{},_=(new Date,[]),S=[],C=0,O=0,W=[],R=!1,P={};M.framerate=M.framerate||60,M.motionBlurFrames=2*(M.motionBlurFrames||1),A=M.verbose||!1,L=M.display||!1,M.step=1e3/M.framerate,M.timeLimit=M.timeLimit||0,M.frameLimit=M.frameLimit||0,M.startTime=M.startTime||0;var j=document.createElement("div");j.style.position="absolute",j.style.left=j.style.top=0,j.style.backgroundColor="black",j.style.fontFamily="monospace",j.style.fontSize="11px",j.style.padding="5px",j.style.color="red",j.style.zIndex=1e5,M.display&&document.body.appendChild(j);var z,q,N=document.createElement("canvas"),V=N.getContext("2d");b("Step is set to "+M.step+"ms");var G={gif:u,webm:s,ffmpegserver:h,png:o,jpg:a,"webm-mediarecorder":f},H=G[M.format];if(!H)throw"Error: Incorrect or missing format: Valid formats are "+Object.keys(G).join(", ");if(D=new H(M),D.step=d,D.on("process",y),D.on("progress",E),"performance"in window==0&&(window.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in window.performance==0){var K=Date.now();performance.timing&&performance.timing.navigationStart&&(K=performance.timing.navigationStart),window.performance.now=function(){return Date.now()-K}}var Z=window.setTimeout,J=window.setInterval,Y=window.clearInterval,$=window.clearTimeout,Q=window.requestAnimationFrame,X=window.Date.now,tt=window.performance.now,et=window.Date.prototype.getTime,it=[];return{start:i,capture:g,stop:n,save:v,on:B}}var l={function:!0,object:!0},c=(parseFloat,parseInt,l[typeof exports]&&exports&&!exports.nodeType?exports:void 0),p=l[typeof module]&&module&&!module.nodeType?module:void 0,m=p&&p.exports===c?c:void 0,w=t(c&&p&&"object"==typeof global&&global),g=t(l[typeof self]&&self),y=t(l[typeof window]&&window),v=t(l[typeof this]&&this),b=w||y!==(v&&v.window)&&y||g||v||Function("return this")();"gc"in window||(window.gc=function(){}),HTMLCanvasElement.prototype.toBlob||Object.defineProperty(HTMLCanvasElement.prototype,"toBlob",{value:function(t,e,i){for(var n=atob(this.toDataURL(e,i).split(",")[1]),r=n.length,o=new Uint8Array(r),a=0;a<r;a++)o[a]=n.charCodeAt(a);t(new Blob([o],{type:e||"image/png"}))}}),function(){if("performance"in window==0&&(window.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in window.performance==0){var t=Date.now();performance.timing&&performance.timing.navigationStart&&(t=performance.timing.navigationStart),window.performance.now=function(){return Date.now()-t}}}();var k=window.Date.now();n.prototype.start=function(){},n.prototype.stop=function(){},n.prototype.add=function(){},n.prototype.save=function(){},n.prototype.dispose=function(){},n.prototype.safeToProceed=function(){return!0},n.prototype.step=function(){console.log("Step not set!")},r.prototype=Object.create(n.prototype),r.prototype.start=function(){this.dispose()},r.prototype.add=function(t){
2
+ var i=new FileReader;i.onload=function(){this.tape.append(e(this.count)+this.fileExtension,new Uint8Array(i.result)),this.settings.autoSaveTime>0&&this.frames/this.settings.framerate>=this.settings.autoSaveTime?this.save(function(t){this.filename=this.baseFilename+"-part-"+e(this.part),download(t,this.filename+this.extension,this.mimeType);var i=this.count;this.dispose(),this.count=i+1,this.part++,this.filename=this.baseFilename+"-part-"+e(this.part),this.frames=0,this.step()}.bind(this)):(this.count++,this.frames++,this.step())}.bind(this),i.readAsArrayBuffer(t)},r.prototype.save=function(t){t(this.tape.save())},r.prototype.dispose=function(){this.tape=new Tar,this.count=0},o.prototype=Object.create(r.prototype),o.prototype.add=function(t){t.toBlob(function(t){r.prototype.add.call(this,t)}.bind(this),this.type)},a.prototype=Object.create(r.prototype),a.prototype.add=function(t){t.toBlob(function(t){r.prototype.add.call(this,t)}.bind(this),this.type,this.quality)},s.prototype=Object.create(n.prototype),s.prototype.start=function(t){this.dispose()},s.prototype.add=function(t){this.videoWriter.addFrame(t),this.settings.autoSaveTime>0&&this.frames/this.settings.framerate>=this.settings.autoSaveTime?this.save(function(t){this.filename=this.baseFilename+"-part-"+e(this.part),download(t,this.filename+this.extension,this.mimeType),this.dispose(),this.part++,this.filename=this.baseFilename+"-part-"+e(this.part),this.step()}.bind(this)):(this.frames++,this.step())},s.prototype.save=function(t){this.videoWriter.complete().then(t)},s.prototype.dispose=function(t){this.frames=0,this.videoWriter=new WebMWriter({quality:this.quality,fileWriter:null,fd:null,frameRate:this.framerate})},h.prototype=Object.create(n.prototype),h.prototype.start=function(){this.encoder.start(this.settings)},h.prototype.add=function(t){this.encoder.add(t)},h.prototype.save=function(t){this.callback=t,this.encoder.end()},h.prototype.safeToProceed=function(){return this.encoder.safeToProceed()},f.prototype=Object.create(n.prototype),f.prototype.add=function(t){this.stream||(this.stream=t.captureStream(this.framerate),this.mediaRecorder=new MediaRecorder(this.stream),this.mediaRecorder.start(),this.mediaRecorder.ondataavailable=function(t){this.chunks.push(t.data)}.bind(this)),this.step()},f.prototype.save=function(t){this.mediaRecorder.onstop=function(e){var i=new Blob(this.chunks,{type:"video/webm"});this.chunks=[],t(i)}.bind(this),this.mediaRecorder.stop()},u.prototype=Object.create(n.prototype),u.prototype.add=function(t){this.sizeSet||(this.encoder.setOption("width",t.width),this.encoder.setOption("height",t.height),this.sizeSet=!0),this.canvas.width=t.width,this.canvas.height=t.height,this.ctx.drawImage(t,0,0),this.encoder.addFrame(this.ctx,{copy:!0,delay:this.settings.step}),this.step()},u.prototype.save=function(t){this.callback=t,this.encoder.render()},(y||g||{}).CCapture=d,"function"==typeof define&&"object"==typeof define.amd&&define.amd?define(function(){return d}):c&&p?(m&&((p.exports=d).CCapture=d),c.CCapture=d):b.CCapture=d}();
public/js/gif.js ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ // gif.js 0.2.0 - https://github.com/jnordberg/gif.js
2
+ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.GIF=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){function EventEmitter(){this._events=this._events||{};this._maxListeners=this._maxListeners||undefined}module.exports=EventEmitter;EventEmitter.EventEmitter=EventEmitter;EventEmitter.prototype._events=undefined;EventEmitter.prototype._maxListeners=undefined;EventEmitter.defaultMaxListeners=10;EventEmitter.prototype.setMaxListeners=function(n){if(!isNumber(n)||n<0||isNaN(n))throw TypeError("n must be a positive number");this._maxListeners=n;return this};EventEmitter.prototype.emit=function(type){var er,handler,len,args,i,listeners;if(!this._events)this._events={};if(type==="error"){if(!this._events.error||isObject(this._events.error)&&!this._events.error.length){er=arguments[1];if(er instanceof Error){throw er}else{var err=new Error('Uncaught, unspecified "error" event. ('+er+")");err.context=er;throw err}}}handler=this._events[type];if(isUndefined(handler))return false;if(isFunction(handler)){switch(arguments.length){case 1:handler.call(this);break;case 2:handler.call(this,arguments[1]);break;case 3:handler.call(this,arguments[1],arguments[2]);break;default:args=Array.prototype.slice.call(arguments,1);handler.apply(this,args)}}else if(isObject(handler)){args=Array.prototype.slice.call(arguments,1);listeners=handler.slice();len=listeners.length;for(i=0;i<len;i++)listeners[i].apply(this,args)}return true};EventEmitter.prototype.addListener=function(type,listener){var m;if(!isFunction(listener))throw TypeError("listener must be a function");if(!this._events)this._events={};if(this._events.newListener)this.emit("newListener",type,isFunction(listener.listener)?listener.listener:listener);if(!this._events[type])this._events[type]=listener;else if(isObject(this._events[type]))this._events[type].push(listener);else this._events[type]=[this._events[type],listener];if(isObject(this._events[type])&&!this._events[type].warned){if(!isUndefined(this._maxListeners)){m=this._maxListeners}else{m=EventEmitter.defaultMaxListeners}if(m&&m>0&&this._events[type].length>m){this._events[type].warned=true;console.error("(node) warning: possible EventEmitter memory "+"leak detected. %d listeners added. "+"Use emitter.setMaxListeners() to increase limit.",this._events[type].length);if(typeof console.trace==="function"){console.trace()}}}return this};EventEmitter.prototype.on=EventEmitter.prototype.addListener;EventEmitter.prototype.once=function(type,listener){if(!isFunction(listener))throw TypeError("listener must be a function");var fired=false;function g(){this.removeListener(type,g);if(!fired){fired=true;listener.apply(this,arguments)}}g.listener=listener;this.on(type,g);return this};EventEmitter.prototype.removeListener=function(type,listener){var list,position,length,i;if(!isFunction(listener))throw TypeError("listener must be a function");if(!this._events||!this._events[type])return this;list=this._events[type];length=list.length;position=-1;if(list===listener||isFunction(list.listener)&&list.listener===listener){delete this._events[type];if(this._events.removeListener)this.emit("removeListener",type,listener)}else if(isObject(list)){for(i=length;i-- >0;){if(list[i]===listener||list[i].listener&&list[i].listener===listener){position=i;break}}if(position<0)return this;if(list.length===1){list.length=0;delete this._events[type]}else{list.splice(position,1)}if(this._events.removeListener)this.emit("removeListener",type,listener)}return this};EventEmitter.prototype.removeAllListeners=function(type){var key,listeners;if(!this._events)return this;if(!this._events.removeListener){if(arguments.length===0)this._events={};else if(this._events[type])delete this._events[type];return this}if(arguments.length===0){for(key in this._events){if(key==="removeListener")continue;this.removeAllListeners(key)}this.removeAllListeners("removeListener");this._events={};return this}listeners=this._events[type];if(isFunction(listeners)){this.removeListener(type,listeners)}else if(listeners){while(listeners.length)this.removeListener(type,listeners[listeners.length-1])}delete this._events[type];return this};EventEmitter.prototype.listeners=function(type){var ret;if(!this._events||!this._events[type])ret=[];else if(isFunction(this._events[type]))ret=[this._events[type]];else ret=this._events[type].slice();return ret};EventEmitter.prototype.listenerCount=function(type){if(this._events){var evlistener=this._events[type];if(isFunction(evlistener))return 1;else if(evlistener)return evlistener.length}return 0};EventEmitter.listenerCount=function(emitter,type){return emitter.listenerCount(type)};function isFunction(arg){return typeof arg==="function"}function isNumber(arg){return typeof arg==="number"}function isObject(arg){return typeof arg==="object"&&arg!==null}function isUndefined(arg){return arg===void 0}},{}],2:[function(require,module,exports){var UA,browser,mode,platform,ua;ua=navigator.userAgent.toLowerCase();platform=navigator.platform.toLowerCase();UA=ua.match(/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/)||[null,"unknown",0];mode=UA[1]==="ie"&&document.documentMode;browser={name:UA[1]==="version"?UA[3]:UA[1],version:mode||parseFloat(UA[1]==="opera"&&UA[4]?UA[4]:UA[2]),platform:{name:ua.match(/ip(?:ad|od|hone)/)?"ios":(ua.match(/(?:webos|android)/)||platform.match(/mac|win|linux/)||["other"])[0]}};browser[browser.name]=true;browser[browser.name+parseInt(browser.version,10)]=true;browser.platform[browser.platform.name]=true;module.exports=browser},{}],3:[function(require,module,exports){var EventEmitter,GIF,browser,extend=function(child,parent){for(var key in parent){if(hasProp.call(parent,key))child[key]=parent[key]}function ctor(){this.constructor=child}ctor.prototype=parent.prototype;child.prototype=new ctor;child.__super__=parent.prototype;return child},hasProp={}.hasOwnProperty,indexOf=[].indexOf||function(item){for(var i=0,l=this.length;i<l;i++){if(i in this&&this[i]===item)return i}return-1},slice=[].slice;EventEmitter=require("events").EventEmitter;browser=require("./browser.coffee");GIF=function(superClass){var defaults,frameDefaults;extend(GIF,superClass);defaults={workerScript:"gif.worker.js",workers:2,repeat:0,background:"#fff",quality:10,width:null,height:null,transparent:null,debug:false,dither:false};frameDefaults={delay:500,copy:false};function GIF(options){var base,key,value;this.running=false;this.options={};this.frames=[];this.freeWorkers=[];this.activeWorkers=[];this.setOptions(options);for(key in defaults){value=defaults[key];if((base=this.options)[key]==null){base[key]=value}}}GIF.prototype.setOption=function(key,value){this.options[key]=value;if(this._canvas!=null&&(key==="width"||key==="height")){return this._canvas[key]=value}};GIF.prototype.setOptions=function(options){var key,results,value;results=[];for(key in options){if(!hasProp.call(options,key))continue;value=options[key];results.push(this.setOption(key,value))}return results};GIF.prototype.addFrame=function(image,options){var frame,key;if(options==null){options={}}frame={};frame.transparent=this.options.transparent;for(key in frameDefaults){frame[key]=options[key]||frameDefaults[key]}if(this.options.width==null){this.setOption("width",image.width)}if(this.options.height==null){this.setOption("height",image.height)}if(typeof ImageData!=="undefined"&&ImageData!==null&&image instanceof ImageData){frame.data=image.data}else if(typeof CanvasRenderingContext2D!=="undefined"&&CanvasRenderingContext2D!==null&&image instanceof CanvasRenderingContext2D||typeof WebGLRenderingContext!=="undefined"&&WebGLRenderingContext!==null&&image instanceof WebGLRenderingContext){if(options.copy){frame.data=this.getContextData(image)}else{frame.context=image}}else if(image.childNodes!=null){if(options.copy){frame.data=this.getImageData(image)}else{frame.image=image}}else{throw new Error("Invalid image")}return this.frames.push(frame)};GIF.prototype.render=function(){var i,j,numWorkers,ref;if(this.running){throw new Error("Already running")}if(this.options.width==null||this.options.height==null){throw new Error("Width and height must be set prior to rendering")}this.running=true;this.nextFrame=0;this.finishedFrames=0;this.imageParts=function(){var j,ref,results;results=[];for(i=j=0,ref=this.frames.length;0<=ref?j<ref:j>ref;i=0<=ref?++j:--j){results.push(null)}return results}.call(this);numWorkers=this.spawnWorkers();if(this.options.globalPalette===true){this.renderNextFrame()}else{for(i=j=0,ref=numWorkers;0<=ref?j<ref:j>ref;i=0<=ref?++j:--j){this.renderNextFrame()}}this.emit("start");return this.emit("progress",0)};GIF.prototype.abort=function(){var worker;while(true){worker=this.activeWorkers.shift();if(worker==null){break}this.log("killing active worker");worker.terminate()}this.running=false;return this.emit("abort")};GIF.prototype.spawnWorkers=function(){var j,numWorkers,ref,results;numWorkers=Math.min(this.options.workers,this.frames.length);(function(){results=[];for(var j=ref=this.freeWorkers.length;ref<=numWorkers?j<numWorkers:j>numWorkers;ref<=numWorkers?j++:j--){results.push(j)}return results}).apply(this).forEach(function(_this){return function(i){var worker;_this.log("spawning worker "+i);worker=new Worker(_this.options.workerScript);worker.onmessage=function(event){_this.activeWorkers.splice(_this.activeWorkers.indexOf(worker),1);_this.freeWorkers.push(worker);return _this.frameFinished(event.data)};return _this.freeWorkers.push(worker)}}(this));return numWorkers};GIF.prototype.frameFinished=function(frame){var i,j,ref;this.log("frame "+frame.index+" finished - "+this.activeWorkers.length+" active");this.finishedFrames++;this.emit("progress",this.finishedFrames/this.frames.length);this.imageParts[frame.index]=frame;if(this.options.globalPalette===true){this.options.globalPalette=frame.globalPalette;this.log("global palette analyzed");if(this.frames.length>2){for(i=j=1,ref=this.freeWorkers.length;1<=ref?j<ref:j>ref;i=1<=ref?++j:--j){this.renderNextFrame()}}}if(indexOf.call(this.imageParts,null)>=0){return this.renderNextFrame()}else{return this.finishRendering()}};GIF.prototype.finishRendering=function(){var data,frame,i,image,j,k,l,len,len1,len2,len3,offset,page,ref,ref1,ref2;len=0;ref=this.imageParts;for(j=0,len1=ref.length;j<len1;j++){frame=ref[j];len+=(frame.data.length-1)*frame.pageSize+frame.cursor}len+=frame.pageSize-frame.cursor;this.log("rendering finished - filesize "+Math.round(len/1e3)+"kb");data=new Uint8Array(len);offset=0;ref1=this.imageParts;for(k=0,len2=ref1.length;k<len2;k++){frame=ref1[k];ref2=frame.data;for(i=l=0,len3=ref2.length;l<len3;i=++l){page=ref2[i];data.set(page,offset);if(i===frame.data.length-1){offset+=frame.cursor}else{offset+=frame.pageSize}}}image=new Blob([data],{type:"image/gif"});return this.emit("finished",image,data)};GIF.prototype.renderNextFrame=function(){var frame,task,worker;if(this.freeWorkers.length===0){throw new Error("No free workers")}if(this.nextFrame>=this.frames.length){return}frame=this.frames[this.nextFrame++];worker=this.freeWorkers.shift();task=this.getTask(frame);this.log("starting frame "+(task.index+1)+" of "+this.frames.length);this.activeWorkers.push(worker);return worker.postMessage(task)};GIF.prototype.getContextData=function(ctx){return ctx.getImageData(0,0,this.options.width,this.options.height).data};GIF.prototype.getImageData=function(image){var ctx;if(this._canvas==null){this._canvas=document.createElement("canvas");this._canvas.width=this.options.width;this._canvas.height=this.options.height}ctx=this._canvas.getContext("2d");ctx.setFill=this.options.background;ctx.fillRect(0,0,this.options.width,this.options.height);ctx.drawImage(image,0,0);return this.getContextData(ctx)};GIF.prototype.getTask=function(frame){var index,task;index=this.frames.indexOf(frame);task={index:index,last:index===this.frames.length-1,delay:frame.delay,transparent:frame.transparent,width:this.options.width,height:this.options.height,quality:this.options.quality,dither:this.options.dither,globalPalette:this.options.globalPalette,repeat:this.options.repeat,canTransfer:browser.name==="chrome"};if(frame.data!=null){task.data=frame.data}else if(frame.context!=null){task.data=this.getContextData(frame.context)}else if(frame.image!=null){task.data=this.getImageData(frame.image)}else{throw new Error("Invalid frame")}return task};GIF.prototype.log=function(){var args;args=1<=arguments.length?slice.call(arguments,0):[];if(!this.options.debug){return}return console.log.apply(console,args)};return GIF}(EventEmitter);module.exports=GIF},{"./browser.coffee":2,events:1}]},{},[3])(3)});
3
+ //# sourceMappingURL=gif.js.map
public/js/gif.worker.js ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ // gif.worker.js 0.2.0 - https://github.com/jnordberg/gif.js
2
+ (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){var NeuQuant=require("./TypedNeuQuant.js");var LZWEncoder=require("./LZWEncoder.js");function ByteArray(){this.page=-1;this.pages=[];this.newPage()}ByteArray.pageSize=4096;ByteArray.charMap={};for(var i=0;i<256;i++)ByteArray.charMap[i]=String.fromCharCode(i);ByteArray.prototype.newPage=function(){this.pages[++this.page]=new Uint8Array(ByteArray.pageSize);this.cursor=0};ByteArray.prototype.getData=function(){var rv="";for(var p=0;p<this.pages.length;p++){for(var i=0;i<ByteArray.pageSize;i++){rv+=ByteArray.charMap[this.pages[p][i]]}}return rv};ByteArray.prototype.writeByte=function(val){if(this.cursor>=ByteArray.pageSize)this.newPage();this.pages[this.page][this.cursor++]=val};ByteArray.prototype.writeUTFBytes=function(string){for(var l=string.length,i=0;i<l;i++)this.writeByte(string.charCodeAt(i))};ByteArray.prototype.writeBytes=function(array,offset,length){for(var l=length||array.length,i=offset||0;i<l;i++)this.writeByte(array[i])};function GIFEncoder(width,height){this.width=~~width;this.height=~~height;this.transparent=null;this.transIndex=0;this.repeat=-1;this.delay=0;this.image=null;this.pixels=null;this.indexedPixels=null;this.colorDepth=null;this.colorTab=null;this.neuQuant=null;this.usedEntry=new Array;this.palSize=7;this.dispose=-1;this.firstFrame=true;this.sample=10;this.dither=false;this.globalPalette=false;this.out=new ByteArray}GIFEncoder.prototype.setDelay=function(milliseconds){this.delay=Math.round(milliseconds/10)};GIFEncoder.prototype.setFrameRate=function(fps){this.delay=Math.round(100/fps)};GIFEncoder.prototype.setDispose=function(disposalCode){if(disposalCode>=0)this.dispose=disposalCode};GIFEncoder.prototype.setRepeat=function(repeat){this.repeat=repeat};GIFEncoder.prototype.setTransparent=function(color){this.transparent=color};GIFEncoder.prototype.addFrame=function(imageData){this.image=imageData;this.colorTab=this.globalPalette&&this.globalPalette.slice?this.globalPalette:null;this.getImagePixels();this.analyzePixels();if(this.globalPalette===true)this.globalPalette=this.colorTab;if(this.firstFrame){this.writeLSD();this.writePalette();if(this.repeat>=0){this.writeNetscapeExt()}}this.writeGraphicCtrlExt();this.writeImageDesc();if(!this.firstFrame&&!this.globalPalette)this.writePalette();this.writePixels();this.firstFrame=false};GIFEncoder.prototype.finish=function(){this.out.writeByte(59)};GIFEncoder.prototype.setQuality=function(quality){if(quality<1)quality=1;this.sample=quality};GIFEncoder.prototype.setDither=function(dither){if(dither===true)dither="FloydSteinberg";this.dither=dither};GIFEncoder.prototype.setGlobalPalette=function(palette){this.globalPalette=palette};GIFEncoder.prototype.getGlobalPalette=function(){return this.globalPalette&&this.globalPalette.slice&&this.globalPalette.slice(0)||this.globalPalette};GIFEncoder.prototype.writeHeader=function(){this.out.writeUTFBytes("GIF89a")};GIFEncoder.prototype.analyzePixels=function(){if(!this.colorTab){this.neuQuant=new NeuQuant(this.pixels,this.sample);this.neuQuant.buildColormap();this.colorTab=this.neuQuant.getColormap()}if(this.dither){this.ditherPixels(this.dither.replace("-serpentine",""),this.dither.match(/-serpentine/)!==null)}else{this.indexPixels()}this.pixels=null;this.colorDepth=8;this.palSize=7;if(this.transparent!==null){this.transIndex=this.findClosest(this.transparent,true)}};GIFEncoder.prototype.indexPixels=function(imgq){var nPix=this.pixels.length/3;this.indexedPixels=new Uint8Array(nPix);var k=0;for(var j=0;j<nPix;j++){var index=this.findClosestRGB(this.pixels[k++]&255,this.pixels[k++]&255,this.pixels[k++]&255);this.usedEntry[index]=true;this.indexedPixels[j]=index}};GIFEncoder.prototype.ditherPixels=function(kernel,serpentine){var kernels={FalseFloydSteinberg:[[3/8,1,0],[3/8,0,1],[2/8,1,1]],FloydSteinberg:[[7/16,1,0],[3/16,-1,1],[5/16,0,1],[1/16,1,1]],Stucki:[[8/42,1,0],[4/42,2,0],[2/42,-2,1],[4/42,-1,1],[8/42,0,1],[4/42,1,1],[2/42,2,1],[1/42,-2,2],[2/42,-1,2],[4/42,0,2],[2/42,1,2],[1/42,2,2]],Atkinson:[[1/8,1,0],[1/8,2,0],[1/8,-1,1],[1/8,0,1],[1/8,1,1],[1/8,0,2]]};if(!kernel||!kernels[kernel]){throw"Unknown dithering kernel: "+kernel}var ds=kernels[kernel];var index=0,height=this.height,width=this.width,data=this.pixels;var direction=serpentine?-1:1;this.indexedPixels=new Uint8Array(this.pixels.length/3);for(var y=0;y<height;y++){if(serpentine)direction=direction*-1;for(var x=direction==1?0:width-1,xend=direction==1?width:0;x!==xend;x+=direction){index=y*width+x;var idx=index*3;var r1=data[idx];var g1=data[idx+1];var b1=data[idx+2];idx=this.findClosestRGB(r1,g1,b1);this.usedEntry[idx]=true;this.indexedPixels[index]=idx;idx*=3;var r2=this.colorTab[idx];var g2=this.colorTab[idx+1];var b2=this.colorTab[idx+2];var er=r1-r2;var eg=g1-g2;var eb=b1-b2;for(var i=direction==1?0:ds.length-1,end=direction==1?ds.length:0;i!==end;i+=direction){var x1=ds[i][1];var y1=ds[i][2];if(x1+x>=0&&x1+x<width&&y1+y>=0&&y1+y<height){var d=ds[i][0];idx=index+x1+y1*width;idx*=3;data[idx]=Math.max(0,Math.min(255,data[idx]+er*d));data[idx+1]=Math.max(0,Math.min(255,data[idx+1]+eg*d));data[idx+2]=Math.max(0,Math.min(255,data[idx+2]+eb*d))}}}}};GIFEncoder.prototype.findClosest=function(c,used){return this.findClosestRGB((c&16711680)>>16,(c&65280)>>8,c&255,used)};GIFEncoder.prototype.findClosestRGB=function(r,g,b,used){if(this.colorTab===null)return-1;if(this.neuQuant&&!used){return this.neuQuant.lookupRGB(r,g,b)}var c=b|g<<8|r<<16;var minpos=0;var dmin=256*256*256;var len=this.colorTab.length;for(var i=0,index=0;i<len;index++){var dr=r-(this.colorTab[i++]&255);var dg=g-(this.colorTab[i++]&255);var db=b-(this.colorTab[i++]&255);var d=dr*dr+dg*dg+db*db;if((!used||this.usedEntry[index])&&d<dmin){dmin=d;minpos=index}}return minpos};GIFEncoder.prototype.getImagePixels=function(){var w=this.width;var h=this.height;this.pixels=new Uint8Array(w*h*3);var data=this.image;var srcPos=0;var count=0;for(var i=0;i<h;i++){for(var j=0;j<w;j++){this.pixels[count++]=data[srcPos++];this.pixels[count++]=data[srcPos++];this.pixels[count++]=data[srcPos++];srcPos++}}};GIFEncoder.prototype.writeGraphicCtrlExt=function(){this.out.writeByte(33);this.out.writeByte(249);this.out.writeByte(4);var transp,disp;if(this.transparent===null){transp=0;disp=0}else{transp=1;disp=2}if(this.dispose>=0){disp=dispose&7}disp<<=2;this.out.writeByte(0|disp|0|transp);this.writeShort(this.delay);this.out.writeByte(this.transIndex);this.out.writeByte(0)};GIFEncoder.prototype.writeImageDesc=function(){this.out.writeByte(44);this.writeShort(0);this.writeShort(0);this.writeShort(this.width);this.writeShort(this.height);if(this.firstFrame||this.globalPalette){this.out.writeByte(0)}else{this.out.writeByte(128|0|0|0|this.palSize)}};GIFEncoder.prototype.writeLSD=function(){this.writeShort(this.width);this.writeShort(this.height);this.out.writeByte(128|112|0|this.palSize);this.out.writeByte(0);this.out.writeByte(0)};GIFEncoder.prototype.writeNetscapeExt=function(){this.out.writeByte(33);this.out.writeByte(255);this.out.writeByte(11);this.out.writeUTFBytes("NETSCAPE2.0");this.out.writeByte(3);this.out.writeByte(1);this.writeShort(this.repeat);this.out.writeByte(0)};GIFEncoder.prototype.writePalette=function(){this.out.writeBytes(this.colorTab);var n=3*256-this.colorTab.length;for(var i=0;i<n;i++)this.out.writeByte(0)};GIFEncoder.prototype.writeShort=function(pValue){this.out.writeByte(pValue&255);this.out.writeByte(pValue>>8&255)};GIFEncoder.prototype.writePixels=function(){var enc=new LZWEncoder(this.width,this.height,this.indexedPixels,this.colorDepth);enc.encode(this.out)};GIFEncoder.prototype.stream=function(){return this.out};module.exports=GIFEncoder},{"./LZWEncoder.js":2,"./TypedNeuQuant.js":3}],2:[function(require,module,exports){var EOF=-1;var BITS=12;var HSIZE=5003;var masks=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535];function LZWEncoder(width,height,pixels,colorDepth){var initCodeSize=Math.max(2,colorDepth);var accum=new Uint8Array(256);var htab=new Int32Array(HSIZE);var codetab=new Int32Array(HSIZE);var cur_accum,cur_bits=0;var a_count;var free_ent=0;var maxcode;var clear_flg=false;var g_init_bits,ClearCode,EOFCode;function char_out(c,outs){accum[a_count++]=c;if(a_count>=254)flush_char(outs)}function cl_block(outs){cl_hash(HSIZE);free_ent=ClearCode+2;clear_flg=true;output(ClearCode,outs)}function cl_hash(hsize){for(var i=0;i<hsize;++i)htab[i]=-1}function compress(init_bits,outs){var fcode,c,i,ent,disp,hsize_reg,hshift;g_init_bits=init_bits;clear_flg=false;n_bits=g_init_bits;maxcode=MAXCODE(n_bits);ClearCode=1<<init_bits-1;EOFCode=ClearCode+1;free_ent=ClearCode+2;a_count=0;ent=nextPixel();hshift=0;for(fcode=HSIZE;fcode<65536;fcode*=2)++hshift;hshift=8-hshift;hsize_reg=HSIZE;cl_hash(hsize_reg);output(ClearCode,outs);outer_loop:while((c=nextPixel())!=EOF){fcode=(c<<BITS)+ent;i=c<<hshift^ent;if(htab[i]===fcode){ent=codetab[i];continue}else if(htab[i]>=0){disp=hsize_reg-i;if(i===0)disp=1;do{if((i-=disp)<0)i+=hsize_reg;if(htab[i]===fcode){ent=codetab[i];continue outer_loop}}while(htab[i]>=0)}output(ent,outs);ent=c;if(free_ent<1<<BITS){codetab[i]=free_ent++;htab[i]=fcode}else{cl_block(outs)}}output(ent,outs);output(EOFCode,outs)}function encode(outs){outs.writeByte(initCodeSize);remaining=width*height;curPixel=0;compress(initCodeSize+1,outs);outs.writeByte(0)}function flush_char(outs){if(a_count>0){outs.writeByte(a_count);outs.writeBytes(accum,0,a_count);a_count=0}}function MAXCODE(n_bits){return(1<<n_bits)-1}function nextPixel(){if(remaining===0)return EOF;--remaining;var pix=pixels[curPixel++];return pix&255}function output(code,outs){cur_accum&=masks[cur_bits];if(cur_bits>0)cur_accum|=code<<cur_bits;else cur_accum=code;cur_bits+=n_bits;while(cur_bits>=8){char_out(cur_accum&255,outs);cur_accum>>=8;cur_bits-=8}if(free_ent>maxcode||clear_flg){if(clear_flg){maxcode=MAXCODE(n_bits=g_init_bits);clear_flg=false}else{++n_bits;if(n_bits==BITS)maxcode=1<<BITS;else maxcode=MAXCODE(n_bits)}}if(code==EOFCode){while(cur_bits>0){char_out(cur_accum&255,outs);cur_accum>>=8;cur_bits-=8}flush_char(outs)}}this.encode=encode}module.exports=LZWEncoder},{}],3:[function(require,module,exports){var ncycles=100;var netsize=256;var maxnetpos=netsize-1;var netbiasshift=4;var intbiasshift=16;var intbias=1<<intbiasshift;var gammashift=10;var gamma=1<<gammashift;var betashift=10;var beta=intbias>>betashift;var betagamma=intbias<<gammashift-betashift;var initrad=netsize>>3;var radiusbiasshift=6;var radiusbias=1<<radiusbiasshift;var initradius=initrad*radiusbias;var radiusdec=30;var alphabiasshift=10;var initalpha=1<<alphabiasshift;var alphadec;var radbiasshift=8;var radbias=1<<radbiasshift;var alpharadbshift=alphabiasshift+radbiasshift;var alpharadbias=1<<alpharadbshift;var prime1=499;var prime2=491;var prime3=487;var prime4=503;var minpicturebytes=3*prime4;function NeuQuant(pixels,samplefac){var network;var netindex;var bias;var freq;var radpower;function init(){network=[];netindex=new Int32Array(256);bias=new Int32Array(netsize);freq=new Int32Array(netsize);radpower=new Int32Array(netsize>>3);var i,v;for(i=0;i<netsize;i++){v=(i<<netbiasshift+8)/netsize;network[i]=new Float64Array([v,v,v,0]);freq[i]=intbias/netsize;bias[i]=0}}function unbiasnet(){for(var i=0;i<netsize;i++){network[i][0]>>=netbiasshift;network[i][1]>>=netbiasshift;network[i][2]>>=netbiasshift;network[i][3]=i}}function altersingle(alpha,i,b,g,r){network[i][0]-=alpha*(network[i][0]-b)/initalpha;network[i][1]-=alpha*(network[i][1]-g)/initalpha;network[i][2]-=alpha*(network[i][2]-r)/initalpha}function alterneigh(radius,i,b,g,r){var lo=Math.abs(i-radius);var hi=Math.min(i+radius,netsize);var j=i+1;var k=i-1;var m=1;var p,a;while(j<hi||k>lo){a=radpower[m++];if(j<hi){p=network[j++];p[0]-=a*(p[0]-b)/alpharadbias;p[1]-=a*(p[1]-g)/alpharadbias;p[2]-=a*(p[2]-r)/alpharadbias}if(k>lo){p=network[k--];p[0]-=a*(p[0]-b)/alpharadbias;p[1]-=a*(p[1]-g)/alpharadbias;p[2]-=a*(p[2]-r)/alpharadbias}}}function contest(b,g,r){var bestd=~(1<<31);var bestbiasd=bestd;var bestpos=-1;var bestbiaspos=bestpos;var i,n,dist,biasdist,betafreq;for(i=0;i<netsize;i++){n=network[i];dist=Math.abs(n[0]-b)+Math.abs(n[1]-g)+Math.abs(n[2]-r);if(dist<bestd){bestd=dist;bestpos=i}biasdist=dist-(bias[i]>>intbiasshift-netbiasshift);if(biasdist<bestbiasd){bestbiasd=biasdist;bestbiaspos=i}betafreq=freq[i]>>betashift;freq[i]-=betafreq;bias[i]+=betafreq<<gammashift}freq[bestpos]+=beta;bias[bestpos]-=betagamma;return bestbiaspos}function inxbuild(){var i,j,p,q,smallpos,smallval,previouscol=0,startpos=0;for(i=0;i<netsize;i++){p=network[i];smallpos=i;smallval=p[1];for(j=i+1;j<netsize;j++){q=network[j];if(q[1]<smallval){smallpos=j;smallval=q[1]}}q=network[smallpos];if(i!=smallpos){j=q[0];q[0]=p[0];p[0]=j;j=q[1];q[1]=p[1];p[1]=j;j=q[2];q[2]=p[2];p[2]=j;j=q[3];q[3]=p[3];p[3]=j}if(smallval!=previouscol){netindex[previouscol]=startpos+i>>1;for(j=previouscol+1;j<smallval;j++)netindex[j]=i;previouscol=smallval;startpos=i}}netindex[previouscol]=startpos+maxnetpos>>1;for(j=previouscol+1;j<256;j++)netindex[j]=maxnetpos}function inxsearch(b,g,r){var a,p,dist;var bestd=1e3;var best=-1;var i=netindex[g];var j=i-1;while(i<netsize||j>=0){if(i<netsize){p=network[i];dist=p[1]-g;if(dist>=bestd)i=netsize;else{i++;if(dist<0)dist=-dist;a=p[0]-b;if(a<0)a=-a;dist+=a;if(dist<bestd){a=p[2]-r;if(a<0)a=-a;dist+=a;if(dist<bestd){bestd=dist;best=p[3]}}}}if(j>=0){p=network[j];dist=g-p[1];if(dist>=bestd)j=-1;else{j--;if(dist<0)dist=-dist;a=p[0]-b;if(a<0)a=-a;dist+=a;if(dist<bestd){a=p[2]-r;if(a<0)a=-a;dist+=a;if(dist<bestd){bestd=dist;best=p[3]}}}}}return best}function learn(){var i;var lengthcount=pixels.length;var alphadec=30+(samplefac-1)/3;var samplepixels=lengthcount/(3*samplefac);var delta=~~(samplepixels/ncycles);var alpha=initalpha;var radius=initradius;var rad=radius>>radiusbiasshift;if(rad<=1)rad=0;for(i=0;i<rad;i++)radpower[i]=alpha*((rad*rad-i*i)*radbias/(rad*rad));var step;if(lengthcount<minpicturebytes){samplefac=1;step=3}else if(lengthcount%prime1!==0){step=3*prime1}else if(lengthcount%prime2!==0){step=3*prime2}else if(lengthcount%prime3!==0){step=3*prime3}else{step=3*prime4}var b,g,r,j;var pix=0;i=0;while(i<samplepixels){b=(pixels[pix]&255)<<netbiasshift;g=(pixels[pix+1]&255)<<netbiasshift;r=(pixels[pix+2]&255)<<netbiasshift;j=contest(b,g,r);altersingle(alpha,j,b,g,r);if(rad!==0)alterneigh(rad,j,b,g,r);pix+=step;if(pix>=lengthcount)pix-=lengthcount;i++;if(delta===0)delta=1;if(i%delta===0){alpha-=alpha/alphadec;radius-=radius/radiusdec;rad=radius>>radiusbiasshift;if(rad<=1)rad=0;for(j=0;j<rad;j++)radpower[j]=alpha*((rad*rad-j*j)*radbias/(rad*rad))}}}function buildColormap(){init();learn();unbiasnet();inxbuild()}this.buildColormap=buildColormap;function getColormap(){var map=[];var index=[];for(var i=0;i<netsize;i++)index[network[i][3]]=i;var k=0;for(var l=0;l<netsize;l++){var j=index[l];map[k++]=network[j][0];map[k++]=network[j][1];map[k++]=network[j][2]}return map}this.getColormap=getColormap;this.lookupRGB=inxsearch}module.exports=NeuQuant},{}],4:[function(require,module,exports){var GIFEncoder,renderFrame;GIFEncoder=require("./GIFEncoder.js");renderFrame=function(frame){var encoder,page,stream,transfer;encoder=new GIFEncoder(frame.width,frame.height);if(frame.index===0){encoder.writeHeader()}else{encoder.firstFrame=false}encoder.setTransparent(frame.transparent);encoder.setRepeat(frame.repeat);encoder.setDelay(frame.delay);encoder.setQuality(frame.quality);encoder.setDither(frame.dither);encoder.setGlobalPalette(frame.globalPalette);encoder.addFrame(frame.data);if(frame.last){encoder.finish()}if(frame.globalPalette===true){frame.globalPalette=encoder.getGlobalPalette()}stream=encoder.stream();frame.data=stream.pages;frame.cursor=stream.cursor;frame.pageSize=stream.constructor.pageSize;if(frame.canTransfer){transfer=function(){var i,len,ref,results;ref=frame.data;results=[];for(i=0,len=ref.length;i<len;i++){page=ref[i];results.push(page.buffer)}return results}();return self.postMessage(frame,transfer)}else{return self.postMessage(frame)}};self.onmessage=function(event){return renderFrame(event.data)}},{"./GIFEncoder.js":1}]},{},[4]);
3
+ //# sourceMappingURL=gif.worker.js.map
public/next.svg ADDED
public/vercel.svg ADDED
public/window.svg ADDED
sketches/BounceSketch.js ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export const bounceReasoning = "For 'bounce', I'll implement simple physics with gravity and collision detection. Each particle will have its own velocity and acceleration, creating natural bouncing motions. Adding slight randomness to the bounce heights and timing creates a more organic, playful feel that captures the essence of bouncing.";
2
+
3
+ export const bounceSketch = `let font;
4
+ let fontSize = 200;
5
+ let word = "bounce";
6
+ let points;
7
+ let particles = [];
8
+ let gravity = 0.5;
9
+ let bounce = -0.7;
10
+ let friction = 0.99;
11
+ let particleMinSize = 3;
12
+ let particleMaxSize = 7;
13
+
14
+ let color1 = "#217BFE";
15
+ let color2 = "#078BFE";
16
+ let color3 = "#AC87EB";
17
+
18
+ function preload() {
19
+ font = loadFont('fonts/GoogleSans-Bold.ttf');
20
+ }
21
+
22
+ function setup() {
23
+ createCanvas(500, 500);
24
+ background(0);
25
+ textFont(font);
26
+ textSize(fontSize);
27
+ textAlign(CENTER, CENTER);
28
+
29
+ // Get the width of the text
30
+ let textW = textWidth(word);
31
+
32
+ // If text is too wide, scale down fontSize
33
+ if (textW > width * 0.8) {
34
+ fontSize = fontSize * (width * 0.8) / textW;
35
+ textSize(fontSize);
36
+ textW = textWidth(word);
37
+ }
38
+
39
+ points = font.textToPoints(word, width/2 - textW/2, height/2 + fontSize/3, fontSize, {
40
+ sampleFactor: 0.1
41
+ });
42
+
43
+ // Find min and max x positions for color gradient
44
+ let minX = points[0].x;
45
+ let maxX = points[0].x;
46
+ for (let pt of points) {
47
+ minX = min(minX, pt.x);
48
+ maxX = max(maxX, pt.x);
49
+ }
50
+
51
+ for (let pt of points) {
52
+ let normalizedX = map(pt.x, minX, maxX, 0, 1);
53
+ particles.push(new Particle(pt.x, pt.y, normalizedX));
54
+ }
55
+ }
56
+
57
+ function draw() {
58
+ blendMode(BLEND);
59
+ background(0);
60
+ blendMode(SCREEN);
61
+
62
+ for (let particle of particles) {
63
+ particle.update();
64
+ particle.display();
65
+ }
66
+ }
67
+
68
+ class Particle {
69
+ constructor(x, y, normalizedX) {
70
+ this.pos = createVector(x, y);
71
+ this.vel = createVector(random(-2, 2), random(-10, -5));
72
+ this.acc = createVector(0, gravity);
73
+ this.size = random(particleMinSize, particleMaxSize);
74
+ this.originalY = y;
75
+ this.colorValue = this.getColor(normalizedX);
76
+ this.frameDelay = 30; // Delay for about 30 frames
77
+ }
78
+
79
+ getColor(normalizedX) {
80
+ let particleColor;
81
+ if (normalizedX < 0.5) {
82
+ particleColor = lerpColor(color(color1), color(color2), normalizedX * 2);
83
+ } else {
84
+ particleColor = lerpColor(color(color2), color(color3), (normalizedX - 0.5) * 2);
85
+ }
86
+ return particleColor;
87
+ }
88
+
89
+ update() {
90
+ if (this.frameDelay > 0) {
91
+ this.frameDelay--;
92
+ return; // Pause movement for the delay duration
93
+ }
94
+
95
+ this.vel.add(this.acc);
96
+ this.pos.add(this.vel);
97
+ this.vel.x *= friction;
98
+
99
+ if (this.pos.y > height - this.size / 2) {
100
+ this.pos.y = height - this.size / 2;
101
+ this.vel.y *= bounce;
102
+ }
103
+
104
+ if (this.pos.x < this.size / 2) {
105
+ this.pos.x = this.size / 2;
106
+ this.vel.x *= bounce;
107
+ } else if (this.pos.x > width - this.size / 2) {
108
+ this.pos.x = width - this.size / 2;
109
+ this.vel.x *= bounce;
110
+ }
111
+
112
+ if (this.pos.y > height + 100) {
113
+ this.pos.y = this.originalY;
114
+ this.vel.y = random(-10, -5);
115
+ this.frameDelay = 30; // Reset delay when particle resets
116
+ }
117
+ }
118
+
119
+ display() {
120
+ noStroke();
121
+ fill(this.colorValue);
122
+ ellipse(this.pos.x, this.pos.y, this.size, this.size);
123
+ }
124
+ }`;
sketches/FluidSketch.js ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export const fluidReasoning = "To capture the essence of 'fluid', I'll use Perlin noise to create smooth, organic movement of particles. The particles will flow like water or liquid, with each particle following its own noise-based path while maintaining a cohesive, flowing appearance. The blue gradient colors reinforce the liquid feeling, and the screen blend mode creates a glowing effect that enhances the fluid motion.";
2
+
3
+ export const fluidSketch = `let font;
4
+ let fontSize = 200;
5
+ let word = "fluid";
6
+ let points;
7
+ let particles = [];
8
+ let particleMinSize = 3;
9
+ let particleMaxSize = 7;
10
+
11
+ // Fluid effect parameters
12
+ let noiseScale = 0.015; // Scale of the Perlin noise - adjust for wave size
13
+ let noiseStrength = 20; // Intensity of the noise displacement
14
+ let noiseSpeed = 0.002; // Speed of the noise evolution
15
+
16
+ // Colors for gradient
17
+ let color1 = "#217BFE";
18
+ let color2 = "#078BFE";
19
+ let color3 = "#AC87EB";
20
+
21
+ function preload() {
22
+ font = loadFont('/fonts/GoogleSans-Bold.ttf');
23
+ }
24
+
25
+ function setup() {
26
+ createCanvas(500, 500);
27
+ background(0);
28
+ textFont(font);
29
+ textSize(fontSize);
30
+ textAlign(CENTER, CENTER);
31
+
32
+ // Get the width of the text
33
+ let textW = textWidth(word);
34
+
35
+ // If text is too wide, scale down fontSize
36
+ if (textW > width * 0.8) {
37
+ fontSize = fontSize * (width * 0.8) / textW;
38
+ textSize(fontSize);
39
+ textW = textWidth(word);
40
+ }
41
+
42
+ // Get points for the text centered in canvas
43
+ points = font.textToPoints(word, width/2 - textW/2, height/2 + fontSize/3, fontSize, {
44
+ sampleFactor: 0.1
45
+ });
46
+
47
+ // Create particles at each point
48
+ for (let i = 0; i < points.length; i++) {
49
+ particles.push(new Particle(points[i].x, points[i].y, i, points.length));
50
+ }
51
+ }
52
+
53
+ function draw() {
54
+ blendMode(BLEND); // Reset to default blend mode first
55
+ background(0); // Clear with black background
56
+ blendMode(SCREEN); // Then set screen blend mode for particles
57
+
58
+ for (let particle of particles) {
59
+ particle.update();
60
+ particle.display();
61
+ }
62
+ }
63
+
64
+ class Particle {
65
+ constructor(x, y, index, totalParticles) {
66
+ this.pos = createVector(x, y);
67
+ this.originalPos = createVector(x, y);
68
+ this.originalX = x;
69
+ this.originalY = y;
70
+ this.size = random(particleMinSize, particleMaxSize);
71
+ this.alpha = 255;
72
+ this.colorValue = this.getColor(index, totalParticles);
73
+ }
74
+
75
+ getColor(index, totalParticles) {
76
+ let normalizedIndex = index / (totalParticles - 1);
77
+ let particleColor;
78
+ if (normalizedIndex < 0.5) {
79
+ particleColor = lerpColor(color(color1), color(color2), normalizedIndex * 2);
80
+ } else {
81
+ particleColor = lerpColor(color(color2), color(color3), (normalizedIndex - 0.5) * 2);
82
+ }
83
+ return particleColor;
84
+ }
85
+
86
+ update() {
87
+ let noiseValueX = noise((this.originalX + frameCount) * noiseScale,
88
+ this.originalY * noiseScale,
89
+ frameCount * noiseSpeed);
90
+ let noiseValueY = noise(this.originalX * noiseScale,
91
+ this.originalY * noiseScale,
92
+ frameCount * noiseSpeed + 1000);
93
+
94
+ let offsetX = map(noiseValueX, 0, 1, -noiseStrength, noiseStrength);
95
+ let offsetY = map(noiseValueY, 0, 1, -noiseStrength, noiseStrength);
96
+
97
+ this.pos.x = this.originalPos.x + offsetX;
98
+ this.pos.y = this.originalPos.y + offsetY;
99
+ }
100
+
101
+ display() {
102
+ noStroke();
103
+ fill(this.colorValue);
104
+ ellipse(this.pos.x, this.pos.y, this.size, this.size);
105
+ }
106
+ }`;
sketches/InitialSketch.js ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export const initialSketch = `
2
+ let font;
3
+ let fontSize = 200;
4
+ let word = "hello";
5
+ let points;
6
+ let particles = [];
7
+ let particleMinSize = 4;
8
+ let particleMaxSize = 8;
9
+
10
+ // Jump effect parameters
11
+ let jumpAmplitude = 5;
12
+ let jumpSpeed = 0.03;
13
+ let jumpOffsetRange = 2;
14
+
15
+ // Colors for gradient
16
+ let color1 = "#217BFE";
17
+ let color2 = "#078BFE";
18
+ let color3 = "#AC87EB";
19
+
20
+ function preload() {
21
+ font = loadFont('/fonts/GoogleSans-Bold.ttf');
22
+ }
23
+
24
+ function setup() {
25
+ createCanvas(500, 500);
26
+ background(0);
27
+ textFont(font);
28
+ textSize(fontSize);
29
+ textAlign(CENTER, CENTER);
30
+
31
+ // Get the width of the text
32
+ let textW = textWidth(word);
33
+
34
+ // If text is too wide, scale down fontSize
35
+ if (textW > width * 0.8) {
36
+ fontSize = fontSize * (width * 0.8) / textW;
37
+ textSize(fontSize);
38
+ textW = textWidth(word);
39
+ }
40
+
41
+ // Get points for the text centered in canvas
42
+ points = font.textToPoints(word, width/2 - textW/2, height/2 + fontSize/3, fontSize, {
43
+ sampleFactor: 0.1
44
+ });
45
+
46
+ // Create particles at each point
47
+ for (let i = 0; i < points.length; i++) {
48
+ particles.push(new Particle(points[i].x, points[i].y, i, points.length));
49
+ }
50
+ }
51
+
52
+ function draw() {
53
+ blendMode(BLEND);
54
+ background(0);
55
+ blendMode(SCREEN);
56
+
57
+ for (let particle of particles) {
58
+ particle.update();
59
+ particle.display();
60
+ }
61
+ }
62
+
63
+ class Particle {
64
+ constructor(x, y, index, totalParticles) {
65
+ this.pos = createVector(x, y);
66
+ this.originalPos = createVector(x, y);
67
+ this.size = random(particleMinSize, particleMaxSize);
68
+ this.alpha = 255;
69
+ this.colorValue = this.getColor(index, totalParticles);
70
+ this.jumpOffset = random(jumpOffsetRange);
71
+ }
72
+
73
+ getColor(index, totalParticles) {
74
+ let normalizedIndex = index / (totalParticles - 1);
75
+ let particleColor;
76
+ if (normalizedIndex < 0.5) {
77
+ particleColor = lerpColor(color(color1), color(color2), normalizedIndex * 2);
78
+ } else {
79
+ particleColor = lerpColor(color(color2), color(color3), (normalizedIndex - 0.5) * 2);
80
+ }
81
+ return particleColor;
82
+ }
83
+
84
+ update() {
85
+ // Subtle wave-like jumping motion
86
+ let jump = sin(frameCount * jumpSpeed + this.jumpOffset) * jumpAmplitude;
87
+ this.pos.y = this.originalPos.y + jump;
88
+ }
89
+
90
+ display() {
91
+ noStroke();
92
+ fill(this.colorValue);
93
+ ellipse(this.pos.x, this.pos.y, this.size, this.size);
94
+ }
95
+ }`;
sketches/LightSketch.js ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export const lightReasoning = "For 'light', I'll create particles that emit a soft glow and pulse rhythmically. The particles will be arranged in a pattern that suggests rays or beams of light, with subtle movement and size variations. The color palette will focus on warm, bright tones, and I'll use the screen blend mode to create authentic light-like effects.";
2
+
3
+ export const lightSketch = `let font;
4
+ let fontSize = 200;
5
+ let word = "light";
6
+ let points;
7
+ let particles = [];
8
+ let lightCycleSpeed = 0.02;
9
+ let particleMinSize = 5;
10
+ let particleMaxSize = 5;
11
+ let shadowBlurAmount = 30;
12
+ let minX, maxX;
13
+
14
+ let color1 = "#217BFE";
15
+ let color2 = "#078BFE";
16
+ let color3 = "#AC87EB";
17
+ let lightColor;
18
+
19
+ function preload() {
20
+ font = loadFont('/fonts/GoogleSans-Bold.ttf');
21
+ }
22
+
23
+ function setup() {
24
+ createCanvas(500, 500);
25
+ background(0);
26
+
27
+ lightColor = color(255, 255, 255);
28
+
29
+ textFont(font);
30
+ textSize(fontSize);
31
+ textAlign(CENTER, CENTER);
32
+
33
+ // Get the width of the text
34
+ let textW = textWidth(word);
35
+
36
+ // If text is too wide, scale down fontSize
37
+ if (textW > width * 0.8) {
38
+ fontSize = fontSize * (width * 0.8) / textW;
39
+ textSize(fontSize);
40
+ textW = textWidth(word);
41
+ }
42
+
43
+ points = font.textToPoints(word, width/2 - textW/2, height/2 + fontSize/3, fontSize, {
44
+ sampleFactor: 0.1
45
+ });
46
+
47
+ minX = width;
48
+ maxX = 0;
49
+ for (let pt of points) {
50
+ minX = min(minX, pt.x);
51
+ maxX = max(maxX, pt.x);
52
+ }
53
+
54
+ for (let i = 0; i < points.length; i++) {
55
+ let pt = points[i];
56
+ particles.push(new Particle(pt.x, pt.y, i));
57
+ }
58
+ }
59
+
60
+ function draw() {
61
+ blendMode(BLEND); // Reset to default blend mode first
62
+ background(0); // Clear with black background
63
+ blendMode(SCREEN); // Then set screen blend mode for particles
64
+
65
+ for (let particle of particles) {
66
+ particle.update();
67
+ particle.display();
68
+ }
69
+ }
70
+
71
+ class Particle {
72
+ constructor(x, y, index) {
73
+ this.pos = createVector(x, y);
74
+ this.size = random(particleMinSize, particleMaxSize);
75
+ this.alpha = 255;
76
+ this.lightOffset = index * 0.1;
77
+ }
78
+
79
+ update() {
80
+ // No position update needed for light animation
81
+ }
82
+
83
+ getBaseColor() {
84
+ let normalizedX = map(this.pos.x, minX, maxX, 0, 1);
85
+ let baseParticleColor;
86
+
87
+ if (normalizedX < 0.5) {
88
+ baseParticleColor = lerpColor(color(color1), color(color2), normalizedX * 2);
89
+ } else {
90
+ baseParticleColor = lerpColor(color(color2), color(color3), (normalizedX - 0.5) * 2);
91
+ }
92
+ return baseParticleColor;
93
+ }
94
+
95
+ display() {
96
+ let brightness = sin(frameCount * lightCycleSpeed + this.lightOffset);
97
+ brightness = map(brightness, -1, 1, 0, 1);
98
+ brightness = constrain(brightness, 0, 1);
99
+
100
+ let baseParticleColor = this.getBaseColor();
101
+ let particleColor = lerpColor(baseParticleColor, lightColor, brightness);
102
+
103
+ noStroke();
104
+
105
+ if (brightness > 0.8) {
106
+ drawingContext.shadowBlur = shadowBlurAmount;
107
+ drawingContext.shadowColor = color(255);
108
+ fill(particleColor);
109
+ ellipse(this.pos.x, this.pos.y, this.size * 1.5, this.size * 1.5);
110
+ drawingContext.shadowBlur = 0;
111
+ } else {
112
+ drawingContext.shadowBlur = 0;
113
+ fill(particleColor);
114
+ ellipse(this.pos.x, this.pos.y, this.size, this.size);
115
+ }
116
+ }
117
+ }`;
sketches/LoadingSketch.js ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export const loadingSketch = `let particles = [];
2
+ let numParticles = 28;
3
+ let circleRadius = 50;
4
+ let rotationSpeed = 0.02;
5
+ let particleMinSize = 3;
6
+ let particleMaxSize = 7;
7
+
8
+ let centerX;
9
+ let centerY;
10
+
11
+ let freeformAmplitude = 2;
12
+ let freeformSpeed = 0.01;
13
+
14
+ let color1Hex = "#217BFE";
15
+ let color2Hex = "#078BFE";
16
+ let color3Hex = "#AC87EB";
17
+ let color1;
18
+ let color2;
19
+ let color3;
20
+
21
+ function setup() {
22
+ createCanvas(500, 500);
23
+ background(0);
24
+ noStroke();
25
+
26
+ color1 = color(color1Hex);
27
+ color2 = color(color2Hex);
28
+ color3 = color(color3Hex);
29
+
30
+ centerX = width / 2;
31
+ centerY = height / 2;
32
+
33
+ for (let i = 0; i < numParticles; i++) {
34
+ particles.push(new Particle(i, numParticles));
35
+ }
36
+ }
37
+
38
+ function draw() {
39
+ background(0, 50);
40
+
41
+ for (let particle of particles) {
42
+ particle.update();
43
+ particle.display();
44
+ }
45
+ }
46
+
47
+ class Particle {
48
+ constructor(index, totalParticles) {
49
+ this.index = index;
50
+ this.totalParticles = totalParticles;
51
+ this.radiusOffset = (index / totalParticles) * TWO_PI;
52
+ this.angle = this.radiusOffset;
53
+ this.speedVariation = random(0.7, 1.3);
54
+ this.size = random(particleMinSize, particleMaxSize);
55
+ this.colorValue = this.getColor(index, totalParticles);
56
+ this.pos = createVector(0, 0);
57
+ }
58
+
59
+ getColor(index, totalParticles) {
60
+ let normalizedIndex = index / (totalParticles - 1);
61
+
62
+ let particleColor;
63
+ if (normalizedIndex < 0.5) {
64
+ particleColor = lerpColor(color1, color2, normalizedIndex * 2);
65
+ } else {
66
+ particleColor = lerpColor(color2, color3, (normalizedIndex - 0.5) * 2);
67
+ }
68
+ return particleColor;
69
+ }
70
+
71
+ update() {
72
+ this.angle += rotationSpeed * this.speedVariation;
73
+
74
+ let base_x = centerX + cos(this.angle) * circleRadius;
75
+ let base_y = centerY + sin(this.angle) * circleRadius;
76
+
77
+ let noiseX = map(noise(this.angle * 2 + frameCount * freeformSpeed), 0, 1, -freeformAmplitude, freeformAmplitude);
78
+ let noiseY = map(noise(this.angle * 2 + frameCount * freeformSpeed + 100), 0, 1, -freeformAmplitude, freeformAmplitude);
79
+
80
+ this.pos.set(base_x + noiseX, base_y + noiseY);
81
+ }
82
+
83
+ display() {
84
+ fill(this.colorValue);
85
+ ellipse(this.pos.x, this.pos.y, this.size, this.size);
86
+ }
87
+ }`;
sketches/RiseSketch.js ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export const riseReasoning = "For 'rise', I'll create a staged animation where particles gradually appear, pause briefly, then float upward. This creates a sense of emergence and ascension. Each particle follows this sequence independently with slight timing variations, creating a continuous cycle of rising elements. The fade-in adds a gentle, ethereal quality that matches the upward motion.";
2
+
3
+ export const riseSketch = `let font;
4
+ let fontSize = 200;
5
+ let word = "rise";
6
+ let points;
7
+ let particles = [];
8
+ let floatSpeed = 4;
9
+ let fadeInSpeed = 10;
10
+ let minWaitTime = 50;
11
+ let maxWaitTime = 200;
12
+ let particleMinSize = 3;
13
+ let particleMaxSize = 7;
14
+
15
+ let color1 = "#217BFE";
16
+ let color2 = "#078BFE";
17
+ let color3 = "#AC87EB";
18
+
19
+ function preload() {
20
+ font = loadFont('/fonts/GoogleSans-Bold.ttf');
21
+ }
22
+
23
+ function setup() {
24
+ createCanvas(500, 500);
25
+ background(0);
26
+ textFont(font);
27
+ textSize(fontSize);
28
+ textAlign(CENTER, CENTER);
29
+
30
+ // Get the width of the text
31
+ let textW = textWidth(word);
32
+
33
+ // If text is too wide, scale down fontSize
34
+ if (textW > width * 0.8) {
35
+ fontSize = fontSize * (width * 0.8) / textW;
36
+ textSize(fontSize);
37
+ textW = textWidth(word);
38
+ }
39
+
40
+ // Get points for the text centered in canvas
41
+ points = font.textToPoints(word, width/2 - textW/2, height/2 + fontSize/3, fontSize, {
42
+ sampleFactor: 0.1
43
+ });
44
+
45
+ // Find min and max x positions for color gradient
46
+ let minX = points[0].x;
47
+ let maxX = points[0].x;
48
+ for (let pt of points) {
49
+ minX = min(minX, pt.x);
50
+ maxX = max(maxX, pt.x);
51
+ }
52
+ let xRange = maxX - minX;
53
+
54
+ for (let pt of points) {
55
+ particles.push(new Particle(pt.x, pt.y, pt.x, minX, xRange));
56
+ }
57
+ }
58
+
59
+ function draw() {
60
+ blendMode(BLEND);
61
+ background(0);
62
+ blendMode(SCREEN);
63
+
64
+ for (let particle of particles) {
65
+ particle.update();
66
+ particle.display();
67
+ }
68
+ }
69
+
70
+ class Particle {
71
+ constructor(x, y, particleX, minX, xRange) {
72
+ this.pos = createVector(x, y);
73
+ this.originalPos = createVector(x, y);
74
+ this.originalX = x;
75
+ this.originalY = y;
76
+ this.size = random(particleMinSize, particleMaxSize);
77
+ this.alpha = 255;
78
+ this.floatSpeedVariation = random(0.5, 2.0);
79
+ this.isFadingIn = true;
80
+ this.isWaiting = false;
81
+ this.waitTime = 0;
82
+ this.particleX = particleX;
83
+ this.minX = minX;
84
+ this.xRange = xRange;
85
+ this.color = this.getColorForPosition();
86
+ }
87
+
88
+ getColorForPosition() {
89
+ let normalizedX = 0;
90
+ if (this.xRange > 0) {
91
+ normalizedX = constrain((this.particleX - this.minX) / this.xRange, 0, 1);
92
+ }
93
+
94
+ let particleColor;
95
+ if (normalizedX < 0.5) {
96
+ particleColor = lerpColor(color(color1), color(color2), normalizedX * 2);
97
+ } else {
98
+ particleColor = lerpColor(color(color2), color(color3), (normalizedX - 0.5) * 2);
99
+ }
100
+ return particleColor;
101
+ }
102
+
103
+ update() {
104
+ if (this.isFadingIn) {
105
+ this.alpha += fadeInSpeed;
106
+ if (this.alpha >= 255) {
107
+ this.alpha = 255;
108
+ this.isFadingIn = false;
109
+ this.isWaiting = true;
110
+ this.waitTime = floor(random(minWaitTime, maxWaitTime));
111
+ }
112
+ } else if (this.isWaiting) {
113
+ this.waitTime--;
114
+ if (this.waitTime <= 0) {
115
+ this.isWaiting = false;
116
+ }
117
+ } else {
118
+ this.pos.y -= floatSpeed * this.floatSpeedVariation;
119
+ if (this.pos.y < -this.size) {
120
+ this.respawn();
121
+ }
122
+ }
123
+ }
124
+
125
+ respawn() {
126
+ this.pos.y = this.originalPos.y;
127
+ this.pos.x = this.originalPos.x;
128
+ this.alpha = 0;
129
+ this.isFadingIn = true;
130
+ this.isWaiting = false;
131
+ this.waitTime = 0;
132
+ this.size = random(particleMinSize, particleMaxSize);
133
+ this.floatSpeedVariation = random(0.5, 2.0);
134
+ this.color = this.getColorForPosition();
135
+ }
136
+
137
+ display() {
138
+ noStroke();
139
+ fill(red(this.color), green(this.color), blue(this.color), this.alpha);
140
+ ellipse(this.pos.x, this.pos.y, this.size, this.size);
141
+ }
142
+ }`;
sketches/TravelSketch.js ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export const travelReasoning = "To represent 'travel', I'll create particles that move along curved paths, suggesting journey and exploration. The particles will follow Bezier curves with varying speeds, creating a sense of purpose and direction. Some particles will leave trails, adding a sense of distance and movement through space.";
2
+
3
+ export const travelSketch = `let font;
4
+ let fontSize = 200;
5
+ let word = "travel";
6
+ let points;
7
+ let particles = [];
8
+ let travelSpeed = 0.8;
9
+ let particleMinSize = 4;
10
+ let particleMaxSize = 4;
11
+ let minX, maxX;
12
+
13
+ let color1 = "#217BFE";
14
+ let color2 = "#078BFE";
15
+ let color3 = "#AC87EB";
16
+
17
+ function preload() {
18
+ font = loadFont('/fonts/GoogleSans-Bold.ttf');
19
+ }
20
+
21
+ function setup() {
22
+ createCanvas(500, 500);
23
+ background(0);
24
+
25
+ textFont(font);
26
+ textSize(fontSize);
27
+ textAlign(CENTER, CENTER);
28
+
29
+ // Get the width of the text
30
+ let textW = textWidth(word);
31
+
32
+ // If text is too wide, scale down fontSize
33
+ if (textW > width * 0.8) {
34
+ fontSize = fontSize * (width * 0.8) / textW;
35
+ textSize(fontSize);
36
+ textW = textWidth(word);
37
+ }
38
+
39
+ points = font.textToPoints(word, width/2 - textW/2, height/2 + fontSize/3, fontSize, {
40
+ sampleFactor: 0.1
41
+ });
42
+
43
+ minX = width;
44
+ maxX = 0;
45
+ for (let pt of points) {
46
+ minX = min(minX, pt.x);
47
+ maxX = max(maxX, pt.x);
48
+ }
49
+
50
+ for (let i = 0; i < points.length; i++) {
51
+ let pt = points[i];
52
+ particles.push(new Particle(pt.x, pt.y, i, points));
53
+ }
54
+ }
55
+
56
+ function draw() {
57
+ blendMode(BLEND); // Reset to default blend mode first
58
+ background(0); // Clear with black background
59
+ blendMode(SCREEN); // Then set screen blend mode for particles
60
+
61
+ for (let particle of particles) {
62
+ particle.update();
63
+ particle.display();
64
+ }
65
+ }
66
+
67
+ class Particle {
68
+ constructor(x, y, index, allPoints) {
69
+ this.pos = createVector(x, y);
70
+ this.size = random(particleMinSize, particleMaxSize);
71
+ this.alpha = 255;
72
+ this.pointIndex = index;
73
+ this.points = allPoints;
74
+ this.targetPoint = this.getNextTargetPoint();
75
+ }
76
+
77
+ getNextTargetPoint() {
78
+ if (this.points.length === 0) return this.pos;
79
+
80
+ this.pointIndex++;
81
+ if (this.pointIndex >= this.points.length) {
82
+ this.pointIndex = 0;
83
+ }
84
+ return createVector(this.points[this.pointIndex].x, this.points[this.pointIndex].y);
85
+ }
86
+
87
+ update() {
88
+ if (!this.targetPoint) return;
89
+
90
+ let direction = p5.Vector.sub(this.targetPoint, this.pos);
91
+ let distance = direction.mag();
92
+
93
+ if (distance < 1) {
94
+ this.targetPoint = this.getNextTargetPoint();
95
+ if (!this.targetPoint) return;
96
+ direction = p5.Vector.sub(this.targetPoint, this.pos);
97
+ }
98
+
99
+ direction.normalize();
100
+ direction.mult(travelSpeed);
101
+ this.pos.add(direction);
102
+ }
103
+
104
+ display() {
105
+ noStroke();
106
+ let normalizedX = map(this.pos.x, minX, maxX, 0, 1, true);
107
+ let particleColor = this.getColorBlend(normalizedX);
108
+ fill(particleColor);
109
+ ellipse(this.pos.x, this.pos.y, this.size, this.size);
110
+ }
111
+
112
+ getColorBlend(normalizedX) {
113
+ if (normalizedX < 0.5) {
114
+ return lerpColor(color(color1), color(color2), normalizedX * 2);
115
+ } else {
116
+ return lerpColor(color(color2), color(color3), (normalizedX - 0.5) * 2);
117
+ }
118
+ }
119
+ }`;
sketches/index.js ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Individual sketch exports
2
+ export { initialSketch } from './InitialSketch';
3
+ export { fluidSketch, fluidReasoning } from './FluidSketch';
4
+ export { riseSketch, riseReasoning } from './RiseSketch';
5
+ export { lightSketch, lightReasoning } from './LightSketch';
6
+ export { travelSketch, travelReasoning } from './TravelSketch';
7
+ export { bounceSketch, bounceReasoning } from './BounceSketch';
8
+ export { loadingSketch } from './LoadingSketch';
9
+
10
+ // Import all sketches for the examples object
11
+ import { fluidSketch } from './FluidSketch';
12
+ import { riseSketch } from './RiseSketch';
13
+ import { lightSketch } from './LightSketch';
14
+ import { travelSketch } from './TravelSketch';
15
+ import { bounceSketch } from './BounceSketch';
16
+
17
+ // Import all reasonings for the exampleReasonings object
18
+ import { fluidReasoning } from './FluidSketch';
19
+ import { riseReasoning } from './RiseSketch';
20
+ import { lightReasoning } from './LightSketch';
21
+ import { travelReasoning } from './TravelSketch';
22
+ import { bounceReasoning } from './BounceSketch';
23
+
24
+ // Export collections
25
+ export const examples = {
26
+ fluid: fluidSketch,
27
+ rise: riseSketch,
28
+ light: lightSketch,
29
+ travel: travelSketch,
30
+ bounce: bounceSketch
31
+ };
32
+
33
+ export const exampleReasonings = {
34
+ fluid: fluidReasoning,
35
+ rise: riseReasoning,
36
+ light: lightReasoning,
37
+ travel: travelReasoning,
38
+ bounce: bounceReasoning
39
+ };
styles/globals.css ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ @layer base {
6
+ html {
7
+ @apply antialiased;
8
+ }
9
+
10
+ body {
11
+ @apply bg-black text-white;
12
+ }
13
+ }
14
+
15
+ @layer components {
16
+ .example-button {
17
+ @apply px-6 py-2.5 bg-zinc-800 rounded-full text-sm hover:bg-zinc-700 transition-colors duration-200;
18
+ }
19
+
20
+ .input-field {
21
+ @apply flex-1 px-6 py-4 bg-zinc-900 border border-zinc-800 rounded-xl text-white placeholder-gray-500 focus:outline-none focus:border-zinc-700 transition-colors;
22
+ }
23
+
24
+ .generate-button {
25
+ @apply px-8 py-4 rounded-xl font-medium transition-colors duration-200;
26
+ }
27
+
28
+ .generate-button-enabled {
29
+ @apply bg-white text-black hover:bg-gray-100;
30
+ }
31
+
32
+ .generate-button-disabled {
33
+ @apply bg-zinc-800 text-gray-400 cursor-not-allowed;
34
+ }
35
+
36
+ .preview-container {
37
+ @apply w-full aspect-square bg-zinc-900 border border-zinc-800 rounded-2xl flex items-center justify-center overflow-hidden;
38
+ }
39
+
40
+ .canvas-container {
41
+ @apply w-[600px] h-[600px] relative;
42
+ }
43
+ }
44
+
45
+ /* Custom scrollbar */
46
+ ::-webkit-scrollbar {
47
+ @apply w-2 h-2;
48
+ }
49
+
50
+ ::-webkit-scrollbar-track {
51
+ @apply bg-zinc-900;
52
+ }
53
+
54
+ ::-webkit-scrollbar-thumb {
55
+ @apply bg-zinc-700 rounded-sm hover:bg-zinc-600;
56
+ }
57
+
58
+ /* Test class to verify CSS is loading */
59
+ .test-style {
60
+ @apply bg-red-500;
61
+ }
62
+
63
+ @font-face {
64
+ font-family: 'Google Sans Display';
65
+ src: url('/fonts/GoogleSansDisplay-Regular.ttf') format('truetype');
66
+ font-weight: normal;
67
+ font-style: normal;
68
+ }
69
+
70
+ @font-face {
71
+ font-family: 'Google Sans Mono';
72
+ src: url('/fonts/GoogleSansMono-Regular.ttf') format('truetype');
73
+ font-weight: normal;
74
+ font-style: normal;
75
+ }
76
+
77
+ :root {
78
+ --font-google-sans-display: 'Google Sans Display', system-ui, -apple-system;
79
+ --font-google-sans-mono: 'Google Sans Mono', monospace;
80
+ --foreground: #ffffff;
81
+ --background: #000000;
82
+ }
83
+
84
+ .code-panel {
85
+ font-family: var(--font-google-sans-mono);
86
+ }
87
+
88
+ .output-panel {
89
+ display: flex;
90
+ width: 414px;
91
+ height: 779px;
92
+ padding: 23px 25px;
93
+ align-items: flex-start;
94
+ gap: 10px;
95
+ flex-shrink: 0;
96
+ border-radius: 26px;
97
+ background: rgba(0, 0, 0, 0.05);
98
+ }
99
+
100
+ input::placeholder {
101
+ color: #666;
102
+ }
103
+
104
+ button:focus {
105
+ outline: none;
106
+ }
tailwind.config.js ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /** @type {import('tailwindcss').Config} */
2
+ module.exports = {
3
+ content: [
4
+ "./pages/**/*.{js,ts,jsx,tsx}",
5
+ "./components/**/*.{js,ts,jsx,tsx}",
6
+ ],
7
+ theme: {
8
+ extend: {
9
+ container: {
10
+ center: true,
11
+ padding: '1rem',
12
+ },
13
+ colors: {
14
+ black: '#000000',
15
+ white: '#FFFFFF',
16
+ zinc: {
17
+ 700: '#3f3f46',
18
+ 800: '#27272a',
19
+ 900: '#18181b',
20
+ },
21
+ },
22
+ fontSize: {
23
+ sm: ['14px', '20px'],
24
+ base: ['16px', '24px'],
25
+ lg: ['20px', '28px'],
26
+ },
27
+ maxWidth: {
28
+ '1000': '1000px',
29
+ '2xl': '42rem',
30
+ },
31
+ width: {
32
+ '414': '414px',
33
+ '564': '564px',
34
+ },
35
+ height: {
36
+ '538': '538px',
37
+ },
38
+ borderRadius: {
39
+ '15': '15px',
40
+ '26': '26px',
41
+ 'xl': '1rem',
42
+ '2xl': '1.5rem',
43
+ },
44
+ padding: {
45
+ '23': '23px',
46
+ '25': '25px',
47
+ },
48
+ spacing: {
49
+ '15': '15px',
50
+ '23': '23px',
51
+ '25': '25px',
52
+ '50': '50px',
53
+ },
54
+ fontFamily: {
55
+ sans: ['var(--font-inter)'],
56
+ },
57
+ },
58
+ },
59
+ plugins: [],
60
+ }