Spaces:
Sleeping
Sleeping
CreatorKit Claude Opus 4.8 commited on
Commit ·
8661b79
0
Parent(s):
Initial commit: CreatorKit — plataforma para criadores
Browse filesPlataforma local com 7 ferramentas:
- Estudio de Video (transcricao Whisper -> 9 saidas de conteudo)
- Gerador de Hooks, Ideias, Roteiro, Hashtags, Bio e Calendario
Stack: Node.js + Express, Whisper (@xenova /transformers), yt-dlp, ffmpeg.
Pronto para producao: Dockerfile, helmet, compression, graceful
shutdown, health check, limpeza automatica de jobs e PORT via env.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- .claude/launch.json +11 -0
- .dockerignore +11 -0
- .gitignore +20 -0
- Dockerfile +28 -0
- README.md +65 -0
- analyze.js +478 -0
- package-lock.json +2047 -0
- package.json +26 -0
- server.js +293 -0
- start.bat +22 -0
- templates/index.html +955 -0
- whisper_worker.js +69 -0
.claude/launch.json
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"version": "0.0.1",
|
| 3 |
+
"configurations": [
|
| 4 |
+
{
|
| 5 |
+
"name": "reel-transcriber",
|
| 6 |
+
"runtimeExecutable": "npm",
|
| 7 |
+
"runtimeArgs": ["start", "--prefix", "D:\\Claudio\\reel-transcriber"],
|
| 8 |
+
"port": 5050
|
| 9 |
+
}
|
| 10 |
+
]
|
| 11 |
+
}
|
.dockerignore
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
node_modules
|
| 2 |
+
npm-debug.log
|
| 3 |
+
.git
|
| 4 |
+
.gitignore
|
| 5 |
+
downloads
|
| 6 |
+
uploads
|
| 7 |
+
bin
|
| 8 |
+
.cache
|
| 9 |
+
*.md
|
| 10 |
+
.env
|
| 11 |
+
.claude
|
.gitignore
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# dependencies
|
| 2 |
+
node_modules/
|
| 3 |
+
|
| 4 |
+
# runtime / temp
|
| 5 |
+
downloads/
|
| 6 |
+
uploads/
|
| 7 |
+
bin/
|
| 8 |
+
.cache/
|
| 9 |
+
|
| 10 |
+
# env
|
| 11 |
+
.env
|
| 12 |
+
.env.local
|
| 13 |
+
|
| 14 |
+
# logs
|
| 15 |
+
*.log
|
| 16 |
+
npm-debug.log*
|
| 17 |
+
|
| 18 |
+
# os
|
| 19 |
+
.DS_Store
|
| 20 |
+
Thumbs.db
|
Dockerfile
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# CreatorKit — imagem de produção
|
| 2 |
+
# Debian slim (glibc) porque o onnxruntime do Whisper não roda bem em Alpine/musl.
|
| 3 |
+
FROM node:20-slim
|
| 4 |
+
|
| 5 |
+
# Dependências de sistema: ffmpeg (merge do yt-dlp) + python3 + yt-dlp standalone
|
| 6 |
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
| 7 |
+
python3 ffmpeg ca-certificates curl \
|
| 8 |
+
&& curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp \
|
| 9 |
+
-o /usr/local/bin/yt-dlp \
|
| 10 |
+
&& chmod a+rx /usr/local/bin/yt-dlp \
|
| 11 |
+
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
| 12 |
+
|
| 13 |
+
WORKDIR /app
|
| 14 |
+
|
| 15 |
+
# Instala dependências (camada cacheável)
|
| 16 |
+
COPY package*.json ./
|
| 17 |
+
RUN npm install --omit=dev && npm cache clean --force
|
| 18 |
+
|
| 19 |
+
# Copia o restante do código
|
| 20 |
+
COPY . .
|
| 21 |
+
|
| 22 |
+
ENV NODE_ENV=production
|
| 23 |
+
ENV YTDLP_PATH=/usr/local/bin/yt-dlp
|
| 24 |
+
# Cache dos modelos Whisper dentro do app
|
| 25 |
+
ENV XENOVA_CACHE_DIR=/app/.cache
|
| 26 |
+
|
| 27 |
+
EXPOSE 5050
|
| 28 |
+
CMD ["node", "server.js"]
|
README.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# ✦ CreatorKit
|
| 2 |
+
|
| 3 |
+
Plataforma local para criadores de conteúdo. Transcreve vídeos e gera caption, thread, post de blog, hooks, ideias, hashtags, bio, roteiro e calendário — tudo processado na própria máquina/servidor, sem API externa.
|
| 4 |
+
|
| 5 |
+
## 🧰 Ferramentas
|
| 6 |
+
|
| 7 |
+
| Ferramenta | Precisa de vídeo? |
|
| 8 |
+
|---|---|
|
| 9 |
+
| 🎬 Estúdio de Vídeo (transcrição → 9 saídas) | Sim |
|
| 10 |
+
| 🪝 Gerador de Hooks | Não |
|
| 11 |
+
| 💡 Ideias de Conteúdo | Não |
|
| 12 |
+
| 📝 Roteiro de Vídeo | Não |
|
| 13 |
+
| #️⃣ Hashtags por Tema | Não |
|
| 14 |
+
| ✍️ Bio de Perfil | Não |
|
| 15 |
+
| 📅 Calendário de Posts | Não |
|
| 16 |
+
|
| 17 |
+
## 🚀 Rodar localmente
|
| 18 |
+
|
| 19 |
+
Requisitos: **Node.js 18+**.
|
| 20 |
+
|
| 21 |
+
```bash
|
| 22 |
+
npm install
|
| 23 |
+
npm start
|
| 24 |
+
```
|
| 25 |
+
|
| 26 |
+
Acesse http://localhost:5050
|
| 27 |
+
|
| 28 |
+
O `yt-dlp` é baixado automaticamente na primeira execução. O `ffmpeg` já vem embutido via `ffmpeg-static`. O modelo Whisper (~250 MB no `small`) é baixado na primeira transcrição e fica em cache.
|
| 29 |
+
|
| 30 |
+
## 🐳 Deploy com Docker
|
| 31 |
+
|
| 32 |
+
```bash
|
| 33 |
+
docker build -t creatorkit .
|
| 34 |
+
docker run -p 5050:5050 creatorkit
|
| 35 |
+
```
|
| 36 |
+
|
| 37 |
+
A imagem já inclui `ffmpeg`, `python3` e `yt-dlp`.
|
| 38 |
+
|
| 39 |
+
## ☁️ Deploy em Render / Railway / Fly.io
|
| 40 |
+
|
| 41 |
+
O projeto está pronto para qualquer plataforma que rode Docker:
|
| 42 |
+
|
| 43 |
+
1. Suba o repositório no GitHub.
|
| 44 |
+
2. Crie um serviço apontando para o repo (deixe a plataforma detectar o `Dockerfile`).
|
| 45 |
+
3. A porta é lida de `process.env.PORT` automaticamente.
|
| 46 |
+
4. Health check disponível em `/health`.
|
| 47 |
+
|
| 48 |
+
### Variáveis de ambiente (opcionais)
|
| 49 |
+
|
| 50 |
+
| Variável | Padrão | Descrição |
|
| 51 |
+
|---|---|---|
|
| 52 |
+
| `PORT` | `5050` | Porta do servidor |
|
| 53 |
+
| `YTDLP_PATH` | `/usr/local/bin/yt-dlp` (Docker) | Caminho do binário yt-dlp |
|
| 54 |
+
| `XENOVA_CACHE_DIR` | `/app/.cache` | Cache dos modelos Whisper |
|
| 55 |
+
|
| 56 |
+
## ⚠️ Considerações de produção
|
| 57 |
+
|
| 58 |
+
- **Whisper é pesado de CPU.** Em instâncias pequenas (512 MB–1 GB), use os modelos `tiny` ou `base`. O `medium`/`large` exigem servidores com mais memória/CPU.
|
| 59 |
+
- **Downloads de Instagram/YouTube** podem ser bloqueados a partir de IPs de datacenter. Funciona melhor em IP residencial; em nuvem pode exigir cookies/login.
|
| 60 |
+
- O processamento é **single-instance** (jobs ficam em memória). Para escalar horizontalmente, seria necessário uma fila externa (ex.: Redis).
|
| 61 |
+
- Arquivos temporários e jobs antigos são limpos automaticamente a cada 15 min (TTL de 1 h).
|
| 62 |
+
|
| 63 |
+
## 📄 Licença
|
| 64 |
+
|
| 65 |
+
ISC
|
analyze.js
ADDED
|
@@ -0,0 +1,478 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* analyze.js — content generation engine for CreatorKit
|
| 3 |
+
* All processing is local — no external API needed.
|
| 4 |
+
*/
|
| 5 |
+
|
| 6 |
+
// ── Stop words (PT + EN) ──────────────────────────────────────
|
| 7 |
+
const STOP_WORDS = new Set([
|
| 8 |
+
// PT
|
| 9 |
+
'a','ao','aos','aquela','aquelas','aquele','aqueles','aquilo','as','até','com',
|
| 10 |
+
'como','da','das','de','dela','delas','dele','deles','depois','do','dos','e',
|
| 11 |
+
'ela','elas','ele','eles','em','entre','era','eram','essa','essas','esse',
|
| 12 |
+
'esses','esta','estas','este','estes','eu','foi','for','foram','há','isso',
|
| 13 |
+
'isto','já','lhe','lhes','mais','mas','me','mesmo','meu','minha','muito',
|
| 14 |
+
'na','nas','nem','no','nos','nós','não','num','numa','o','os','ou','para',
|
| 15 |
+
'pela','pelas','pelo','pelos','por','que','qual','quando','quem','são','se',
|
| 16 |
+
'sem','ser','seu','seus','si','sua','suas','também','te','tem','ter','teu',
|
| 17 |
+
'tua','tuas','tudo','um','uma','uns','umas','vai','vem','você','vocês','à',
|
| 18 |
+
'às','é','isso','assim','então','agora','aqui','ali','lá','ainda','logo',
|
| 19 |
+
'porque','então','pois','portanto','todavia','porém','entanto','contudo',
|
| 20 |
+
'apenas','só','todo','toda','todos','todas','cada','outro','outra','outros',
|
| 21 |
+
'outras','tal','tais','tanto','tantos','tanta','tantas','bem','mal','muito',
|
| 22 |
+
'pouco','sempre','nunca','jamais','hoje','ontem','amanhã','quando','onde',
|
| 23 |
+
// EN
|
| 24 |
+
'a','an','the','and','or','but','in','on','at','to','for','of','with',
|
| 25 |
+
'as','is','was','are','were','be','been','being','have','has','had',
|
| 26 |
+
'do','does','did','will','would','could','should','may','might','shall',
|
| 27 |
+
'can','this','that','these','those','i','we','you','he','she','they','it',
|
| 28 |
+
'my','our','your','his','her','their','its','me','us','him','them','who',
|
| 29 |
+
'what','which','how','when','where','why','all','any','both','each',
|
| 30 |
+
'few','more','most','other','some','such','no','not','only','same','so',
|
| 31 |
+
'than','too','very','just','about','above','after','again','also','before',
|
| 32 |
+
'between','here','into','like','now','out','over','own','then','there',
|
| 33 |
+
'through','under','until','up','while','from','if',
|
| 34 |
+
]);
|
| 35 |
+
|
| 36 |
+
// ── Tokenize & extract keywords ───────────────────────────────
|
| 37 |
+
function tokenize(text) {
|
| 38 |
+
return text
|
| 39 |
+
.toLowerCase()
|
| 40 |
+
.replace(/[^a-záàãâäéèêëíìîïóòõôöúùûüçñ\s]/gi, ' ')
|
| 41 |
+
.split(/\s+/)
|
| 42 |
+
.filter(w => w.length > 3 && !STOP_WORDS.has(w));
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
function extractKeywords(text, topN = 20) {
|
| 46 |
+
const words = tokenize(text);
|
| 47 |
+
const freq = {};
|
| 48 |
+
for (const w of words) freq[w] = (freq[w] || 0) + 1;
|
| 49 |
+
return Object.entries(freq)
|
| 50 |
+
.sort((a, b) => b[1] - a[1])
|
| 51 |
+
.slice(0, topN)
|
| 52 |
+
.map(([word, count]) => ({ word, count }));
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
// ── Extractive summary ────────────────────────────────────────
|
| 56 |
+
function summarize(text, numSentences = 4) {
|
| 57 |
+
const sentences = text.match(/[^.!?]+[.!?]+/g) || [text];
|
| 58 |
+
if (sentences.length <= numSentences) return text.trim();
|
| 59 |
+
|
| 60 |
+
const keywords = new Set(extractKeywords(text, 15).map(k => k.word));
|
| 61 |
+
|
| 62 |
+
const scored = sentences.map(s => {
|
| 63 |
+
const words = tokenize(s);
|
| 64 |
+
const score = words.filter(w => keywords.has(w)).length / (words.length || 1);
|
| 65 |
+
return { s: s.trim(), score };
|
| 66 |
+
});
|
| 67 |
+
|
| 68 |
+
return scored
|
| 69 |
+
.sort((a, b) => b.score - a.score)
|
| 70 |
+
.slice(0, numSentences)
|
| 71 |
+
.sort((a, b) => sentences.indexOf(a.s) - sentences.indexOf(b.s))
|
| 72 |
+
.map(x => x.s)
|
| 73 |
+
.join(' ');
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
// ── Hashtag generator ─────────────────────────────────────────
|
| 77 |
+
function generateHashtags(text, keywords) {
|
| 78 |
+
const tags = keywords
|
| 79 |
+
.slice(0, 12)
|
| 80 |
+
.map(k => '#' + k.word.replace(/\s+/g, '').normalize('NFD').replace(/[̀-ͯ]/g, ''));
|
| 81 |
+
|
| 82 |
+
// Detect topics and add contextual tags
|
| 83 |
+
const lower = text.toLowerCase();
|
| 84 |
+
const contextual = [];
|
| 85 |
+
if (/negócio|empresa|empreend|startup|produto|vend/.test(lower)) contextual.push('#empreendedorismo','#negócios','#business');
|
| 86 |
+
if (/saúde|treino|exercício|academia|fitness|dieta/.test(lower)) contextual.push('#saúde','#fitness','#bemestar');
|
| 87 |
+
if (/tecnologia|tech|software|programação|código|ia|inteligência/.test(lower)) contextual.push('#tecnologia','#tech','#inovação');
|
| 88 |
+
if (/motivação|sucesso|crescimento|mindset|foco/.test(lower)) contextual.push('#motivação','#sucesso','#mindset');
|
| 89 |
+
if (/receita|cozinha|comida|culinária|alimento/.test(lower)) contextual.push('#gastronomia','#culinária','#foodlover');
|
| 90 |
+
if (/moda|roupa|estilo|fashion|look/.test(lower)) contextual.push('#moda','#fashion','#estilo');
|
| 91 |
+
if (/viagem|destino|turismo|lugar|cidade/.test(lower)) contextual.push('#viagem','#turismo','#travel');
|
| 92 |
+
if (/financ|invest|dinheiro|renda|rico/.test(lower)) contextual.push('#finanças','#investimento','#dinheiro');
|
| 93 |
+
if (/relacionamento|amor|família|casal|vida/.test(lower)) contextual.push('#relacionamentos','#vidapessoal');
|
| 94 |
+
|
| 95 |
+
const all = [...new Set([...tags, ...contextual, '#conteúdo', '#influencer', '#viral'])];
|
| 96 |
+
return all.slice(0, 25);
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
// ── Instagram Caption ─────────────────────────────────────────
|
| 100 |
+
function generateInstagramCaption(text, keywords, hashtags, lang) {
|
| 101 |
+
const summary = summarize(text, 2);
|
| 102 |
+
const sentences = text.match(/[^.!?]+[.!?]+/g) || [text];
|
| 103 |
+
const hook = sentences[0]?.trim() || summary.split('.')[0];
|
| 104 |
+
const kws = keywords.slice(0, 3).map(k => k.word);
|
| 105 |
+
|
| 106 |
+
const ctas = [
|
| 107 |
+
'💬 Me conta o que você achou nos comentários!',
|
| 108 |
+
'👇 Qual foi o ponto que mais te chamou atenção?',
|
| 109 |
+
'🔁 Salva esse conteúdo para não perder!',
|
| 110 |
+
'📲 Manda pra um amigo que precisa ver isso!',
|
| 111 |
+
'✨ Segue para mais conteúdo como esse!',
|
| 112 |
+
];
|
| 113 |
+
const cta = ctas[Math.floor(Math.random() * ctas.length)];
|
| 114 |
+
|
| 115 |
+
const topHashtags = hashtags.slice(0, 15).join(' ');
|
| 116 |
+
|
| 117 |
+
return `${hook}
|
| 118 |
+
|
| 119 |
+
✨ Neste conteúdo você vai ver:
|
| 120 |
+
${kws.map(k => `▸ ${k.charAt(0).toUpperCase() + k.slice(1)}`).join('\n')}
|
| 121 |
+
|
| 122 |
+
${summary}
|
| 123 |
+
|
| 124 |
+
${cta}
|
| 125 |
+
|
| 126 |
+
.
|
| 127 |
+
.
|
| 128 |
+
.
|
| 129 |
+
${topHashtags}`;
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
// ── YouTube Kit ───────────────────────────────────────────────
|
| 133 |
+
function generateYouTubeKit(text, keywords, segments) {
|
| 134 |
+
const kws = keywords.slice(0, 5).map(k => k.word);
|
| 135 |
+
|
| 136 |
+
// Title variations
|
| 137 |
+
const firstSentence = (text.match(/[^.!?]+[.!?]+/)?.[0] || '').trim().slice(0, 60);
|
| 138 |
+
const titles = [
|
| 139 |
+
`${firstSentence || kws.slice(0,2).join(' e ')} | Conteúdo Completo`,
|
| 140 |
+
`TUDO sobre ${kws[0] || 'esse tema'} que você precisa saber`,
|
| 141 |
+
`${kws.slice(0,2).join(', ')} e muito mais — Veja agora!`,
|
| 142 |
+
];
|
| 143 |
+
|
| 144 |
+
// Description
|
| 145 |
+
const summary = summarize(text, 3);
|
| 146 |
+
const tags = keywords.slice(0, 15).map(k => k.word).join(', ');
|
| 147 |
+
|
| 148 |
+
// Timestamps from segments
|
| 149 |
+
let timestampBlock = '';
|
| 150 |
+
if (segments && segments.length > 0) {
|
| 151 |
+
const interval = Math.max(1, Math.floor(segments.length / 8));
|
| 152 |
+
const picks = segments.filter((_, i) => i % interval === 0).slice(0, 8);
|
| 153 |
+
timestampBlock = '\n\n⏱️ CAPÍTULOS:\n' + picks.map(s => `${fmtTime(s.start)} ${s.text.slice(0, 50)}`).join('\n');
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
+
const description = `📌 ${summary}
|
| 157 |
+
${timestampBlock}
|
| 158 |
+
|
| 159 |
+
🔔 Inscreva-se no canal e ative o sininho para não perder nenhum vídeo!
|
| 160 |
+
👍 Se o conteúdo foi útil, deixa o like — ajuda muito!
|
| 161 |
+
💬 Tem alguma dúvida? Comenta aqui embaixo!
|
| 162 |
+
|
| 163 |
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
| 164 |
+
🔗 Minhas redes sociais:
|
| 165 |
+
▸ Instagram: @seuinstagram
|
| 166 |
+
▸ TikTok: @seutiktok
|
| 167 |
+
▸ Twitter: @seutwitter
|
| 168 |
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
| 169 |
+
|
| 170 |
+
#${kws.join(' #')}`;
|
| 171 |
+
|
| 172 |
+
return { titles, description, tags };
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
// ── Twitter/X Thread ──────────────────────────────────────────
|
| 176 |
+
function generateTwitterThread(text, keywords) {
|
| 177 |
+
const sentences = (text.match(/[^.!?]+[.!?]+/g) || [text]).map(s => s.trim()).filter(Boolean);
|
| 178 |
+
const summary = summarize(text, 6);
|
| 179 |
+
const sumSentences = (summary.match(/[^.!?]+[.!?]+/g) || [summary]).map(s => s.trim()).filter(Boolean);
|
| 180 |
+
|
| 181 |
+
const tweets = [];
|
| 182 |
+
const kws = keywords.slice(0, 3).map(k => k.word);
|
| 183 |
+
|
| 184 |
+
// Tweet 1: hook
|
| 185 |
+
tweets.push(`🧵 ${sentences[0] || kws.join(', ')}\n\nThread completa 👇`);
|
| 186 |
+
|
| 187 |
+
// Middle tweets: pack sentences into 250 chars each
|
| 188 |
+
let current = '';
|
| 189 |
+
for (const s of sumSentences) {
|
| 190 |
+
if ((current + ' ' + s).length > 250) {
|
| 191 |
+
if (current) tweets.push(current.trim());
|
| 192 |
+
current = s;
|
| 193 |
+
} else {
|
| 194 |
+
current = current ? current + ' ' + s : s;
|
| 195 |
+
}
|
| 196 |
+
}
|
| 197 |
+
if (current) tweets.push(current.trim());
|
| 198 |
+
|
| 199 |
+
// Last tweet: CTA
|
| 200 |
+
tweets.push(`📌 Gostou desse conteúdo?\n\n↩️ RT para compartilhar\n❤️ Like se foi útil\n🔔 Siga para mais\n\n#${kws.slice(0,3).join(' #')}`);
|
| 201 |
+
|
| 202 |
+
return tweets.map((t, i) => `${i + 1}/${tweets.length}\n\n${t}`);
|
| 203 |
+
}
|
| 204 |
+
|
| 205 |
+
// ── LinkedIn Post ─────────────────────────────────────────────
|
| 206 |
+
function generateLinkedIn(text, keywords) {
|
| 207 |
+
const sentences = (text.match(/[^.!?]+[.!?]+/g) || [text]).map(s => s.trim());
|
| 208 |
+
const kws = keywords.slice(0, 5);
|
| 209 |
+
const summary = summarize(text, 4);
|
| 210 |
+
|
| 211 |
+
return `💡 ${sentences[0] || 'Reflexão importante'}
|
| 212 |
+
|
| 213 |
+
${summary}
|
| 214 |
+
|
| 215 |
+
3 pontos principais sobre ${kws[0]?.word || 'esse tema'}:
|
| 216 |
+
|
| 217 |
+
→ ${sentences[1]?.trim() || kws[0]?.word || ''}
|
| 218 |
+
→ ${sentences[2]?.trim() || kws[1]?.word || ''}
|
| 219 |
+
→ ${sentences[3]?.trim() || kws[2]?.word || ''}
|
| 220 |
+
|
| 221 |
+
O que você pensa sobre isso? Compartilhe nos comentários. 👇
|
| 222 |
+
|
| 223 |
+
━━━━━━━━━━━━━━━━━━━━━
|
| 224 |
+
|
| 225 |
+
${kws.slice(0, 5).map(k => `#${k.word}`).join(' ')} #linkedin #networking #conteúdo`;
|
| 226 |
+
}
|
| 227 |
+
|
| 228 |
+
// ── Blog Post ─────────────────────────────────────────────────
|
| 229 |
+
function generateBlogPost(text, keywords, title) {
|
| 230 |
+
const sentences = (text.match(/[^.!?]+[.!?]+/g) || [text]).map(s => s.trim()).filter(Boolean);
|
| 231 |
+
const kws = keywords.slice(0, 6).map(k => k.word);
|
| 232 |
+
const postTitle = title || `${kws[0]?.charAt(0).toUpperCase() + kws[0]?.slice(1) || 'Conteúdo'}: tudo o que você precisa saber`;
|
| 233 |
+
|
| 234 |
+
// Split into chunks of ~3 sentences per section
|
| 235 |
+
const sections = [];
|
| 236 |
+
let chunk = [];
|
| 237 |
+
for (const s of sentences) {
|
| 238 |
+
chunk.push(s);
|
| 239 |
+
if (chunk.length === 3) { sections.push(chunk.join(' ')); chunk = []; }
|
| 240 |
+
}
|
| 241 |
+
if (chunk.length) sections.push(chunk.join(' '));
|
| 242 |
+
|
| 243 |
+
const sectionTitles = [
|
| 244 |
+
'Introdução', 'Por que isso importa', 'Principais pontos',
|
| 245 |
+
'Como aplicar na prática', 'Dicas e insights', 'Conclusão',
|
| 246 |
+
];
|
| 247 |
+
|
| 248 |
+
let post = `# ${postTitle}\n\n`;
|
| 249 |
+
post += `*Tempo de leitura: ~${Math.ceil(text.split(/\s+/).length / 200)} min*\n\n`;
|
| 250 |
+
post += `---\n\n`;
|
| 251 |
+
|
| 252 |
+
sections.slice(0, 5).forEach((section, i) => {
|
| 253 |
+
post += `## ${sectionTitles[i] || `Parte ${i + 1}`}\n\n${section}\n\n`;
|
| 254 |
+
});
|
| 255 |
+
|
| 256 |
+
post += `## Conclusão\n\n${summarize(text, 2)}\n\n`;
|
| 257 |
+
post += `---\n\n**Tags:** ${kws.join(', ')}`;
|
| 258 |
+
|
| 259 |
+
return post;
|
| 260 |
+
}
|
| 261 |
+
|
| 262 |
+
// ── Main analyze function ─────────────────────────────────────
|
| 263 |
+
function analyze(text, segments = [], videoTitle = '') {
|
| 264 |
+
if (!text || text.trim().length < 10) throw new Error('Texto muito curto para análise.');
|
| 265 |
+
|
| 266 |
+
const keywords = extractKeywords(text, 20);
|
| 267 |
+
const hashtags = generateHashtags(text, keywords);
|
| 268 |
+
const summary = summarize(text, 4);
|
| 269 |
+
const instagram = generateInstagramCaption(text, keywords, hashtags);
|
| 270 |
+
const yt = generateYouTubeKit(text, keywords, segments);
|
| 271 |
+
const thread = generateTwitterThread(text, keywords);
|
| 272 |
+
const linkedin = generateLinkedIn(text, keywords);
|
| 273 |
+
const blog = generateBlogPost(text, keywords, videoTitle);
|
| 274 |
+
|
| 275 |
+
const wordCount = text.trim().split(/\s+/).length;
|
| 276 |
+
const readingTime = Math.ceil(wordCount / 200);
|
| 277 |
+
|
| 278 |
+
return {
|
| 279 |
+
summary,
|
| 280 |
+
keywords: keywords.slice(0, 12),
|
| 281 |
+
hashtags,
|
| 282 |
+
instagram,
|
| 283 |
+
youtube: yt,
|
| 284 |
+
twitter: thread,
|
| 285 |
+
linkedin,
|
| 286 |
+
blog,
|
| 287 |
+
stats: { wordCount, readingTime, sentenceCount: (text.match(/[.!?]+/g) || []).length },
|
| 288 |
+
};
|
| 289 |
+
}
|
| 290 |
+
|
| 291 |
+
function fmtTime(s) {
|
| 292 |
+
const m = Math.floor(s / 60), sec = Math.floor(s % 60).toString().padStart(2,'0');
|
| 293 |
+
return `${m}:${sec}`;
|
| 294 |
+
}
|
| 295 |
+
|
| 296 |
+
// ══════════════════════════════════════════════════════════════
|
| 297 |
+
// STANDALONE CREATOR TOOLS (topic-based, no video needed)
|
| 298 |
+
// ══════════════════════════════════════════════════════════════
|
| 299 |
+
|
| 300 |
+
function pick(arr, n) {
|
| 301 |
+
const copy = [...arr];
|
| 302 |
+
const out = [];
|
| 303 |
+
while (out.length < n && copy.length) {
|
| 304 |
+
out.push(copy.splice(Math.floor(Math.random() * copy.length), 1)[0]);
|
| 305 |
+
}
|
| 306 |
+
return out;
|
| 307 |
+
}
|
| 308 |
+
|
| 309 |
+
const cap = s => s ? s.charAt(0).toUpperCase() + s.slice(1) : s;
|
| 310 |
+
|
| 311 |
+
// ── 🪝 HOOKS ──────────────────────────────────────────────────
|
| 312 |
+
function generateHooks(topic) {
|
| 313 |
+
if (!topic || !topic.trim()) throw new Error('Informe um tópico.');
|
| 314 |
+
const t = topic.trim().toLowerCase();
|
| 315 |
+
const T = cap(t);
|
| 316 |
+
|
| 317 |
+
const templates = [
|
| 318 |
+
`Pare de errar em ${t} — faça assim a partir de hoje.`,
|
| 319 |
+
`Ninguém te conta a verdade sobre ${t}...`,
|
| 320 |
+
`Eu perdi anos errando em ${t}. Não cometa o mesmo erro.`,
|
| 321 |
+
`3 verdades sobre ${t} que mudaram tudo pra mim.`,
|
| 322 |
+
`O segredo de ${t} que os experts não compartilham.`,
|
| 323 |
+
`Como eu dominei ${t} em apenas 30 dias.`,
|
| 324 |
+
`A maioria das pessoas erra em ${t}. Veja como acertar.`,
|
| 325 |
+
`${T} não é o que você imagina. Olha só isso.`,
|
| 326 |
+
`Faça ISSO antes de tentar qualquer coisa com ${t}.`,
|
| 327 |
+
`O maior mito sobre ${t} — desmascarado.`,
|
| 328 |
+
`Se você quer resultado com ${t}, assista até o final.`,
|
| 329 |
+
`Eu testei tudo sobre ${t} pra você não precisar.`,
|
| 330 |
+
`Esse erro em ${t} está te custando caro (e você nem percebe).`,
|
| 331 |
+
`${T} em 60 segundos: o guia que você precisava.`,
|
| 332 |
+
`Por que 90% das pessoas falham em ${t}?`,
|
| 333 |
+
`O que eu faria se tivesse que começar do zero em ${t}.`,
|
| 334 |
+
];
|
| 335 |
+
return { topic, hooks: pick(templates, 10) };
|
| 336 |
+
}
|
| 337 |
+
|
| 338 |
+
// ── 💡 CONTENT IDEAS ──────────────────────────────────────────
|
| 339 |
+
function generateIdeas(niche) {
|
| 340 |
+
if (!niche || !niche.trim()) throw new Error('Informe seu nicho.');
|
| 341 |
+
const n = niche.trim().toLowerCase();
|
| 342 |
+
const N = cap(n);
|
| 343 |
+
|
| 344 |
+
const ideas = [
|
| 345 |
+
{ fmt: 'Reels', icon: '🎬', title: `Top 5 erros que iniciantes cometem em ${n}` },
|
| 346 |
+
{ fmt: 'Carrossel', icon: '🖼️', title: `Mitos vs verdades sobre ${n}` },
|
| 347 |
+
{ fmt: 'Reels', icon: '🎬', title: `Um dia na vida de quem trabalha com ${n}` },
|
| 348 |
+
{ fmt: 'YouTube', icon: '▶️', title: `Tutorial passo a passo de ${n} para iniciantes` },
|
| 349 |
+
{ fmt: 'Carrossel', icon: '🖼️', title: `O que eu gostaria de saber antes de começar em ${n}` },
|
| 350 |
+
{ fmt: 'Story', icon: '📲', title: `Caixinha de perguntas: tudo sobre ${n}` },
|
| 351 |
+
{ fmt: 'Reels', icon: '🎬', title: `Antes e depois: minha evolução em ${n}` },
|
| 352 |
+
{ fmt: 'Carrossel', icon: '🖼️', title: `5 ferramentas essenciais para ${n}` },
|
| 353 |
+
{ fmt: 'YouTube', icon: '▶️', title: `Reagindo às maiores tendências de ${n}` },
|
| 354 |
+
{ fmt: 'Reels', icon: '🎬', title: `Desafio de 30 dias de ${n} — resultados reais` },
|
| 355 |
+
{ fmt: 'Carrossel', icon: '🖼️', title: `Guia rápido: ${n} do zero ao avançado` },
|
| 356 |
+
{ fmt: 'Reels', icon: '🎬', title: `3 hábitos que transformaram meu ${n}` },
|
| 357 |
+
{ fmt: 'Story', icon: '📲', title: `Bastidores: como eu produzo conteúdo de ${n}` },
|
| 358 |
+
{ fmt: 'YouTube', icon: '▶️', title: `${N}: vale a pena em 2026? Minha opinião sincera` },
|
| 359 |
+
{ fmt: 'Carrossel', icon: '🖼️', title: `Os 7 termos de ${n} que todo mundo deveria saber` },
|
| 360 |
+
];
|
| 361 |
+
return { niche, ideas: pick(ideas, 9) };
|
| 362 |
+
}
|
| 363 |
+
|
| 364 |
+
// ── ✍️ BIO GENERATOR ──────────────────────────────────────────
|
| 365 |
+
function generateBio({ name = '', niche = '', cta = '' }) {
|
| 366 |
+
if (!niche.trim()) throw new Error('Informe seu nicho.');
|
| 367 |
+
const n = niche.trim();
|
| 368 |
+
const link = cta.trim() || '👇 Link abaixo';
|
| 369 |
+
|
| 370 |
+
const bios = [
|
| 371 |
+
`✨ ${name || 'Criador(a)'} | ${cap(n)}\n📍 Conteúdo diário sobre ${n.toLowerCase()}\n💡 Dicas que realmente funcionam\n${link}`,
|
| 372 |
+
`${cap(n)} descomplicado 🚀\nAjudo você a evoluir em ${n.toLowerCase()}\n🎯 Novo conteúdo toda semana\n${link}`,
|
| 373 |
+
`${name ? name + ' • ' : ''}Apaixonado(a) por ${n.toLowerCase()} 💜\nTransformando conhecimento em resultado\n📲 Me segue pra não perder nada\n${link}`,
|
| 374 |
+
`Seu cantinho de ${n.toLowerCase()} 🌟\n✅ Conteúdo prático e direto\n✅ Sem enrolação\n${link}`,
|
| 375 |
+
];
|
| 376 |
+
return { bios };
|
| 377 |
+
}
|
| 378 |
+
|
| 379 |
+
// ── 📅 CONTENT CALENDAR ───────────────────────────────────────
|
| 380 |
+
function generateCalendar({ niche = '', perWeek = 5 }) {
|
| 381 |
+
if (!niche.trim()) throw new Error('Informe seu nicho.');
|
| 382 |
+
const n = niche.trim().toLowerCase();
|
| 383 |
+
const days = ['Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta', 'Sábado', 'Domingo'];
|
| 384 |
+
const blocks = [
|
| 385 |
+
{ icon: '🎬', fmt: 'Reels', theme: `Dica rápida de ${n}`, best: '12h ou 19h' },
|
| 386 |
+
{ icon: '🖼️', fmt: 'Carrossel', theme: `Passo a passo sobre ${n}`, best: '18h' },
|
| 387 |
+
{ icon: '📲', fmt: 'Story', theme: `Bastidores + enquete de ${n}`, best: 'Ao longo do dia' },
|
| 388 |
+
{ icon: '🎬', fmt: 'Reels', theme: `Mito vs verdade de ${n}`, best: '20h' },
|
| 389 |
+
{ icon: '▶️', fmt: 'YouTube', theme: `Vídeo aprofundado de ${n}`, best: 'Sábado 10h' },
|
| 390 |
+
{ icon: '🖼️', fmt: 'Carrossel', theme: `Lista: top ferramentas de ${n}`, best: '17h' },
|
| 391 |
+
{ icon: '📲', fmt: 'Story', theme: `Caixinha de perguntas de ${n}`, best: 'Domingo' },
|
| 392 |
+
];
|
| 393 |
+
const count = Math.min(Math.max(parseInt(perWeek) || 5, 1), 7);
|
| 394 |
+
const plan = days.slice(0, count).map((d, i) => ({ day: d, ...blocks[i % blocks.length] }));
|
| 395 |
+
return { niche, plan };
|
| 396 |
+
}
|
| 397 |
+
|
| 398 |
+
// ── 📸 CAPTION FROM TOPIC ─────────────────────────────────────
|
| 399 |
+
function generateCaptionFromTopic(topic) {
|
| 400 |
+
if (!topic || !topic.trim()) throw new Error('Informe um tópico.');
|
| 401 |
+
const t = topic.trim();
|
| 402 |
+
const keywords = extractKeywords(t + ' ' + t, 10);
|
| 403 |
+
const hashtags = generateHashtags(t, keywords);
|
| 404 |
+
const ctas = [
|
| 405 |
+
'💬 Comenta aqui o que você achou!',
|
| 406 |
+
'🔁 Salva esse post para não esquecer!',
|
| 407 |
+
'📲 Marca um amigo que precisa ver isso!',
|
| 408 |
+
'✨ Segue pra mais conteúdo como esse!',
|
| 409 |
+
];
|
| 410 |
+
const caption = `${cap(t)} 🚀\n\nVocê sabia disso? Deixa eu te explicar de um jeito simples 👇\n\n▸ Ponto 1 sobre ${t.toLowerCase()}\n▸ Ponto 2 que faz a diferença\n▸ Ponto 3 que ninguém te conta\n\n${pick(ctas, 1)[0]}\n\n.\n.\n.\n${hashtags.slice(0, 15).join(' ')}`;
|
| 411 |
+
return { caption, hashtags };
|
| 412 |
+
}
|
| 413 |
+
|
| 414 |
+
// ── 📝 SCRIPT / ROTEIRO ───────────────────────────────────────
|
| 415 |
+
function generateScript({ topic = '', format = 'reels' }) {
|
| 416 |
+
if (!topic.trim()) throw new Error('Informe o tema do vídeo.');
|
| 417 |
+
const t = topic.trim().toLowerCase();
|
| 418 |
+
const T = cap(t);
|
| 419 |
+
|
| 420 |
+
const hooks = [
|
| 421 |
+
`Pare tudo: se você se interessa por ${t}, precisa ver isso.`,
|
| 422 |
+
`Ninguém te conta a verdade sobre ${t}...`,
|
| 423 |
+
`Eu errei MUITO em ${t} até descobrir isso.`,
|
| 424 |
+
`Esse erro em ${t} está te custando caro.`,
|
| 425 |
+
`${T} em 30 segundos — presta atenção.`,
|
| 426 |
+
];
|
| 427 |
+
const ctas = [
|
| 428 |
+
`Salva esse vídeo pra não esquecer e segue pra mais conteúdo sobre ${t}! 🚀`,
|
| 429 |
+
`Comenta aqui embaixo a sua maior dúvida sobre ${t}. Eu respondo todo mundo! 💬`,
|
| 430 |
+
`Marca aquele amigo que precisa ver isso e me segue pra mais dicas! 📲`,
|
| 431 |
+
];
|
| 432 |
+
|
| 433 |
+
const isYT = format === 'youtube';
|
| 434 |
+
|
| 435 |
+
const sections = [
|
| 436 |
+
{ label: '🎣 Gancho (0–3s)', tip: 'Fale isso olhando pra câmera, com energia.', text: pick(hooks, 1)[0] },
|
| 437 |
+
{ label: '🎬 Contexto (3–10s)', tip: 'Mostre que você entende a dor de quem assiste.', text: `Se você sente que ${t} é complicado ou já tentou e não deu certo, relaxa — eu vou simplificar tudo pra você agora.` },
|
| 438 |
+
{ label: '📍 Ponto 1', tip: 'Primeira ideia prática.', text: `O primeiro passo em ${t} é entender o fundamento. A maioria pula essa parte e é por isso que trava.` },
|
| 439 |
+
{ label: '📍 Ponto 2', tip: 'Segunda ideia, aprofunde.', text: `Depois disso, foque em consistência. Pequenas ações repetidas valem mais do que grandes esforços isolados.` },
|
| 440 |
+
{ label: '📍 Ponto 3', tip: 'Terceira ideia, a mais forte.', text: `E o pulo do gato: ${t} funciona muito melhor quando você acompanha os resultados e ajusta no caminho.` },
|
| 441 |
+
{ label: '🔥 Virada', tip: 'O insight que prende até o fim.', text: `Mas o que quase ninguém te conta é que ${t} não é sobre fazer mais — é sobre fazer o certo, de forma constante.` },
|
| 442 |
+
{ label: '📢 Chamada pra ação', tip: 'Diga exatamente o que fazer agora.', text: pick(ctas, 1)[0] },
|
| 443 |
+
];
|
| 444 |
+
|
| 445 |
+
if (isYT) {
|
| 446 |
+
sections.splice(2, 0, { label: '👋 Intro do canal (10–20s)', tip: 'Só no YouTube — apresente-se rápido.', text: `Se é a primeira vez aqui no canal, seja muito bem-vindo! Aqui a gente fala sobre ${t} de um jeito direto e sem enrolação. Bora?` });
|
| 447 |
+
}
|
| 448 |
+
|
| 449 |
+
const full = sections.map(s => `${s.label}\n${s.text}`).join('\n\n');
|
| 450 |
+
const wordCount = full.split(/\s+/).length;
|
| 451 |
+
const estSeconds = Math.round(wordCount / 2.5); // ~150 wpm falado
|
| 452 |
+
|
| 453 |
+
return { topic, format, sections, full, estSeconds };
|
| 454 |
+
}
|
| 455 |
+
|
| 456 |
+
// ── #️⃣ HASHTAGS FROM TOPIC ────────────────────────────────────
|
| 457 |
+
function generateHashtagsFromTopic(topic) {
|
| 458 |
+
if (!topic || !topic.trim()) throw new Error('Informe um tópico.');
|
| 459 |
+
const keywords = extractKeywords(topic + ' ' + topic, 12);
|
| 460 |
+
const hashtags = generateHashtags(topic, keywords);
|
| 461 |
+
return { hashtags };
|
| 462 |
+
}
|
| 463 |
+
|
| 464 |
+
// ── DISPATCHER ────────────────────────────────────────────────
|
| 465 |
+
function generateTools(type, params = {}) {
|
| 466 |
+
switch (type) {
|
| 467 |
+
case 'hooks': return generateHooks(params.topic);
|
| 468 |
+
case 'ideas': return generateIdeas(params.niche);
|
| 469 |
+
case 'bio': return generateBio(params);
|
| 470 |
+
case 'calendar': return generateCalendar(params);
|
| 471 |
+
case 'caption': return generateCaptionFromTopic(params.topic);
|
| 472 |
+
case 'script': return generateScript(params);
|
| 473 |
+
case 'hashtags': return generateHashtagsFromTopic(params.topic);
|
| 474 |
+
default: throw new Error('Ferramenta desconhecida: ' + type);
|
| 475 |
+
}
|
| 476 |
+
}
|
| 477 |
+
|
| 478 |
+
module.exports = { analyze, generateTools };
|
package-lock.json
ADDED
|
@@ -0,0 +1,2047 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "reel-transcriber",
|
| 3 |
+
"version": "1.0.0",
|
| 4 |
+
"lockfileVersion": 3,
|
| 5 |
+
"requires": true,
|
| 6 |
+
"packages": {
|
| 7 |
+
"": {
|
| 8 |
+
"name": "reel-transcriber",
|
| 9 |
+
"version": "1.0.0",
|
| 10 |
+
"license": "ISC",
|
| 11 |
+
"dependencies": {
|
| 12 |
+
"@xenova/transformers": "^2.17.2",
|
| 13 |
+
"compression": "^1.8.1",
|
| 14 |
+
"express": "^5.2.1",
|
| 15 |
+
"ffmpeg-static": "^5.3.0",
|
| 16 |
+
"fluent-ffmpeg": "^2.1.3",
|
| 17 |
+
"helmet": "^8.2.0",
|
| 18 |
+
"multer": "^2.1.1",
|
| 19 |
+
"yt-dlp-wrap": "^2.3.12"
|
| 20 |
+
}
|
| 21 |
+
},
|
| 22 |
+
"node_modules/@derhuerst/http-basic": {
|
| 23 |
+
"version": "8.2.4",
|
| 24 |
+
"resolved": "https://registry.npmjs.org/@derhuerst/http-basic/-/http-basic-8.2.4.tgz",
|
| 25 |
+
"integrity": "sha512-F9rL9k9Xjf5blCz8HsJRO4diy111cayL2vkY2XE4r4t3n0yPXVYy3KD3nJ1qbrSn9743UWSXH4IwuCa/HWlGFw==",
|
| 26 |
+
"license": "MIT",
|
| 27 |
+
"dependencies": {
|
| 28 |
+
"caseless": "^0.12.0",
|
| 29 |
+
"concat-stream": "^2.0.0",
|
| 30 |
+
"http-response-object": "^3.0.1",
|
| 31 |
+
"parse-cache-control": "^1.0.1"
|
| 32 |
+
},
|
| 33 |
+
"engines": {
|
| 34 |
+
"node": ">=6.0.0"
|
| 35 |
+
}
|
| 36 |
+
},
|
| 37 |
+
"node_modules/@huggingface/jinja": {
|
| 38 |
+
"version": "0.2.2",
|
| 39 |
+
"resolved": "https://registry.npmjs.org/@huggingface/jinja/-/jinja-0.2.2.tgz",
|
| 40 |
+
"integrity": "sha512-/KPde26khDUIPkTGU82jdtTW9UAuvUTumCAbFs/7giR0SxsvZC4hru51PBvpijH6BVkHcROcvZM/lpy5h1jRRA==",
|
| 41 |
+
"license": "MIT",
|
| 42 |
+
"engines": {
|
| 43 |
+
"node": ">=18"
|
| 44 |
+
}
|
| 45 |
+
},
|
| 46 |
+
"node_modules/@protobufjs/aspromise": {
|
| 47 |
+
"version": "1.1.2",
|
| 48 |
+
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
| 49 |
+
"integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
|
| 50 |
+
"license": "BSD-3-Clause"
|
| 51 |
+
},
|
| 52 |
+
"node_modules/@protobufjs/base64": {
|
| 53 |
+
"version": "1.1.2",
|
| 54 |
+
"resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
|
| 55 |
+
"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
|
| 56 |
+
"license": "BSD-3-Clause"
|
| 57 |
+
},
|
| 58 |
+
"node_modules/@protobufjs/codegen": {
|
| 59 |
+
"version": "2.0.5",
|
| 60 |
+
"resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz",
|
| 61 |
+
"integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==",
|
| 62 |
+
"license": "BSD-3-Clause"
|
| 63 |
+
},
|
| 64 |
+
"node_modules/@protobufjs/eventemitter": {
|
| 65 |
+
"version": "1.1.1",
|
| 66 |
+
"resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz",
|
| 67 |
+
"integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==",
|
| 68 |
+
"license": "BSD-3-Clause"
|
| 69 |
+
},
|
| 70 |
+
"node_modules/@protobufjs/fetch": {
|
| 71 |
+
"version": "1.1.1",
|
| 72 |
+
"resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz",
|
| 73 |
+
"integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==",
|
| 74 |
+
"license": "BSD-3-Clause",
|
| 75 |
+
"dependencies": {
|
| 76 |
+
"@protobufjs/aspromise": "^1.1.1"
|
| 77 |
+
}
|
| 78 |
+
},
|
| 79 |
+
"node_modules/@protobufjs/float": {
|
| 80 |
+
"version": "1.0.2",
|
| 81 |
+
"resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
|
| 82 |
+
"integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
|
| 83 |
+
"license": "BSD-3-Clause"
|
| 84 |
+
},
|
| 85 |
+
"node_modules/@protobufjs/inquire": {
|
| 86 |
+
"version": "1.1.2",
|
| 87 |
+
"resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.2.tgz",
|
| 88 |
+
"integrity": "sha512-pa0vFRuws4wkvaXKK1uXZMAwAX4/t8ANaJo45iw/oQHNQ9q5xUzwgFmVJGXiga2BeN+zpX7Vf9vmsiIa2J+MUw==",
|
| 89 |
+
"license": "BSD-3-Clause"
|
| 90 |
+
},
|
| 91 |
+
"node_modules/@protobufjs/path": {
|
| 92 |
+
"version": "1.1.2",
|
| 93 |
+
"resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
|
| 94 |
+
"integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
|
| 95 |
+
"license": "BSD-3-Clause"
|
| 96 |
+
},
|
| 97 |
+
"node_modules/@protobufjs/pool": {
|
| 98 |
+
"version": "1.1.0",
|
| 99 |
+
"resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
|
| 100 |
+
"integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
|
| 101 |
+
"license": "BSD-3-Clause"
|
| 102 |
+
},
|
| 103 |
+
"node_modules/@protobufjs/utf8": {
|
| 104 |
+
"version": "1.1.1",
|
| 105 |
+
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.1.tgz",
|
| 106 |
+
"integrity": "sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==",
|
| 107 |
+
"license": "BSD-3-Clause"
|
| 108 |
+
},
|
| 109 |
+
"node_modules/@types/long": {
|
| 110 |
+
"version": "4.0.2",
|
| 111 |
+
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz",
|
| 112 |
+
"integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==",
|
| 113 |
+
"license": "MIT"
|
| 114 |
+
},
|
| 115 |
+
"node_modules/@types/node": {
|
| 116 |
+
"version": "10.17.60",
|
| 117 |
+
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz",
|
| 118 |
+
"integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==",
|
| 119 |
+
"license": "MIT"
|
| 120 |
+
},
|
| 121 |
+
"node_modules/@xenova/transformers": {
|
| 122 |
+
"version": "2.17.2",
|
| 123 |
+
"resolved": "https://registry.npmjs.org/@xenova/transformers/-/transformers-2.17.2.tgz",
|
| 124 |
+
"integrity": "sha512-lZmHqzrVIkSvZdKZEx7IYY51TK0WDrC8eR0c5IMnBsO8di8are1zzw8BlLhyO2TklZKLN5UffNGs1IJwT6oOqQ==",
|
| 125 |
+
"license": "Apache-2.0",
|
| 126 |
+
"dependencies": {
|
| 127 |
+
"@huggingface/jinja": "^0.2.2",
|
| 128 |
+
"onnxruntime-web": "1.14.0",
|
| 129 |
+
"sharp": "^0.32.0"
|
| 130 |
+
},
|
| 131 |
+
"optionalDependencies": {
|
| 132 |
+
"onnxruntime-node": "1.14.0"
|
| 133 |
+
}
|
| 134 |
+
},
|
| 135 |
+
"node_modules/accepts": {
|
| 136 |
+
"version": "2.0.0",
|
| 137 |
+
"resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
|
| 138 |
+
"integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
|
| 139 |
+
"license": "MIT",
|
| 140 |
+
"dependencies": {
|
| 141 |
+
"mime-types": "^3.0.0",
|
| 142 |
+
"negotiator": "^1.0.0"
|
| 143 |
+
},
|
| 144 |
+
"engines": {
|
| 145 |
+
"node": ">= 0.6"
|
| 146 |
+
}
|
| 147 |
+
},
|
| 148 |
+
"node_modules/agent-base": {
|
| 149 |
+
"version": "6.0.2",
|
| 150 |
+
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
| 151 |
+
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
|
| 152 |
+
"license": "MIT",
|
| 153 |
+
"dependencies": {
|
| 154 |
+
"debug": "4"
|
| 155 |
+
},
|
| 156 |
+
"engines": {
|
| 157 |
+
"node": ">= 6.0.0"
|
| 158 |
+
}
|
| 159 |
+
},
|
| 160 |
+
"node_modules/append-field": {
|
| 161 |
+
"version": "1.0.0",
|
| 162 |
+
"resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz",
|
| 163 |
+
"integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==",
|
| 164 |
+
"license": "MIT"
|
| 165 |
+
},
|
| 166 |
+
"node_modules/async": {
|
| 167 |
+
"version": "0.2.10",
|
| 168 |
+
"resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
|
| 169 |
+
"integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ=="
|
| 170 |
+
},
|
| 171 |
+
"node_modules/b4a": {
|
| 172 |
+
"version": "1.8.1",
|
| 173 |
+
"resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.1.tgz",
|
| 174 |
+
"integrity": "sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw==",
|
| 175 |
+
"license": "Apache-2.0",
|
| 176 |
+
"peerDependencies": {
|
| 177 |
+
"react-native-b4a": "*"
|
| 178 |
+
},
|
| 179 |
+
"peerDependenciesMeta": {
|
| 180 |
+
"react-native-b4a": {
|
| 181 |
+
"optional": true
|
| 182 |
+
}
|
| 183 |
+
}
|
| 184 |
+
},
|
| 185 |
+
"node_modules/bare-events": {
|
| 186 |
+
"version": "2.9.1",
|
| 187 |
+
"resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.9.1.tgz",
|
| 188 |
+
"integrity": "sha512-Z0oHEHAFDZkffN8Qc39zNZjQlMDkPJRyyyZieU1VH7u8c5S+qHZ2S8ixdKIAxEjfHO7FJxXmJWgteOghVanIsg==",
|
| 189 |
+
"license": "Apache-2.0",
|
| 190 |
+
"peerDependencies": {
|
| 191 |
+
"bare-abort-controller": "*"
|
| 192 |
+
},
|
| 193 |
+
"peerDependenciesMeta": {
|
| 194 |
+
"bare-abort-controller": {
|
| 195 |
+
"optional": true
|
| 196 |
+
}
|
| 197 |
+
}
|
| 198 |
+
},
|
| 199 |
+
"node_modules/bare-fs": {
|
| 200 |
+
"version": "4.7.2",
|
| 201 |
+
"resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.2.tgz",
|
| 202 |
+
"integrity": "sha512-aTvMFUWkBmjzKtEQMDGGDNF8bkfpD5N1b/FCwt7A3wrU4t1o/e/85Wzkluh6JlODCjqVESYCkQCdTXqZ9G7VFg==",
|
| 203 |
+
"license": "Apache-2.0",
|
| 204 |
+
"dependencies": {
|
| 205 |
+
"bare-events": "^2.5.4",
|
| 206 |
+
"bare-path": "^3.0.0",
|
| 207 |
+
"bare-stream": "^2.6.4",
|
| 208 |
+
"bare-url": "^2.2.2",
|
| 209 |
+
"fast-fifo": "^1.3.2"
|
| 210 |
+
},
|
| 211 |
+
"engines": {
|
| 212 |
+
"bare": ">=1.16.0"
|
| 213 |
+
},
|
| 214 |
+
"peerDependencies": {
|
| 215 |
+
"bare-buffer": "*"
|
| 216 |
+
},
|
| 217 |
+
"peerDependenciesMeta": {
|
| 218 |
+
"bare-buffer": {
|
| 219 |
+
"optional": true
|
| 220 |
+
}
|
| 221 |
+
}
|
| 222 |
+
},
|
| 223 |
+
"node_modules/bare-os": {
|
| 224 |
+
"version": "3.9.1",
|
| 225 |
+
"resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.9.1.tgz",
|
| 226 |
+
"integrity": "sha512-6M5XjcnsygQNPMCMPXSK379xrJFiZ/AEMNBmFEmQW8d/789VQATvriyi5r0HYTL9TkQ26rn3kgdTG3aisbrXkQ==",
|
| 227 |
+
"license": "Apache-2.0",
|
| 228 |
+
"engines": {
|
| 229 |
+
"bare": ">=1.14.0"
|
| 230 |
+
}
|
| 231 |
+
},
|
| 232 |
+
"node_modules/bare-path": {
|
| 233 |
+
"version": "3.0.1",
|
| 234 |
+
"resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.1.tgz",
|
| 235 |
+
"integrity": "sha512-ghj2DSK/2e99a1anTVPCV4m4YIYtrbXhfM7V3D7XZLOTsybnYyaJloymGqssQc8l/or0UoDyRtNQkmkEF/ysgQ==",
|
| 236 |
+
"license": "Apache-2.0",
|
| 237 |
+
"dependencies": {
|
| 238 |
+
"bare-os": "^3.0.1"
|
| 239 |
+
}
|
| 240 |
+
},
|
| 241 |
+
"node_modules/bare-stream": {
|
| 242 |
+
"version": "2.13.1",
|
| 243 |
+
"resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.13.1.tgz",
|
| 244 |
+
"integrity": "sha512-Vp0cnjYyrEC4whYTymQ+YZi6pBpfiICZO3cfRG8sy67ZNWe951urv1x4eW1BKNngw3U+3fPYb5JQvHbCtxH7Ow==",
|
| 245 |
+
"license": "Apache-2.0",
|
| 246 |
+
"dependencies": {
|
| 247 |
+
"streamx": "^2.25.0",
|
| 248 |
+
"teex": "^1.0.1"
|
| 249 |
+
},
|
| 250 |
+
"peerDependencies": {
|
| 251 |
+
"bare-abort-controller": "*",
|
| 252 |
+
"bare-buffer": "*",
|
| 253 |
+
"bare-events": "*"
|
| 254 |
+
},
|
| 255 |
+
"peerDependenciesMeta": {
|
| 256 |
+
"bare-abort-controller": {
|
| 257 |
+
"optional": true
|
| 258 |
+
},
|
| 259 |
+
"bare-buffer": {
|
| 260 |
+
"optional": true
|
| 261 |
+
},
|
| 262 |
+
"bare-events": {
|
| 263 |
+
"optional": true
|
| 264 |
+
}
|
| 265 |
+
}
|
| 266 |
+
},
|
| 267 |
+
"node_modules/bare-url": {
|
| 268 |
+
"version": "2.4.3",
|
| 269 |
+
"resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.3.tgz",
|
| 270 |
+
"integrity": "sha512-Kccpc7ACfXaxfeInfqKcZtW4pT5YBn1mesc4sCsun6sRwtbJ4h+sNOaksUpYEJUKfN65YWC6Bw2OJEFiKxq8nQ==",
|
| 271 |
+
"license": "Apache-2.0",
|
| 272 |
+
"dependencies": {
|
| 273 |
+
"bare-path": "^3.0.0"
|
| 274 |
+
}
|
| 275 |
+
},
|
| 276 |
+
"node_modules/base64-js": {
|
| 277 |
+
"version": "1.5.1",
|
| 278 |
+
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
| 279 |
+
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
| 280 |
+
"funding": [
|
| 281 |
+
{
|
| 282 |
+
"type": "github",
|
| 283 |
+
"url": "https://github.com/sponsors/feross"
|
| 284 |
+
},
|
| 285 |
+
{
|
| 286 |
+
"type": "patreon",
|
| 287 |
+
"url": "https://www.patreon.com/feross"
|
| 288 |
+
},
|
| 289 |
+
{
|
| 290 |
+
"type": "consulting",
|
| 291 |
+
"url": "https://feross.org/support"
|
| 292 |
+
}
|
| 293 |
+
],
|
| 294 |
+
"license": "MIT"
|
| 295 |
+
},
|
| 296 |
+
"node_modules/bl": {
|
| 297 |
+
"version": "4.1.0",
|
| 298 |
+
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
| 299 |
+
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
|
| 300 |
+
"license": "MIT",
|
| 301 |
+
"dependencies": {
|
| 302 |
+
"buffer": "^5.5.0",
|
| 303 |
+
"inherits": "^2.0.4",
|
| 304 |
+
"readable-stream": "^3.4.0"
|
| 305 |
+
}
|
| 306 |
+
},
|
| 307 |
+
"node_modules/body-parser": {
|
| 308 |
+
"version": "2.2.2",
|
| 309 |
+
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz",
|
| 310 |
+
"integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==",
|
| 311 |
+
"license": "MIT",
|
| 312 |
+
"dependencies": {
|
| 313 |
+
"bytes": "^3.1.2",
|
| 314 |
+
"content-type": "^1.0.5",
|
| 315 |
+
"debug": "^4.4.3",
|
| 316 |
+
"http-errors": "^2.0.0",
|
| 317 |
+
"iconv-lite": "^0.7.0",
|
| 318 |
+
"on-finished": "^2.4.1",
|
| 319 |
+
"qs": "^6.14.1",
|
| 320 |
+
"raw-body": "^3.0.1",
|
| 321 |
+
"type-is": "^2.0.1"
|
| 322 |
+
},
|
| 323 |
+
"engines": {
|
| 324 |
+
"node": ">=18"
|
| 325 |
+
},
|
| 326 |
+
"funding": {
|
| 327 |
+
"type": "opencollective",
|
| 328 |
+
"url": "https://opencollective.com/express"
|
| 329 |
+
}
|
| 330 |
+
},
|
| 331 |
+
"node_modules/buffer": {
|
| 332 |
+
"version": "5.7.1",
|
| 333 |
+
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
| 334 |
+
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
| 335 |
+
"funding": [
|
| 336 |
+
{
|
| 337 |
+
"type": "github",
|
| 338 |
+
"url": "https://github.com/sponsors/feross"
|
| 339 |
+
},
|
| 340 |
+
{
|
| 341 |
+
"type": "patreon",
|
| 342 |
+
"url": "https://www.patreon.com/feross"
|
| 343 |
+
},
|
| 344 |
+
{
|
| 345 |
+
"type": "consulting",
|
| 346 |
+
"url": "https://feross.org/support"
|
| 347 |
+
}
|
| 348 |
+
],
|
| 349 |
+
"license": "MIT",
|
| 350 |
+
"dependencies": {
|
| 351 |
+
"base64-js": "^1.3.1",
|
| 352 |
+
"ieee754": "^1.1.13"
|
| 353 |
+
}
|
| 354 |
+
},
|
| 355 |
+
"node_modules/buffer-from": {
|
| 356 |
+
"version": "1.1.2",
|
| 357 |
+
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
| 358 |
+
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
| 359 |
+
"license": "MIT"
|
| 360 |
+
},
|
| 361 |
+
"node_modules/busboy": {
|
| 362 |
+
"version": "1.6.0",
|
| 363 |
+
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
|
| 364 |
+
"integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
|
| 365 |
+
"dependencies": {
|
| 366 |
+
"streamsearch": "^1.1.0"
|
| 367 |
+
},
|
| 368 |
+
"engines": {
|
| 369 |
+
"node": ">=10.16.0"
|
| 370 |
+
}
|
| 371 |
+
},
|
| 372 |
+
"node_modules/bytes": {
|
| 373 |
+
"version": "3.1.2",
|
| 374 |
+
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
| 375 |
+
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
|
| 376 |
+
"license": "MIT",
|
| 377 |
+
"engines": {
|
| 378 |
+
"node": ">= 0.8"
|
| 379 |
+
}
|
| 380 |
+
},
|
| 381 |
+
"node_modules/call-bind-apply-helpers": {
|
| 382 |
+
"version": "1.0.2",
|
| 383 |
+
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
| 384 |
+
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
| 385 |
+
"license": "MIT",
|
| 386 |
+
"dependencies": {
|
| 387 |
+
"es-errors": "^1.3.0",
|
| 388 |
+
"function-bind": "^1.1.2"
|
| 389 |
+
},
|
| 390 |
+
"engines": {
|
| 391 |
+
"node": ">= 0.4"
|
| 392 |
+
}
|
| 393 |
+
},
|
| 394 |
+
"node_modules/call-bound": {
|
| 395 |
+
"version": "1.0.4",
|
| 396 |
+
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
|
| 397 |
+
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
|
| 398 |
+
"license": "MIT",
|
| 399 |
+
"dependencies": {
|
| 400 |
+
"call-bind-apply-helpers": "^1.0.2",
|
| 401 |
+
"get-intrinsic": "^1.3.0"
|
| 402 |
+
},
|
| 403 |
+
"engines": {
|
| 404 |
+
"node": ">= 0.4"
|
| 405 |
+
},
|
| 406 |
+
"funding": {
|
| 407 |
+
"url": "https://github.com/sponsors/ljharb"
|
| 408 |
+
}
|
| 409 |
+
},
|
| 410 |
+
"node_modules/caseless": {
|
| 411 |
+
"version": "0.12.0",
|
| 412 |
+
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
| 413 |
+
"integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==",
|
| 414 |
+
"license": "Apache-2.0"
|
| 415 |
+
},
|
| 416 |
+
"node_modules/chownr": {
|
| 417 |
+
"version": "1.1.4",
|
| 418 |
+
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
|
| 419 |
+
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
|
| 420 |
+
"license": "ISC"
|
| 421 |
+
},
|
| 422 |
+
"node_modules/color": {
|
| 423 |
+
"version": "4.2.3",
|
| 424 |
+
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
|
| 425 |
+
"integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
|
| 426 |
+
"license": "MIT",
|
| 427 |
+
"dependencies": {
|
| 428 |
+
"color-convert": "^2.0.1",
|
| 429 |
+
"color-string": "^1.9.0"
|
| 430 |
+
},
|
| 431 |
+
"engines": {
|
| 432 |
+
"node": ">=12.5.0"
|
| 433 |
+
}
|
| 434 |
+
},
|
| 435 |
+
"node_modules/color-convert": {
|
| 436 |
+
"version": "2.0.1",
|
| 437 |
+
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
| 438 |
+
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
| 439 |
+
"license": "MIT",
|
| 440 |
+
"dependencies": {
|
| 441 |
+
"color-name": "~1.1.4"
|
| 442 |
+
},
|
| 443 |
+
"engines": {
|
| 444 |
+
"node": ">=7.0.0"
|
| 445 |
+
}
|
| 446 |
+
},
|
| 447 |
+
"node_modules/color-name": {
|
| 448 |
+
"version": "1.1.4",
|
| 449 |
+
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
| 450 |
+
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
| 451 |
+
"license": "MIT"
|
| 452 |
+
},
|
| 453 |
+
"node_modules/color-string": {
|
| 454 |
+
"version": "1.9.1",
|
| 455 |
+
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
|
| 456 |
+
"integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
|
| 457 |
+
"license": "MIT",
|
| 458 |
+
"dependencies": {
|
| 459 |
+
"color-name": "^1.0.0",
|
| 460 |
+
"simple-swizzle": "^0.2.2"
|
| 461 |
+
}
|
| 462 |
+
},
|
| 463 |
+
"node_modules/compressible": {
|
| 464 |
+
"version": "2.0.18",
|
| 465 |
+
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
|
| 466 |
+
"integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
|
| 467 |
+
"license": "MIT",
|
| 468 |
+
"dependencies": {
|
| 469 |
+
"mime-db": ">= 1.43.0 < 2"
|
| 470 |
+
},
|
| 471 |
+
"engines": {
|
| 472 |
+
"node": ">= 0.6"
|
| 473 |
+
}
|
| 474 |
+
},
|
| 475 |
+
"node_modules/compression": {
|
| 476 |
+
"version": "1.8.1",
|
| 477 |
+
"resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz",
|
| 478 |
+
"integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==",
|
| 479 |
+
"license": "MIT",
|
| 480 |
+
"dependencies": {
|
| 481 |
+
"bytes": "3.1.2",
|
| 482 |
+
"compressible": "~2.0.18",
|
| 483 |
+
"debug": "2.6.9",
|
| 484 |
+
"negotiator": "~0.6.4",
|
| 485 |
+
"on-headers": "~1.1.0",
|
| 486 |
+
"safe-buffer": "5.2.1",
|
| 487 |
+
"vary": "~1.1.2"
|
| 488 |
+
},
|
| 489 |
+
"engines": {
|
| 490 |
+
"node": ">= 0.8.0"
|
| 491 |
+
}
|
| 492 |
+
},
|
| 493 |
+
"node_modules/compression/node_modules/debug": {
|
| 494 |
+
"version": "2.6.9",
|
| 495 |
+
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
| 496 |
+
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
| 497 |
+
"license": "MIT",
|
| 498 |
+
"dependencies": {
|
| 499 |
+
"ms": "2.0.0"
|
| 500 |
+
}
|
| 501 |
+
},
|
| 502 |
+
"node_modules/compression/node_modules/ms": {
|
| 503 |
+
"version": "2.0.0",
|
| 504 |
+
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
| 505 |
+
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
| 506 |
+
"license": "MIT"
|
| 507 |
+
},
|
| 508 |
+
"node_modules/compression/node_modules/negotiator": {
|
| 509 |
+
"version": "0.6.4",
|
| 510 |
+
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
|
| 511 |
+
"integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==",
|
| 512 |
+
"license": "MIT",
|
| 513 |
+
"engines": {
|
| 514 |
+
"node": ">= 0.6"
|
| 515 |
+
}
|
| 516 |
+
},
|
| 517 |
+
"node_modules/concat-stream": {
|
| 518 |
+
"version": "2.0.0",
|
| 519 |
+
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
|
| 520 |
+
"integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
|
| 521 |
+
"engines": [
|
| 522 |
+
"node >= 6.0"
|
| 523 |
+
],
|
| 524 |
+
"license": "MIT",
|
| 525 |
+
"dependencies": {
|
| 526 |
+
"buffer-from": "^1.0.0",
|
| 527 |
+
"inherits": "^2.0.3",
|
| 528 |
+
"readable-stream": "^3.0.2",
|
| 529 |
+
"typedarray": "^0.0.6"
|
| 530 |
+
}
|
| 531 |
+
},
|
| 532 |
+
"node_modules/content-disposition": {
|
| 533 |
+
"version": "1.1.0",
|
| 534 |
+
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz",
|
| 535 |
+
"integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==",
|
| 536 |
+
"license": "MIT",
|
| 537 |
+
"engines": {
|
| 538 |
+
"node": ">=18"
|
| 539 |
+
},
|
| 540 |
+
"funding": {
|
| 541 |
+
"type": "opencollective",
|
| 542 |
+
"url": "https://opencollective.com/express"
|
| 543 |
+
}
|
| 544 |
+
},
|
| 545 |
+
"node_modules/content-type": {
|
| 546 |
+
"version": "1.0.5",
|
| 547 |
+
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
|
| 548 |
+
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
|
| 549 |
+
"license": "MIT",
|
| 550 |
+
"engines": {
|
| 551 |
+
"node": ">= 0.6"
|
| 552 |
+
}
|
| 553 |
+
},
|
| 554 |
+
"node_modules/cookie": {
|
| 555 |
+
"version": "0.7.2",
|
| 556 |
+
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
|
| 557 |
+
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
|
| 558 |
+
"license": "MIT",
|
| 559 |
+
"engines": {
|
| 560 |
+
"node": ">= 0.6"
|
| 561 |
+
}
|
| 562 |
+
},
|
| 563 |
+
"node_modules/cookie-signature": {
|
| 564 |
+
"version": "1.2.2",
|
| 565 |
+
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
|
| 566 |
+
"integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
|
| 567 |
+
"license": "MIT",
|
| 568 |
+
"engines": {
|
| 569 |
+
"node": ">=6.6.0"
|
| 570 |
+
}
|
| 571 |
+
},
|
| 572 |
+
"node_modules/debug": {
|
| 573 |
+
"version": "4.4.3",
|
| 574 |
+
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
| 575 |
+
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
| 576 |
+
"license": "MIT",
|
| 577 |
+
"dependencies": {
|
| 578 |
+
"ms": "^2.1.3"
|
| 579 |
+
},
|
| 580 |
+
"engines": {
|
| 581 |
+
"node": ">=6.0"
|
| 582 |
+
},
|
| 583 |
+
"peerDependenciesMeta": {
|
| 584 |
+
"supports-color": {
|
| 585 |
+
"optional": true
|
| 586 |
+
}
|
| 587 |
+
}
|
| 588 |
+
},
|
| 589 |
+
"node_modules/decompress-response": {
|
| 590 |
+
"version": "6.0.0",
|
| 591 |
+
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
|
| 592 |
+
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
|
| 593 |
+
"license": "MIT",
|
| 594 |
+
"dependencies": {
|
| 595 |
+
"mimic-response": "^3.1.0"
|
| 596 |
+
},
|
| 597 |
+
"engines": {
|
| 598 |
+
"node": ">=10"
|
| 599 |
+
},
|
| 600 |
+
"funding": {
|
| 601 |
+
"url": "https://github.com/sponsors/sindresorhus"
|
| 602 |
+
}
|
| 603 |
+
},
|
| 604 |
+
"node_modules/deep-extend": {
|
| 605 |
+
"version": "0.6.0",
|
| 606 |
+
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
|
| 607 |
+
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
|
| 608 |
+
"license": "MIT",
|
| 609 |
+
"engines": {
|
| 610 |
+
"node": ">=4.0.0"
|
| 611 |
+
}
|
| 612 |
+
},
|
| 613 |
+
"node_modules/depd": {
|
| 614 |
+
"version": "2.0.0",
|
| 615 |
+
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
| 616 |
+
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
|
| 617 |
+
"license": "MIT",
|
| 618 |
+
"engines": {
|
| 619 |
+
"node": ">= 0.8"
|
| 620 |
+
}
|
| 621 |
+
},
|
| 622 |
+
"node_modules/detect-libc": {
|
| 623 |
+
"version": "2.1.2",
|
| 624 |
+
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
|
| 625 |
+
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
|
| 626 |
+
"license": "Apache-2.0",
|
| 627 |
+
"engines": {
|
| 628 |
+
"node": ">=8"
|
| 629 |
+
}
|
| 630 |
+
},
|
| 631 |
+
"node_modules/dunder-proto": {
|
| 632 |
+
"version": "1.0.1",
|
| 633 |
+
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
| 634 |
+
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
| 635 |
+
"license": "MIT",
|
| 636 |
+
"dependencies": {
|
| 637 |
+
"call-bind-apply-helpers": "^1.0.1",
|
| 638 |
+
"es-errors": "^1.3.0",
|
| 639 |
+
"gopd": "^1.2.0"
|
| 640 |
+
},
|
| 641 |
+
"engines": {
|
| 642 |
+
"node": ">= 0.4"
|
| 643 |
+
}
|
| 644 |
+
},
|
| 645 |
+
"node_modules/ee-first": {
|
| 646 |
+
"version": "1.1.1",
|
| 647 |
+
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
| 648 |
+
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
|
| 649 |
+
"license": "MIT"
|
| 650 |
+
},
|
| 651 |
+
"node_modules/encodeurl": {
|
| 652 |
+
"version": "2.0.0",
|
| 653 |
+
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
|
| 654 |
+
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
|
| 655 |
+
"license": "MIT",
|
| 656 |
+
"engines": {
|
| 657 |
+
"node": ">= 0.8"
|
| 658 |
+
}
|
| 659 |
+
},
|
| 660 |
+
"node_modules/end-of-stream": {
|
| 661 |
+
"version": "1.4.5",
|
| 662 |
+
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
|
| 663 |
+
"integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
|
| 664 |
+
"license": "MIT",
|
| 665 |
+
"dependencies": {
|
| 666 |
+
"once": "^1.4.0"
|
| 667 |
+
}
|
| 668 |
+
},
|
| 669 |
+
"node_modules/env-paths": {
|
| 670 |
+
"version": "2.2.1",
|
| 671 |
+
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
|
| 672 |
+
"integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
|
| 673 |
+
"license": "MIT",
|
| 674 |
+
"engines": {
|
| 675 |
+
"node": ">=6"
|
| 676 |
+
}
|
| 677 |
+
},
|
| 678 |
+
"node_modules/es-define-property": {
|
| 679 |
+
"version": "1.0.1",
|
| 680 |
+
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
| 681 |
+
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
| 682 |
+
"license": "MIT",
|
| 683 |
+
"engines": {
|
| 684 |
+
"node": ">= 0.4"
|
| 685 |
+
}
|
| 686 |
+
},
|
| 687 |
+
"node_modules/es-errors": {
|
| 688 |
+
"version": "1.3.0",
|
| 689 |
+
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
| 690 |
+
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
| 691 |
+
"license": "MIT",
|
| 692 |
+
"engines": {
|
| 693 |
+
"node": ">= 0.4"
|
| 694 |
+
}
|
| 695 |
+
},
|
| 696 |
+
"node_modules/es-object-atoms": {
|
| 697 |
+
"version": "1.1.2",
|
| 698 |
+
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
|
| 699 |
+
"integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
|
| 700 |
+
"license": "MIT",
|
| 701 |
+
"dependencies": {
|
| 702 |
+
"es-errors": "^1.3.0"
|
| 703 |
+
},
|
| 704 |
+
"engines": {
|
| 705 |
+
"node": ">= 0.4"
|
| 706 |
+
}
|
| 707 |
+
},
|
| 708 |
+
"node_modules/escape-html": {
|
| 709 |
+
"version": "1.0.3",
|
| 710 |
+
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
| 711 |
+
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
|
| 712 |
+
"license": "MIT"
|
| 713 |
+
},
|
| 714 |
+
"node_modules/etag": {
|
| 715 |
+
"version": "1.8.1",
|
| 716 |
+
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
| 717 |
+
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
|
| 718 |
+
"license": "MIT",
|
| 719 |
+
"engines": {
|
| 720 |
+
"node": ">= 0.6"
|
| 721 |
+
}
|
| 722 |
+
},
|
| 723 |
+
"node_modules/events-universal": {
|
| 724 |
+
"version": "1.0.1",
|
| 725 |
+
"resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz",
|
| 726 |
+
"integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==",
|
| 727 |
+
"license": "Apache-2.0",
|
| 728 |
+
"dependencies": {
|
| 729 |
+
"bare-events": "^2.7.0"
|
| 730 |
+
}
|
| 731 |
+
},
|
| 732 |
+
"node_modules/expand-template": {
|
| 733 |
+
"version": "2.0.3",
|
| 734 |
+
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
|
| 735 |
+
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
|
| 736 |
+
"license": "(MIT OR WTFPL)",
|
| 737 |
+
"engines": {
|
| 738 |
+
"node": ">=6"
|
| 739 |
+
}
|
| 740 |
+
},
|
| 741 |
+
"node_modules/express": {
|
| 742 |
+
"version": "5.2.1",
|
| 743 |
+
"resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
|
| 744 |
+
"integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
|
| 745 |
+
"license": "MIT",
|
| 746 |
+
"dependencies": {
|
| 747 |
+
"accepts": "^2.0.0",
|
| 748 |
+
"body-parser": "^2.2.1",
|
| 749 |
+
"content-disposition": "^1.0.0",
|
| 750 |
+
"content-type": "^1.0.5",
|
| 751 |
+
"cookie": "^0.7.1",
|
| 752 |
+
"cookie-signature": "^1.2.1",
|
| 753 |
+
"debug": "^4.4.0",
|
| 754 |
+
"depd": "^2.0.0",
|
| 755 |
+
"encodeurl": "^2.0.0",
|
| 756 |
+
"escape-html": "^1.0.3",
|
| 757 |
+
"etag": "^1.8.1",
|
| 758 |
+
"finalhandler": "^2.1.0",
|
| 759 |
+
"fresh": "^2.0.0",
|
| 760 |
+
"http-errors": "^2.0.0",
|
| 761 |
+
"merge-descriptors": "^2.0.0",
|
| 762 |
+
"mime-types": "^3.0.0",
|
| 763 |
+
"on-finished": "^2.4.1",
|
| 764 |
+
"once": "^1.4.0",
|
| 765 |
+
"parseurl": "^1.3.3",
|
| 766 |
+
"proxy-addr": "^2.0.7",
|
| 767 |
+
"qs": "^6.14.0",
|
| 768 |
+
"range-parser": "^1.2.1",
|
| 769 |
+
"router": "^2.2.0",
|
| 770 |
+
"send": "^1.1.0",
|
| 771 |
+
"serve-static": "^2.2.0",
|
| 772 |
+
"statuses": "^2.0.1",
|
| 773 |
+
"type-is": "^2.0.1",
|
| 774 |
+
"vary": "^1.1.2"
|
| 775 |
+
},
|
| 776 |
+
"engines": {
|
| 777 |
+
"node": ">= 18"
|
| 778 |
+
},
|
| 779 |
+
"funding": {
|
| 780 |
+
"type": "opencollective",
|
| 781 |
+
"url": "https://opencollective.com/express"
|
| 782 |
+
}
|
| 783 |
+
},
|
| 784 |
+
"node_modules/fast-fifo": {
|
| 785 |
+
"version": "1.3.2",
|
| 786 |
+
"resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
|
| 787 |
+
"integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",
|
| 788 |
+
"license": "MIT"
|
| 789 |
+
},
|
| 790 |
+
"node_modules/ffmpeg-static": {
|
| 791 |
+
"version": "5.3.0",
|
| 792 |
+
"resolved": "https://registry.npmjs.org/ffmpeg-static/-/ffmpeg-static-5.3.0.tgz",
|
| 793 |
+
"integrity": "sha512-H+K6sW6TiIX6VGend0KQwthe+kaceeH/luE8dIZyOP35ik7ahYojDuqlTV1bOrtEwl01sy2HFNGQfi5IDJvotg==",
|
| 794 |
+
"hasInstallScript": true,
|
| 795 |
+
"license": "GPL-3.0-or-later",
|
| 796 |
+
"dependencies": {
|
| 797 |
+
"@derhuerst/http-basic": "^8.2.0",
|
| 798 |
+
"env-paths": "^2.2.0",
|
| 799 |
+
"https-proxy-agent": "^5.0.0",
|
| 800 |
+
"progress": "^2.0.3"
|
| 801 |
+
},
|
| 802 |
+
"engines": {
|
| 803 |
+
"node": ">=16"
|
| 804 |
+
}
|
| 805 |
+
},
|
| 806 |
+
"node_modules/finalhandler": {
|
| 807 |
+
"version": "2.1.1",
|
| 808 |
+
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
|
| 809 |
+
"integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==",
|
| 810 |
+
"license": "MIT",
|
| 811 |
+
"dependencies": {
|
| 812 |
+
"debug": "^4.4.0",
|
| 813 |
+
"encodeurl": "^2.0.0",
|
| 814 |
+
"escape-html": "^1.0.3",
|
| 815 |
+
"on-finished": "^2.4.1",
|
| 816 |
+
"parseurl": "^1.3.3",
|
| 817 |
+
"statuses": "^2.0.1"
|
| 818 |
+
},
|
| 819 |
+
"engines": {
|
| 820 |
+
"node": ">= 18.0.0"
|
| 821 |
+
},
|
| 822 |
+
"funding": {
|
| 823 |
+
"type": "opencollective",
|
| 824 |
+
"url": "https://opencollective.com/express"
|
| 825 |
+
}
|
| 826 |
+
},
|
| 827 |
+
"node_modules/flatbuffers": {
|
| 828 |
+
"version": "1.12.0",
|
| 829 |
+
"resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.12.0.tgz",
|
| 830 |
+
"integrity": "sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ==",
|
| 831 |
+
"license": "SEE LICENSE IN LICENSE.txt"
|
| 832 |
+
},
|
| 833 |
+
"node_modules/fluent-ffmpeg": {
|
| 834 |
+
"version": "2.1.3",
|
| 835 |
+
"resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.3.tgz",
|
| 836 |
+
"integrity": "sha512-Be3narBNt2s6bsaqP6Jzq91heDgOEaDCJAXcE3qcma/EJBSy5FB4cvO31XBInuAuKBx8Kptf8dkhjK0IOru39Q==",
|
| 837 |
+
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
|
| 838 |
+
"license": "MIT",
|
| 839 |
+
"dependencies": {
|
| 840 |
+
"async": "^0.2.9",
|
| 841 |
+
"which": "^1.1.1"
|
| 842 |
+
},
|
| 843 |
+
"engines": {
|
| 844 |
+
"node": ">=18"
|
| 845 |
+
}
|
| 846 |
+
},
|
| 847 |
+
"node_modules/forwarded": {
|
| 848 |
+
"version": "0.2.0",
|
| 849 |
+
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
| 850 |
+
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
|
| 851 |
+
"license": "MIT",
|
| 852 |
+
"engines": {
|
| 853 |
+
"node": ">= 0.6"
|
| 854 |
+
}
|
| 855 |
+
},
|
| 856 |
+
"node_modules/fresh": {
|
| 857 |
+
"version": "2.0.0",
|
| 858 |
+
"resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
|
| 859 |
+
"integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
|
| 860 |
+
"license": "MIT",
|
| 861 |
+
"engines": {
|
| 862 |
+
"node": ">= 0.8"
|
| 863 |
+
}
|
| 864 |
+
},
|
| 865 |
+
"node_modules/fs-constants": {
|
| 866 |
+
"version": "1.0.0",
|
| 867 |
+
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
|
| 868 |
+
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
|
| 869 |
+
"license": "MIT"
|
| 870 |
+
},
|
| 871 |
+
"node_modules/function-bind": {
|
| 872 |
+
"version": "1.1.2",
|
| 873 |
+
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
| 874 |
+
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
| 875 |
+
"license": "MIT",
|
| 876 |
+
"funding": {
|
| 877 |
+
"url": "https://github.com/sponsors/ljharb"
|
| 878 |
+
}
|
| 879 |
+
},
|
| 880 |
+
"node_modules/get-intrinsic": {
|
| 881 |
+
"version": "1.3.0",
|
| 882 |
+
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
| 883 |
+
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
| 884 |
+
"license": "MIT",
|
| 885 |
+
"dependencies": {
|
| 886 |
+
"call-bind-apply-helpers": "^1.0.2",
|
| 887 |
+
"es-define-property": "^1.0.1",
|
| 888 |
+
"es-errors": "^1.3.0",
|
| 889 |
+
"es-object-atoms": "^1.1.1",
|
| 890 |
+
"function-bind": "^1.1.2",
|
| 891 |
+
"get-proto": "^1.0.1",
|
| 892 |
+
"gopd": "^1.2.0",
|
| 893 |
+
"has-symbols": "^1.1.0",
|
| 894 |
+
"hasown": "^2.0.2",
|
| 895 |
+
"math-intrinsics": "^1.1.0"
|
| 896 |
+
},
|
| 897 |
+
"engines": {
|
| 898 |
+
"node": ">= 0.4"
|
| 899 |
+
},
|
| 900 |
+
"funding": {
|
| 901 |
+
"url": "https://github.com/sponsors/ljharb"
|
| 902 |
+
}
|
| 903 |
+
},
|
| 904 |
+
"node_modules/get-proto": {
|
| 905 |
+
"version": "1.0.1",
|
| 906 |
+
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
|
| 907 |
+
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
| 908 |
+
"license": "MIT",
|
| 909 |
+
"dependencies": {
|
| 910 |
+
"dunder-proto": "^1.0.1",
|
| 911 |
+
"es-object-atoms": "^1.0.0"
|
| 912 |
+
},
|
| 913 |
+
"engines": {
|
| 914 |
+
"node": ">= 0.4"
|
| 915 |
+
}
|
| 916 |
+
},
|
| 917 |
+
"node_modules/github-from-package": {
|
| 918 |
+
"version": "0.0.0",
|
| 919 |
+
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
|
| 920 |
+
"integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
|
| 921 |
+
"license": "MIT"
|
| 922 |
+
},
|
| 923 |
+
"node_modules/gopd": {
|
| 924 |
+
"version": "1.2.0",
|
| 925 |
+
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
| 926 |
+
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
| 927 |
+
"license": "MIT",
|
| 928 |
+
"engines": {
|
| 929 |
+
"node": ">= 0.4"
|
| 930 |
+
},
|
| 931 |
+
"funding": {
|
| 932 |
+
"url": "https://github.com/sponsors/ljharb"
|
| 933 |
+
}
|
| 934 |
+
},
|
| 935 |
+
"node_modules/guid-typescript": {
|
| 936 |
+
"version": "1.0.9",
|
| 937 |
+
"resolved": "https://registry.npmjs.org/guid-typescript/-/guid-typescript-1.0.9.tgz",
|
| 938 |
+
"integrity": "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==",
|
| 939 |
+
"license": "ISC"
|
| 940 |
+
},
|
| 941 |
+
"node_modules/has-symbols": {
|
| 942 |
+
"version": "1.1.0",
|
| 943 |
+
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
| 944 |
+
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
| 945 |
+
"license": "MIT",
|
| 946 |
+
"engines": {
|
| 947 |
+
"node": ">= 0.4"
|
| 948 |
+
},
|
| 949 |
+
"funding": {
|
| 950 |
+
"url": "https://github.com/sponsors/ljharb"
|
| 951 |
+
}
|
| 952 |
+
},
|
| 953 |
+
"node_modules/hasown": {
|
| 954 |
+
"version": "2.0.4",
|
| 955 |
+
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
|
| 956 |
+
"integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
|
| 957 |
+
"license": "MIT",
|
| 958 |
+
"dependencies": {
|
| 959 |
+
"function-bind": "^1.1.2"
|
| 960 |
+
},
|
| 961 |
+
"engines": {
|
| 962 |
+
"node": ">= 0.4"
|
| 963 |
+
}
|
| 964 |
+
},
|
| 965 |
+
"node_modules/helmet": {
|
| 966 |
+
"version": "8.2.0",
|
| 967 |
+
"resolved": "https://registry.npmjs.org/helmet/-/helmet-8.2.0.tgz",
|
| 968 |
+
"integrity": "sha512-DRgTIUgnWcJ62KyarxxziuqYxKGnR6Rgg19BlbucN/dpmJbl1XOit6qvoOX0ZT+HhWe5OUVhU/a1zpGyc1xA0Q==",
|
| 969 |
+
"license": "MIT",
|
| 970 |
+
"engines": {
|
| 971 |
+
"node": ">=18.0.0"
|
| 972 |
+
},
|
| 973 |
+
"funding": {
|
| 974 |
+
"url": "https://github.com/sponsors/EvanHahn"
|
| 975 |
+
}
|
| 976 |
+
},
|
| 977 |
+
"node_modules/http-errors": {
|
| 978 |
+
"version": "2.0.1",
|
| 979 |
+
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
|
| 980 |
+
"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
|
| 981 |
+
"license": "MIT",
|
| 982 |
+
"dependencies": {
|
| 983 |
+
"depd": "~2.0.0",
|
| 984 |
+
"inherits": "~2.0.4",
|
| 985 |
+
"setprototypeof": "~1.2.0",
|
| 986 |
+
"statuses": "~2.0.2",
|
| 987 |
+
"toidentifier": "~1.0.1"
|
| 988 |
+
},
|
| 989 |
+
"engines": {
|
| 990 |
+
"node": ">= 0.8"
|
| 991 |
+
},
|
| 992 |
+
"funding": {
|
| 993 |
+
"type": "opencollective",
|
| 994 |
+
"url": "https://opencollective.com/express"
|
| 995 |
+
}
|
| 996 |
+
},
|
| 997 |
+
"node_modules/http-response-object": {
|
| 998 |
+
"version": "3.0.2",
|
| 999 |
+
"resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz",
|
| 1000 |
+
"integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==",
|
| 1001 |
+
"license": "MIT",
|
| 1002 |
+
"dependencies": {
|
| 1003 |
+
"@types/node": "^10.0.3"
|
| 1004 |
+
}
|
| 1005 |
+
},
|
| 1006 |
+
"node_modules/https-proxy-agent": {
|
| 1007 |
+
"version": "5.0.1",
|
| 1008 |
+
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
|
| 1009 |
+
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
|
| 1010 |
+
"license": "MIT",
|
| 1011 |
+
"dependencies": {
|
| 1012 |
+
"agent-base": "6",
|
| 1013 |
+
"debug": "4"
|
| 1014 |
+
},
|
| 1015 |
+
"engines": {
|
| 1016 |
+
"node": ">= 6"
|
| 1017 |
+
}
|
| 1018 |
+
},
|
| 1019 |
+
"node_modules/iconv-lite": {
|
| 1020 |
+
"version": "0.7.2",
|
| 1021 |
+
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
|
| 1022 |
+
"integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
|
| 1023 |
+
"license": "MIT",
|
| 1024 |
+
"dependencies": {
|
| 1025 |
+
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
| 1026 |
+
},
|
| 1027 |
+
"engines": {
|
| 1028 |
+
"node": ">=0.10.0"
|
| 1029 |
+
},
|
| 1030 |
+
"funding": {
|
| 1031 |
+
"type": "opencollective",
|
| 1032 |
+
"url": "https://opencollective.com/express"
|
| 1033 |
+
}
|
| 1034 |
+
},
|
| 1035 |
+
"node_modules/ieee754": {
|
| 1036 |
+
"version": "1.2.1",
|
| 1037 |
+
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
| 1038 |
+
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
| 1039 |
+
"funding": [
|
| 1040 |
+
{
|
| 1041 |
+
"type": "github",
|
| 1042 |
+
"url": "https://github.com/sponsors/feross"
|
| 1043 |
+
},
|
| 1044 |
+
{
|
| 1045 |
+
"type": "patreon",
|
| 1046 |
+
"url": "https://www.patreon.com/feross"
|
| 1047 |
+
},
|
| 1048 |
+
{
|
| 1049 |
+
"type": "consulting",
|
| 1050 |
+
"url": "https://feross.org/support"
|
| 1051 |
+
}
|
| 1052 |
+
],
|
| 1053 |
+
"license": "BSD-3-Clause"
|
| 1054 |
+
},
|
| 1055 |
+
"node_modules/inherits": {
|
| 1056 |
+
"version": "2.0.4",
|
| 1057 |
+
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
| 1058 |
+
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
| 1059 |
+
"license": "ISC"
|
| 1060 |
+
},
|
| 1061 |
+
"node_modules/ini": {
|
| 1062 |
+
"version": "1.3.8",
|
| 1063 |
+
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
|
| 1064 |
+
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
|
| 1065 |
+
"license": "ISC"
|
| 1066 |
+
},
|
| 1067 |
+
"node_modules/ipaddr.js": {
|
| 1068 |
+
"version": "1.9.1",
|
| 1069 |
+
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
| 1070 |
+
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
|
| 1071 |
+
"license": "MIT",
|
| 1072 |
+
"engines": {
|
| 1073 |
+
"node": ">= 0.10"
|
| 1074 |
+
}
|
| 1075 |
+
},
|
| 1076 |
+
"node_modules/is-arrayish": {
|
| 1077 |
+
"version": "0.3.4",
|
| 1078 |
+
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz",
|
| 1079 |
+
"integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==",
|
| 1080 |
+
"license": "MIT"
|
| 1081 |
+
},
|
| 1082 |
+
"node_modules/is-promise": {
|
| 1083 |
+
"version": "4.0.0",
|
| 1084 |
+
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
|
| 1085 |
+
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
|
| 1086 |
+
"license": "MIT"
|
| 1087 |
+
},
|
| 1088 |
+
"node_modules/isexe": {
|
| 1089 |
+
"version": "2.0.0",
|
| 1090 |
+
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
| 1091 |
+
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
| 1092 |
+
"license": "ISC"
|
| 1093 |
+
},
|
| 1094 |
+
"node_modules/long": {
|
| 1095 |
+
"version": "4.0.0",
|
| 1096 |
+
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
|
| 1097 |
+
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==",
|
| 1098 |
+
"license": "Apache-2.0"
|
| 1099 |
+
},
|
| 1100 |
+
"node_modules/math-intrinsics": {
|
| 1101 |
+
"version": "1.1.0",
|
| 1102 |
+
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
| 1103 |
+
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
| 1104 |
+
"license": "MIT",
|
| 1105 |
+
"engines": {
|
| 1106 |
+
"node": ">= 0.4"
|
| 1107 |
+
}
|
| 1108 |
+
},
|
| 1109 |
+
"node_modules/media-typer": {
|
| 1110 |
+
"version": "1.1.0",
|
| 1111 |
+
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
|
| 1112 |
+
"integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
|
| 1113 |
+
"license": "MIT",
|
| 1114 |
+
"engines": {
|
| 1115 |
+
"node": ">= 0.8"
|
| 1116 |
+
}
|
| 1117 |
+
},
|
| 1118 |
+
"node_modules/merge-descriptors": {
|
| 1119 |
+
"version": "2.0.0",
|
| 1120 |
+
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
|
| 1121 |
+
"integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
|
| 1122 |
+
"license": "MIT",
|
| 1123 |
+
"engines": {
|
| 1124 |
+
"node": ">=18"
|
| 1125 |
+
},
|
| 1126 |
+
"funding": {
|
| 1127 |
+
"url": "https://github.com/sponsors/sindresorhus"
|
| 1128 |
+
}
|
| 1129 |
+
},
|
| 1130 |
+
"node_modules/mime-db": {
|
| 1131 |
+
"version": "1.54.0",
|
| 1132 |
+
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
|
| 1133 |
+
"integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
|
| 1134 |
+
"license": "MIT",
|
| 1135 |
+
"engines": {
|
| 1136 |
+
"node": ">= 0.6"
|
| 1137 |
+
}
|
| 1138 |
+
},
|
| 1139 |
+
"node_modules/mime-types": {
|
| 1140 |
+
"version": "3.0.2",
|
| 1141 |
+
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
|
| 1142 |
+
"integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
|
| 1143 |
+
"license": "MIT",
|
| 1144 |
+
"dependencies": {
|
| 1145 |
+
"mime-db": "^1.54.0"
|
| 1146 |
+
},
|
| 1147 |
+
"engines": {
|
| 1148 |
+
"node": ">=18"
|
| 1149 |
+
},
|
| 1150 |
+
"funding": {
|
| 1151 |
+
"type": "opencollective",
|
| 1152 |
+
"url": "https://opencollective.com/express"
|
| 1153 |
+
}
|
| 1154 |
+
},
|
| 1155 |
+
"node_modules/mimic-response": {
|
| 1156 |
+
"version": "3.1.0",
|
| 1157 |
+
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
|
| 1158 |
+
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
|
| 1159 |
+
"license": "MIT",
|
| 1160 |
+
"engines": {
|
| 1161 |
+
"node": ">=10"
|
| 1162 |
+
},
|
| 1163 |
+
"funding": {
|
| 1164 |
+
"url": "https://github.com/sponsors/sindresorhus"
|
| 1165 |
+
}
|
| 1166 |
+
},
|
| 1167 |
+
"node_modules/minimist": {
|
| 1168 |
+
"version": "1.2.8",
|
| 1169 |
+
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
| 1170 |
+
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
| 1171 |
+
"license": "MIT",
|
| 1172 |
+
"funding": {
|
| 1173 |
+
"url": "https://github.com/sponsors/ljharb"
|
| 1174 |
+
}
|
| 1175 |
+
},
|
| 1176 |
+
"node_modules/mkdirp-classic": {
|
| 1177 |
+
"version": "0.5.3",
|
| 1178 |
+
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
|
| 1179 |
+
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
|
| 1180 |
+
"license": "MIT"
|
| 1181 |
+
},
|
| 1182 |
+
"node_modules/ms": {
|
| 1183 |
+
"version": "2.1.3",
|
| 1184 |
+
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
| 1185 |
+
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
| 1186 |
+
"license": "MIT"
|
| 1187 |
+
},
|
| 1188 |
+
"node_modules/multer": {
|
| 1189 |
+
"version": "2.1.1",
|
| 1190 |
+
"resolved": "https://registry.npmjs.org/multer/-/multer-2.1.1.tgz",
|
| 1191 |
+
"integrity": "sha512-mo+QTzKlx8R7E5ylSXxWzGoXoZbOsRMpyitcht8By2KHvMbf3tjwosZ/Mu/XYU6UuJ3VZnODIrak5ZrPiPyB6A==",
|
| 1192 |
+
"license": "MIT",
|
| 1193 |
+
"dependencies": {
|
| 1194 |
+
"append-field": "^1.0.0",
|
| 1195 |
+
"busboy": "^1.6.0",
|
| 1196 |
+
"concat-stream": "^2.0.0",
|
| 1197 |
+
"type-is": "^1.6.18"
|
| 1198 |
+
},
|
| 1199 |
+
"engines": {
|
| 1200 |
+
"node": ">= 10.16.0"
|
| 1201 |
+
},
|
| 1202 |
+
"funding": {
|
| 1203 |
+
"type": "opencollective",
|
| 1204 |
+
"url": "https://opencollective.com/express"
|
| 1205 |
+
}
|
| 1206 |
+
},
|
| 1207 |
+
"node_modules/multer/node_modules/media-typer": {
|
| 1208 |
+
"version": "0.3.0",
|
| 1209 |
+
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
| 1210 |
+
"integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
|
| 1211 |
+
"license": "MIT",
|
| 1212 |
+
"engines": {
|
| 1213 |
+
"node": ">= 0.6"
|
| 1214 |
+
}
|
| 1215 |
+
},
|
| 1216 |
+
"node_modules/multer/node_modules/mime-db": {
|
| 1217 |
+
"version": "1.52.0",
|
| 1218 |
+
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
| 1219 |
+
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
| 1220 |
+
"license": "MIT",
|
| 1221 |
+
"engines": {
|
| 1222 |
+
"node": ">= 0.6"
|
| 1223 |
+
}
|
| 1224 |
+
},
|
| 1225 |
+
"node_modules/multer/node_modules/mime-types": {
|
| 1226 |
+
"version": "2.1.35",
|
| 1227 |
+
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
| 1228 |
+
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
| 1229 |
+
"license": "MIT",
|
| 1230 |
+
"dependencies": {
|
| 1231 |
+
"mime-db": "1.52.0"
|
| 1232 |
+
},
|
| 1233 |
+
"engines": {
|
| 1234 |
+
"node": ">= 0.6"
|
| 1235 |
+
}
|
| 1236 |
+
},
|
| 1237 |
+
"node_modules/multer/node_modules/type-is": {
|
| 1238 |
+
"version": "1.6.18",
|
| 1239 |
+
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
| 1240 |
+
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
|
| 1241 |
+
"license": "MIT",
|
| 1242 |
+
"dependencies": {
|
| 1243 |
+
"media-typer": "0.3.0",
|
| 1244 |
+
"mime-types": "~2.1.24"
|
| 1245 |
+
},
|
| 1246 |
+
"engines": {
|
| 1247 |
+
"node": ">= 0.6"
|
| 1248 |
+
}
|
| 1249 |
+
},
|
| 1250 |
+
"node_modules/napi-build-utils": {
|
| 1251 |
+
"version": "2.0.0",
|
| 1252 |
+
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
|
| 1253 |
+
"integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
|
| 1254 |
+
"license": "MIT"
|
| 1255 |
+
},
|
| 1256 |
+
"node_modules/negotiator": {
|
| 1257 |
+
"version": "1.0.0",
|
| 1258 |
+
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
|
| 1259 |
+
"integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
|
| 1260 |
+
"license": "MIT",
|
| 1261 |
+
"engines": {
|
| 1262 |
+
"node": ">= 0.6"
|
| 1263 |
+
}
|
| 1264 |
+
},
|
| 1265 |
+
"node_modules/node-abi": {
|
| 1266 |
+
"version": "3.92.0",
|
| 1267 |
+
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.92.0.tgz",
|
| 1268 |
+
"integrity": "sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ==",
|
| 1269 |
+
"license": "MIT",
|
| 1270 |
+
"dependencies": {
|
| 1271 |
+
"semver": "^7.3.5"
|
| 1272 |
+
},
|
| 1273 |
+
"engines": {
|
| 1274 |
+
"node": ">=10"
|
| 1275 |
+
}
|
| 1276 |
+
},
|
| 1277 |
+
"node_modules/node-addon-api": {
|
| 1278 |
+
"version": "6.1.0",
|
| 1279 |
+
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz",
|
| 1280 |
+
"integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==",
|
| 1281 |
+
"license": "MIT"
|
| 1282 |
+
},
|
| 1283 |
+
"node_modules/object-inspect": {
|
| 1284 |
+
"version": "1.13.4",
|
| 1285 |
+
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
|
| 1286 |
+
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
|
| 1287 |
+
"license": "MIT",
|
| 1288 |
+
"engines": {
|
| 1289 |
+
"node": ">= 0.4"
|
| 1290 |
+
},
|
| 1291 |
+
"funding": {
|
| 1292 |
+
"url": "https://github.com/sponsors/ljharb"
|
| 1293 |
+
}
|
| 1294 |
+
},
|
| 1295 |
+
"node_modules/on-finished": {
|
| 1296 |
+
"version": "2.4.1",
|
| 1297 |
+
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
| 1298 |
+
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
|
| 1299 |
+
"license": "MIT",
|
| 1300 |
+
"dependencies": {
|
| 1301 |
+
"ee-first": "1.1.1"
|
| 1302 |
+
},
|
| 1303 |
+
"engines": {
|
| 1304 |
+
"node": ">= 0.8"
|
| 1305 |
+
}
|
| 1306 |
+
},
|
| 1307 |
+
"node_modules/on-headers": {
|
| 1308 |
+
"version": "1.1.0",
|
| 1309 |
+
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz",
|
| 1310 |
+
"integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==",
|
| 1311 |
+
"license": "MIT",
|
| 1312 |
+
"engines": {
|
| 1313 |
+
"node": ">= 0.8"
|
| 1314 |
+
}
|
| 1315 |
+
},
|
| 1316 |
+
"node_modules/once": {
|
| 1317 |
+
"version": "1.4.0",
|
| 1318 |
+
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
| 1319 |
+
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
| 1320 |
+
"license": "ISC",
|
| 1321 |
+
"dependencies": {
|
| 1322 |
+
"wrappy": "1"
|
| 1323 |
+
}
|
| 1324 |
+
},
|
| 1325 |
+
"node_modules/onnx-proto": {
|
| 1326 |
+
"version": "4.0.4",
|
| 1327 |
+
"resolved": "https://registry.npmjs.org/onnx-proto/-/onnx-proto-4.0.4.tgz",
|
| 1328 |
+
"integrity": "sha512-aldMOB3HRoo6q/phyB6QRQxSt895HNNw82BNyZ2CMh4bjeKv7g/c+VpAFtJuEMVfYLMbRx61hbuqnKceLeDcDA==",
|
| 1329 |
+
"license": "MIT",
|
| 1330 |
+
"dependencies": {
|
| 1331 |
+
"protobufjs": "^6.8.8"
|
| 1332 |
+
}
|
| 1333 |
+
},
|
| 1334 |
+
"node_modules/onnxruntime-common": {
|
| 1335 |
+
"version": "1.14.0",
|
| 1336 |
+
"resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.14.0.tgz",
|
| 1337 |
+
"integrity": "sha512-3LJpegM2iMNRX2wUmtYfeX/ytfOzNwAWKSq1HbRrKc9+uqG/FsEA0bbKZl1btQeZaXhC26l44NWpNUeXPII7Ew==",
|
| 1338 |
+
"license": "MIT"
|
| 1339 |
+
},
|
| 1340 |
+
"node_modules/onnxruntime-node": {
|
| 1341 |
+
"version": "1.14.0",
|
| 1342 |
+
"resolved": "https://registry.npmjs.org/onnxruntime-node/-/onnxruntime-node-1.14.0.tgz",
|
| 1343 |
+
"integrity": "sha512-5ba7TWomIV/9b6NH/1x/8QEeowsb+jBEvFzU6z0T4mNsFwdPqXeFUM7uxC6QeSRkEbWu3qEB0VMjrvzN/0S9+w==",
|
| 1344 |
+
"license": "MIT",
|
| 1345 |
+
"optional": true,
|
| 1346 |
+
"os": [
|
| 1347 |
+
"win32",
|
| 1348 |
+
"darwin",
|
| 1349 |
+
"linux"
|
| 1350 |
+
],
|
| 1351 |
+
"dependencies": {
|
| 1352 |
+
"onnxruntime-common": "~1.14.0"
|
| 1353 |
+
}
|
| 1354 |
+
},
|
| 1355 |
+
"node_modules/onnxruntime-web": {
|
| 1356 |
+
"version": "1.14.0",
|
| 1357 |
+
"resolved": "https://registry.npmjs.org/onnxruntime-web/-/onnxruntime-web-1.14.0.tgz",
|
| 1358 |
+
"integrity": "sha512-Kcqf43UMfW8mCydVGcX9OMXI2VN17c0p6XvR7IPSZzBf/6lteBzXHvcEVWDPmCKuGombl997HgLqj91F11DzXw==",
|
| 1359 |
+
"license": "MIT",
|
| 1360 |
+
"dependencies": {
|
| 1361 |
+
"flatbuffers": "^1.12.0",
|
| 1362 |
+
"guid-typescript": "^1.0.9",
|
| 1363 |
+
"long": "^4.0.0",
|
| 1364 |
+
"onnx-proto": "^4.0.4",
|
| 1365 |
+
"onnxruntime-common": "~1.14.0",
|
| 1366 |
+
"platform": "^1.3.6"
|
| 1367 |
+
}
|
| 1368 |
+
},
|
| 1369 |
+
"node_modules/parse-cache-control": {
|
| 1370 |
+
"version": "1.0.1",
|
| 1371 |
+
"resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz",
|
| 1372 |
+
"integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg=="
|
| 1373 |
+
},
|
| 1374 |
+
"node_modules/parseurl": {
|
| 1375 |
+
"version": "1.3.3",
|
| 1376 |
+
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
| 1377 |
+
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
|
| 1378 |
+
"license": "MIT",
|
| 1379 |
+
"engines": {
|
| 1380 |
+
"node": ">= 0.8"
|
| 1381 |
+
}
|
| 1382 |
+
},
|
| 1383 |
+
"node_modules/path-to-regexp": {
|
| 1384 |
+
"version": "8.4.2",
|
| 1385 |
+
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz",
|
| 1386 |
+
"integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==",
|
| 1387 |
+
"license": "MIT",
|
| 1388 |
+
"funding": {
|
| 1389 |
+
"type": "opencollective",
|
| 1390 |
+
"url": "https://opencollective.com/express"
|
| 1391 |
+
}
|
| 1392 |
+
},
|
| 1393 |
+
"node_modules/platform": {
|
| 1394 |
+
"version": "1.3.6",
|
| 1395 |
+
"resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz",
|
| 1396 |
+
"integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==",
|
| 1397 |
+
"license": "MIT"
|
| 1398 |
+
},
|
| 1399 |
+
"node_modules/prebuild-install": {
|
| 1400 |
+
"version": "7.1.3",
|
| 1401 |
+
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
|
| 1402 |
+
"integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
|
| 1403 |
+
"deprecated": "No longer maintained. Please contact the author of the relevant native addon; alternatives are available.",
|
| 1404 |
+
"license": "MIT",
|
| 1405 |
+
"dependencies": {
|
| 1406 |
+
"detect-libc": "^2.0.0",
|
| 1407 |
+
"expand-template": "^2.0.3",
|
| 1408 |
+
"github-from-package": "0.0.0",
|
| 1409 |
+
"minimist": "^1.2.3",
|
| 1410 |
+
"mkdirp-classic": "^0.5.3",
|
| 1411 |
+
"napi-build-utils": "^2.0.0",
|
| 1412 |
+
"node-abi": "^3.3.0",
|
| 1413 |
+
"pump": "^3.0.0",
|
| 1414 |
+
"rc": "^1.2.7",
|
| 1415 |
+
"simple-get": "^4.0.0",
|
| 1416 |
+
"tar-fs": "^2.0.0",
|
| 1417 |
+
"tunnel-agent": "^0.6.0"
|
| 1418 |
+
},
|
| 1419 |
+
"bin": {
|
| 1420 |
+
"prebuild-install": "bin.js"
|
| 1421 |
+
},
|
| 1422 |
+
"engines": {
|
| 1423 |
+
"node": ">=10"
|
| 1424 |
+
}
|
| 1425 |
+
},
|
| 1426 |
+
"node_modules/prebuild-install/node_modules/tar-fs": {
|
| 1427 |
+
"version": "2.1.4",
|
| 1428 |
+
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz",
|
| 1429 |
+
"integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==",
|
| 1430 |
+
"license": "MIT",
|
| 1431 |
+
"dependencies": {
|
| 1432 |
+
"chownr": "^1.1.1",
|
| 1433 |
+
"mkdirp-classic": "^0.5.2",
|
| 1434 |
+
"pump": "^3.0.0",
|
| 1435 |
+
"tar-stream": "^2.1.4"
|
| 1436 |
+
}
|
| 1437 |
+
},
|
| 1438 |
+
"node_modules/prebuild-install/node_modules/tar-stream": {
|
| 1439 |
+
"version": "2.2.0",
|
| 1440 |
+
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
|
| 1441 |
+
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
|
| 1442 |
+
"license": "MIT",
|
| 1443 |
+
"dependencies": {
|
| 1444 |
+
"bl": "^4.0.3",
|
| 1445 |
+
"end-of-stream": "^1.4.1",
|
| 1446 |
+
"fs-constants": "^1.0.0",
|
| 1447 |
+
"inherits": "^2.0.3",
|
| 1448 |
+
"readable-stream": "^3.1.1"
|
| 1449 |
+
},
|
| 1450 |
+
"engines": {
|
| 1451 |
+
"node": ">=6"
|
| 1452 |
+
}
|
| 1453 |
+
},
|
| 1454 |
+
"node_modules/progress": {
|
| 1455 |
+
"version": "2.0.3",
|
| 1456 |
+
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
|
| 1457 |
+
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
|
| 1458 |
+
"license": "MIT",
|
| 1459 |
+
"engines": {
|
| 1460 |
+
"node": ">=0.4.0"
|
| 1461 |
+
}
|
| 1462 |
+
},
|
| 1463 |
+
"node_modules/protobufjs": {
|
| 1464 |
+
"version": "6.11.6",
|
| 1465 |
+
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.6.tgz",
|
| 1466 |
+
"integrity": "sha512-k8BHqgPBOtrlougZZqF2uUk5Z7bN8f0wj+3e8M3hvtSv0NBAz4VBy5f6R5Nxq/l+i7mRFTgNZb2trxqTpHNY/A==",
|
| 1467 |
+
"hasInstallScript": true,
|
| 1468 |
+
"license": "BSD-3-Clause",
|
| 1469 |
+
"dependencies": {
|
| 1470 |
+
"@protobufjs/aspromise": "^1.1.2",
|
| 1471 |
+
"@protobufjs/base64": "^1.1.2",
|
| 1472 |
+
"@protobufjs/codegen": "^2.0.4",
|
| 1473 |
+
"@protobufjs/eventemitter": "^1.1.0",
|
| 1474 |
+
"@protobufjs/fetch": "^1.1.0",
|
| 1475 |
+
"@protobufjs/float": "^1.0.2",
|
| 1476 |
+
"@protobufjs/inquire": "^1.1.0",
|
| 1477 |
+
"@protobufjs/path": "^1.1.2",
|
| 1478 |
+
"@protobufjs/pool": "^1.1.0",
|
| 1479 |
+
"@protobufjs/utf8": "^1.1.0",
|
| 1480 |
+
"@types/long": "^4.0.1",
|
| 1481 |
+
"@types/node": ">=13.7.0",
|
| 1482 |
+
"long": "^4.0.0"
|
| 1483 |
+
},
|
| 1484 |
+
"bin": {
|
| 1485 |
+
"pbjs": "bin/pbjs",
|
| 1486 |
+
"pbts": "bin/pbts"
|
| 1487 |
+
}
|
| 1488 |
+
},
|
| 1489 |
+
"node_modules/protobufjs/node_modules/@types/node": {
|
| 1490 |
+
"version": "25.9.1",
|
| 1491 |
+
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.1.tgz",
|
| 1492 |
+
"integrity": "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==",
|
| 1493 |
+
"license": "MIT",
|
| 1494 |
+
"dependencies": {
|
| 1495 |
+
"undici-types": ">=7.24.0 <7.24.7"
|
| 1496 |
+
}
|
| 1497 |
+
},
|
| 1498 |
+
"node_modules/proxy-addr": {
|
| 1499 |
+
"version": "2.0.7",
|
| 1500 |
+
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
| 1501 |
+
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
|
| 1502 |
+
"license": "MIT",
|
| 1503 |
+
"dependencies": {
|
| 1504 |
+
"forwarded": "0.2.0",
|
| 1505 |
+
"ipaddr.js": "1.9.1"
|
| 1506 |
+
},
|
| 1507 |
+
"engines": {
|
| 1508 |
+
"node": ">= 0.10"
|
| 1509 |
+
}
|
| 1510 |
+
},
|
| 1511 |
+
"node_modules/pump": {
|
| 1512 |
+
"version": "3.0.4",
|
| 1513 |
+
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz",
|
| 1514 |
+
"integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==",
|
| 1515 |
+
"license": "MIT",
|
| 1516 |
+
"dependencies": {
|
| 1517 |
+
"end-of-stream": "^1.1.0",
|
| 1518 |
+
"once": "^1.3.1"
|
| 1519 |
+
}
|
| 1520 |
+
},
|
| 1521 |
+
"node_modules/qs": {
|
| 1522 |
+
"version": "6.15.2",
|
| 1523 |
+
"resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz",
|
| 1524 |
+
"integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==",
|
| 1525 |
+
"license": "BSD-3-Clause",
|
| 1526 |
+
"dependencies": {
|
| 1527 |
+
"side-channel": "^1.1.0"
|
| 1528 |
+
},
|
| 1529 |
+
"engines": {
|
| 1530 |
+
"node": ">=0.6"
|
| 1531 |
+
},
|
| 1532 |
+
"funding": {
|
| 1533 |
+
"url": "https://github.com/sponsors/ljharb"
|
| 1534 |
+
}
|
| 1535 |
+
},
|
| 1536 |
+
"node_modules/range-parser": {
|
| 1537 |
+
"version": "1.2.1",
|
| 1538 |
+
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
| 1539 |
+
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
|
| 1540 |
+
"license": "MIT",
|
| 1541 |
+
"engines": {
|
| 1542 |
+
"node": ">= 0.6"
|
| 1543 |
+
}
|
| 1544 |
+
},
|
| 1545 |
+
"node_modules/raw-body": {
|
| 1546 |
+
"version": "3.0.2",
|
| 1547 |
+
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz",
|
| 1548 |
+
"integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==",
|
| 1549 |
+
"license": "MIT",
|
| 1550 |
+
"dependencies": {
|
| 1551 |
+
"bytes": "~3.1.2",
|
| 1552 |
+
"http-errors": "~2.0.1",
|
| 1553 |
+
"iconv-lite": "~0.7.0",
|
| 1554 |
+
"unpipe": "~1.0.0"
|
| 1555 |
+
},
|
| 1556 |
+
"engines": {
|
| 1557 |
+
"node": ">= 0.10"
|
| 1558 |
+
}
|
| 1559 |
+
},
|
| 1560 |
+
"node_modules/rc": {
|
| 1561 |
+
"version": "1.2.8",
|
| 1562 |
+
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
|
| 1563 |
+
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
|
| 1564 |
+
"license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
|
| 1565 |
+
"dependencies": {
|
| 1566 |
+
"deep-extend": "^0.6.0",
|
| 1567 |
+
"ini": "~1.3.0",
|
| 1568 |
+
"minimist": "^1.2.0",
|
| 1569 |
+
"strip-json-comments": "~2.0.1"
|
| 1570 |
+
},
|
| 1571 |
+
"bin": {
|
| 1572 |
+
"rc": "cli.js"
|
| 1573 |
+
}
|
| 1574 |
+
},
|
| 1575 |
+
"node_modules/readable-stream": {
|
| 1576 |
+
"version": "3.6.2",
|
| 1577 |
+
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
| 1578 |
+
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
| 1579 |
+
"license": "MIT",
|
| 1580 |
+
"dependencies": {
|
| 1581 |
+
"inherits": "^2.0.3",
|
| 1582 |
+
"string_decoder": "^1.1.1",
|
| 1583 |
+
"util-deprecate": "^1.0.1"
|
| 1584 |
+
},
|
| 1585 |
+
"engines": {
|
| 1586 |
+
"node": ">= 6"
|
| 1587 |
+
}
|
| 1588 |
+
},
|
| 1589 |
+
"node_modules/router": {
|
| 1590 |
+
"version": "2.2.0",
|
| 1591 |
+
"resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
|
| 1592 |
+
"integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
|
| 1593 |
+
"license": "MIT",
|
| 1594 |
+
"dependencies": {
|
| 1595 |
+
"debug": "^4.4.0",
|
| 1596 |
+
"depd": "^2.0.0",
|
| 1597 |
+
"is-promise": "^4.0.0",
|
| 1598 |
+
"parseurl": "^1.3.3",
|
| 1599 |
+
"path-to-regexp": "^8.0.0"
|
| 1600 |
+
},
|
| 1601 |
+
"engines": {
|
| 1602 |
+
"node": ">= 18"
|
| 1603 |
+
}
|
| 1604 |
+
},
|
| 1605 |
+
"node_modules/safe-buffer": {
|
| 1606 |
+
"version": "5.2.1",
|
| 1607 |
+
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
| 1608 |
+
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
| 1609 |
+
"funding": [
|
| 1610 |
+
{
|
| 1611 |
+
"type": "github",
|
| 1612 |
+
"url": "https://github.com/sponsors/feross"
|
| 1613 |
+
},
|
| 1614 |
+
{
|
| 1615 |
+
"type": "patreon",
|
| 1616 |
+
"url": "https://www.patreon.com/feross"
|
| 1617 |
+
},
|
| 1618 |
+
{
|
| 1619 |
+
"type": "consulting",
|
| 1620 |
+
"url": "https://feross.org/support"
|
| 1621 |
+
}
|
| 1622 |
+
],
|
| 1623 |
+
"license": "MIT"
|
| 1624 |
+
},
|
| 1625 |
+
"node_modules/safer-buffer": {
|
| 1626 |
+
"version": "2.1.2",
|
| 1627 |
+
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
| 1628 |
+
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
| 1629 |
+
"license": "MIT"
|
| 1630 |
+
},
|
| 1631 |
+
"node_modules/semver": {
|
| 1632 |
+
"version": "7.8.1",
|
| 1633 |
+
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz",
|
| 1634 |
+
"integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==",
|
| 1635 |
+
"license": "ISC",
|
| 1636 |
+
"bin": {
|
| 1637 |
+
"semver": "bin/semver.js"
|
| 1638 |
+
},
|
| 1639 |
+
"engines": {
|
| 1640 |
+
"node": ">=10"
|
| 1641 |
+
}
|
| 1642 |
+
},
|
| 1643 |
+
"node_modules/send": {
|
| 1644 |
+
"version": "1.2.1",
|
| 1645 |
+
"resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
|
| 1646 |
+
"integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==",
|
| 1647 |
+
"license": "MIT",
|
| 1648 |
+
"dependencies": {
|
| 1649 |
+
"debug": "^4.4.3",
|
| 1650 |
+
"encodeurl": "^2.0.0",
|
| 1651 |
+
"escape-html": "^1.0.3",
|
| 1652 |
+
"etag": "^1.8.1",
|
| 1653 |
+
"fresh": "^2.0.0",
|
| 1654 |
+
"http-errors": "^2.0.1",
|
| 1655 |
+
"mime-types": "^3.0.2",
|
| 1656 |
+
"ms": "^2.1.3",
|
| 1657 |
+
"on-finished": "^2.4.1",
|
| 1658 |
+
"range-parser": "^1.2.1",
|
| 1659 |
+
"statuses": "^2.0.2"
|
| 1660 |
+
},
|
| 1661 |
+
"engines": {
|
| 1662 |
+
"node": ">= 18"
|
| 1663 |
+
},
|
| 1664 |
+
"funding": {
|
| 1665 |
+
"type": "opencollective",
|
| 1666 |
+
"url": "https://opencollective.com/express"
|
| 1667 |
+
}
|
| 1668 |
+
},
|
| 1669 |
+
"node_modules/serve-static": {
|
| 1670 |
+
"version": "2.2.1",
|
| 1671 |
+
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz",
|
| 1672 |
+
"integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==",
|
| 1673 |
+
"license": "MIT",
|
| 1674 |
+
"dependencies": {
|
| 1675 |
+
"encodeurl": "^2.0.0",
|
| 1676 |
+
"escape-html": "^1.0.3",
|
| 1677 |
+
"parseurl": "^1.3.3",
|
| 1678 |
+
"send": "^1.2.0"
|
| 1679 |
+
},
|
| 1680 |
+
"engines": {
|
| 1681 |
+
"node": ">= 18"
|
| 1682 |
+
},
|
| 1683 |
+
"funding": {
|
| 1684 |
+
"type": "opencollective",
|
| 1685 |
+
"url": "https://opencollective.com/express"
|
| 1686 |
+
}
|
| 1687 |
+
},
|
| 1688 |
+
"node_modules/setprototypeof": {
|
| 1689 |
+
"version": "1.2.0",
|
| 1690 |
+
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
| 1691 |
+
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
| 1692 |
+
"license": "ISC"
|
| 1693 |
+
},
|
| 1694 |
+
"node_modules/sharp": {
|
| 1695 |
+
"version": "0.32.6",
|
| 1696 |
+
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz",
|
| 1697 |
+
"integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==",
|
| 1698 |
+
"hasInstallScript": true,
|
| 1699 |
+
"license": "Apache-2.0",
|
| 1700 |
+
"dependencies": {
|
| 1701 |
+
"color": "^4.2.3",
|
| 1702 |
+
"detect-libc": "^2.0.2",
|
| 1703 |
+
"node-addon-api": "^6.1.0",
|
| 1704 |
+
"prebuild-install": "^7.1.1",
|
| 1705 |
+
"semver": "^7.5.4",
|
| 1706 |
+
"simple-get": "^4.0.1",
|
| 1707 |
+
"tar-fs": "^3.0.4",
|
| 1708 |
+
"tunnel-agent": "^0.6.0"
|
| 1709 |
+
},
|
| 1710 |
+
"engines": {
|
| 1711 |
+
"node": ">=14.15.0"
|
| 1712 |
+
},
|
| 1713 |
+
"funding": {
|
| 1714 |
+
"url": "https://opencollective.com/libvips"
|
| 1715 |
+
}
|
| 1716 |
+
},
|
| 1717 |
+
"node_modules/side-channel": {
|
| 1718 |
+
"version": "1.1.0",
|
| 1719 |
+
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
|
| 1720 |
+
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
|
| 1721 |
+
"license": "MIT",
|
| 1722 |
+
"dependencies": {
|
| 1723 |
+
"es-errors": "^1.3.0",
|
| 1724 |
+
"object-inspect": "^1.13.3",
|
| 1725 |
+
"side-channel-list": "^1.0.0",
|
| 1726 |
+
"side-channel-map": "^1.0.1",
|
| 1727 |
+
"side-channel-weakmap": "^1.0.2"
|
| 1728 |
+
},
|
| 1729 |
+
"engines": {
|
| 1730 |
+
"node": ">= 0.4"
|
| 1731 |
+
},
|
| 1732 |
+
"funding": {
|
| 1733 |
+
"url": "https://github.com/sponsors/ljharb"
|
| 1734 |
+
}
|
| 1735 |
+
},
|
| 1736 |
+
"node_modules/side-channel-list": {
|
| 1737 |
+
"version": "1.0.1",
|
| 1738 |
+
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz",
|
| 1739 |
+
"integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==",
|
| 1740 |
+
"license": "MIT",
|
| 1741 |
+
"dependencies": {
|
| 1742 |
+
"es-errors": "^1.3.0",
|
| 1743 |
+
"object-inspect": "^1.13.4"
|
| 1744 |
+
},
|
| 1745 |
+
"engines": {
|
| 1746 |
+
"node": ">= 0.4"
|
| 1747 |
+
},
|
| 1748 |
+
"funding": {
|
| 1749 |
+
"url": "https://github.com/sponsors/ljharb"
|
| 1750 |
+
}
|
| 1751 |
+
},
|
| 1752 |
+
"node_modules/side-channel-map": {
|
| 1753 |
+
"version": "1.0.1",
|
| 1754 |
+
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
|
| 1755 |
+
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
|
| 1756 |
+
"license": "MIT",
|
| 1757 |
+
"dependencies": {
|
| 1758 |
+
"call-bound": "^1.0.2",
|
| 1759 |
+
"es-errors": "^1.3.0",
|
| 1760 |
+
"get-intrinsic": "^1.2.5",
|
| 1761 |
+
"object-inspect": "^1.13.3"
|
| 1762 |
+
},
|
| 1763 |
+
"engines": {
|
| 1764 |
+
"node": ">= 0.4"
|
| 1765 |
+
},
|
| 1766 |
+
"funding": {
|
| 1767 |
+
"url": "https://github.com/sponsors/ljharb"
|
| 1768 |
+
}
|
| 1769 |
+
},
|
| 1770 |
+
"node_modules/side-channel-weakmap": {
|
| 1771 |
+
"version": "1.0.2",
|
| 1772 |
+
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
|
| 1773 |
+
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
|
| 1774 |
+
"license": "MIT",
|
| 1775 |
+
"dependencies": {
|
| 1776 |
+
"call-bound": "^1.0.2",
|
| 1777 |
+
"es-errors": "^1.3.0",
|
| 1778 |
+
"get-intrinsic": "^1.2.5",
|
| 1779 |
+
"object-inspect": "^1.13.3",
|
| 1780 |
+
"side-channel-map": "^1.0.1"
|
| 1781 |
+
},
|
| 1782 |
+
"engines": {
|
| 1783 |
+
"node": ">= 0.4"
|
| 1784 |
+
},
|
| 1785 |
+
"funding": {
|
| 1786 |
+
"url": "https://github.com/sponsors/ljharb"
|
| 1787 |
+
}
|
| 1788 |
+
},
|
| 1789 |
+
"node_modules/simple-concat": {
|
| 1790 |
+
"version": "1.0.1",
|
| 1791 |
+
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
|
| 1792 |
+
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
|
| 1793 |
+
"funding": [
|
| 1794 |
+
{
|
| 1795 |
+
"type": "github",
|
| 1796 |
+
"url": "https://github.com/sponsors/feross"
|
| 1797 |
+
},
|
| 1798 |
+
{
|
| 1799 |
+
"type": "patreon",
|
| 1800 |
+
"url": "https://www.patreon.com/feross"
|
| 1801 |
+
},
|
| 1802 |
+
{
|
| 1803 |
+
"type": "consulting",
|
| 1804 |
+
"url": "https://feross.org/support"
|
| 1805 |
+
}
|
| 1806 |
+
],
|
| 1807 |
+
"license": "MIT"
|
| 1808 |
+
},
|
| 1809 |
+
"node_modules/simple-get": {
|
| 1810 |
+
"version": "4.0.1",
|
| 1811 |
+
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
|
| 1812 |
+
"integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
|
| 1813 |
+
"funding": [
|
| 1814 |
+
{
|
| 1815 |
+
"type": "github",
|
| 1816 |
+
"url": "https://github.com/sponsors/feross"
|
| 1817 |
+
},
|
| 1818 |
+
{
|
| 1819 |
+
"type": "patreon",
|
| 1820 |
+
"url": "https://www.patreon.com/feross"
|
| 1821 |
+
},
|
| 1822 |
+
{
|
| 1823 |
+
"type": "consulting",
|
| 1824 |
+
"url": "https://feross.org/support"
|
| 1825 |
+
}
|
| 1826 |
+
],
|
| 1827 |
+
"license": "MIT",
|
| 1828 |
+
"dependencies": {
|
| 1829 |
+
"decompress-response": "^6.0.0",
|
| 1830 |
+
"once": "^1.3.1",
|
| 1831 |
+
"simple-concat": "^1.0.0"
|
| 1832 |
+
}
|
| 1833 |
+
},
|
| 1834 |
+
"node_modules/simple-swizzle": {
|
| 1835 |
+
"version": "0.2.4",
|
| 1836 |
+
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz",
|
| 1837 |
+
"integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==",
|
| 1838 |
+
"license": "MIT",
|
| 1839 |
+
"dependencies": {
|
| 1840 |
+
"is-arrayish": "^0.3.1"
|
| 1841 |
+
}
|
| 1842 |
+
},
|
| 1843 |
+
"node_modules/statuses": {
|
| 1844 |
+
"version": "2.0.2",
|
| 1845 |
+
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
| 1846 |
+
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
|
| 1847 |
+
"license": "MIT",
|
| 1848 |
+
"engines": {
|
| 1849 |
+
"node": ">= 0.8"
|
| 1850 |
+
}
|
| 1851 |
+
},
|
| 1852 |
+
"node_modules/streamsearch": {
|
| 1853 |
+
"version": "1.1.0",
|
| 1854 |
+
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
|
| 1855 |
+
"integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
|
| 1856 |
+
"engines": {
|
| 1857 |
+
"node": ">=10.0.0"
|
| 1858 |
+
}
|
| 1859 |
+
},
|
| 1860 |
+
"node_modules/streamx": {
|
| 1861 |
+
"version": "2.26.0",
|
| 1862 |
+
"resolved": "https://registry.npmjs.org/streamx/-/streamx-2.26.0.tgz",
|
| 1863 |
+
"integrity": "sha512-VvNG1K72Po/xwJzxZFnZ++Tbrv4lwSptsbkFuzXCJAYZvCK5nnxsvXU6ajqkv7chyiI1Y0YXq2Jh8Iy8Y7NF/A==",
|
| 1864 |
+
"license": "MIT",
|
| 1865 |
+
"dependencies": {
|
| 1866 |
+
"events-universal": "^1.0.0",
|
| 1867 |
+
"fast-fifo": "^1.3.2",
|
| 1868 |
+
"text-decoder": "^1.1.0"
|
| 1869 |
+
}
|
| 1870 |
+
},
|
| 1871 |
+
"node_modules/string_decoder": {
|
| 1872 |
+
"version": "1.3.0",
|
| 1873 |
+
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
| 1874 |
+
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
| 1875 |
+
"license": "MIT",
|
| 1876 |
+
"dependencies": {
|
| 1877 |
+
"safe-buffer": "~5.2.0"
|
| 1878 |
+
}
|
| 1879 |
+
},
|
| 1880 |
+
"node_modules/strip-json-comments": {
|
| 1881 |
+
"version": "2.0.1",
|
| 1882 |
+
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
|
| 1883 |
+
"integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
|
| 1884 |
+
"license": "MIT",
|
| 1885 |
+
"engines": {
|
| 1886 |
+
"node": ">=0.10.0"
|
| 1887 |
+
}
|
| 1888 |
+
},
|
| 1889 |
+
"node_modules/tar-fs": {
|
| 1890 |
+
"version": "3.1.2",
|
| 1891 |
+
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.2.tgz",
|
| 1892 |
+
"integrity": "sha512-QGxxTxxyleAdyM3kpFs14ymbYmNFrfY+pHj7Z8FgtbZ7w2//VAgLMac7sT6nRpIHjppXO2AwwEOg0bPFVRcmXw==",
|
| 1893 |
+
"license": "MIT",
|
| 1894 |
+
"dependencies": {
|
| 1895 |
+
"pump": "^3.0.0",
|
| 1896 |
+
"tar-stream": "^3.1.5"
|
| 1897 |
+
},
|
| 1898 |
+
"optionalDependencies": {
|
| 1899 |
+
"bare-fs": "^4.0.1",
|
| 1900 |
+
"bare-path": "^3.0.0"
|
| 1901 |
+
}
|
| 1902 |
+
},
|
| 1903 |
+
"node_modules/tar-stream": {
|
| 1904 |
+
"version": "3.2.0",
|
| 1905 |
+
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.2.0.tgz",
|
| 1906 |
+
"integrity": "sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==",
|
| 1907 |
+
"license": "MIT",
|
| 1908 |
+
"dependencies": {
|
| 1909 |
+
"b4a": "^1.6.4",
|
| 1910 |
+
"bare-fs": "^4.5.5",
|
| 1911 |
+
"fast-fifo": "^1.2.0",
|
| 1912 |
+
"streamx": "^2.15.0"
|
| 1913 |
+
}
|
| 1914 |
+
},
|
| 1915 |
+
"node_modules/teex": {
|
| 1916 |
+
"version": "1.0.1",
|
| 1917 |
+
"resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz",
|
| 1918 |
+
"integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==",
|
| 1919 |
+
"license": "MIT",
|
| 1920 |
+
"dependencies": {
|
| 1921 |
+
"streamx": "^2.12.5"
|
| 1922 |
+
}
|
| 1923 |
+
},
|
| 1924 |
+
"node_modules/text-decoder": {
|
| 1925 |
+
"version": "1.2.7",
|
| 1926 |
+
"resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz",
|
| 1927 |
+
"integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==",
|
| 1928 |
+
"license": "Apache-2.0",
|
| 1929 |
+
"dependencies": {
|
| 1930 |
+
"b4a": "^1.6.4"
|
| 1931 |
+
}
|
| 1932 |
+
},
|
| 1933 |
+
"node_modules/toidentifier": {
|
| 1934 |
+
"version": "1.0.1",
|
| 1935 |
+
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
| 1936 |
+
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
|
| 1937 |
+
"license": "MIT",
|
| 1938 |
+
"engines": {
|
| 1939 |
+
"node": ">=0.6"
|
| 1940 |
+
}
|
| 1941 |
+
},
|
| 1942 |
+
"node_modules/tunnel-agent": {
|
| 1943 |
+
"version": "0.6.0",
|
| 1944 |
+
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
| 1945 |
+
"integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
|
| 1946 |
+
"license": "Apache-2.0",
|
| 1947 |
+
"dependencies": {
|
| 1948 |
+
"safe-buffer": "^5.0.1"
|
| 1949 |
+
},
|
| 1950 |
+
"engines": {
|
| 1951 |
+
"node": "*"
|
| 1952 |
+
}
|
| 1953 |
+
},
|
| 1954 |
+
"node_modules/type-is": {
|
| 1955 |
+
"version": "2.1.0",
|
| 1956 |
+
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz",
|
| 1957 |
+
"integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==",
|
| 1958 |
+
"license": "MIT",
|
| 1959 |
+
"dependencies": {
|
| 1960 |
+
"content-type": "^2.0.0",
|
| 1961 |
+
"media-typer": "^1.1.0",
|
| 1962 |
+
"mime-types": "^3.0.0"
|
| 1963 |
+
},
|
| 1964 |
+
"engines": {
|
| 1965 |
+
"node": ">= 18"
|
| 1966 |
+
},
|
| 1967 |
+
"funding": {
|
| 1968 |
+
"type": "opencollective",
|
| 1969 |
+
"url": "https://opencollective.com/express"
|
| 1970 |
+
}
|
| 1971 |
+
},
|
| 1972 |
+
"node_modules/type-is/node_modules/content-type": {
|
| 1973 |
+
"version": "2.0.0",
|
| 1974 |
+
"resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz",
|
| 1975 |
+
"integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==",
|
| 1976 |
+
"license": "MIT",
|
| 1977 |
+
"engines": {
|
| 1978 |
+
"node": ">=18"
|
| 1979 |
+
},
|
| 1980 |
+
"funding": {
|
| 1981 |
+
"type": "opencollective",
|
| 1982 |
+
"url": "https://opencollective.com/express"
|
| 1983 |
+
}
|
| 1984 |
+
},
|
| 1985 |
+
"node_modules/typedarray": {
|
| 1986 |
+
"version": "0.0.6",
|
| 1987 |
+
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
| 1988 |
+
"integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
|
| 1989 |
+
"license": "MIT"
|
| 1990 |
+
},
|
| 1991 |
+
"node_modules/undici-types": {
|
| 1992 |
+
"version": "7.24.6",
|
| 1993 |
+
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
|
| 1994 |
+
"integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==",
|
| 1995 |
+
"license": "MIT"
|
| 1996 |
+
},
|
| 1997 |
+
"node_modules/unpipe": {
|
| 1998 |
+
"version": "1.0.0",
|
| 1999 |
+
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
| 2000 |
+
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
|
| 2001 |
+
"license": "MIT",
|
| 2002 |
+
"engines": {
|
| 2003 |
+
"node": ">= 0.8"
|
| 2004 |
+
}
|
| 2005 |
+
},
|
| 2006 |
+
"node_modules/util-deprecate": {
|
| 2007 |
+
"version": "1.0.2",
|
| 2008 |
+
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
| 2009 |
+
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
| 2010 |
+
"license": "MIT"
|
| 2011 |
+
},
|
| 2012 |
+
"node_modules/vary": {
|
| 2013 |
+
"version": "1.1.2",
|
| 2014 |
+
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
| 2015 |
+
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
|
| 2016 |
+
"license": "MIT",
|
| 2017 |
+
"engines": {
|
| 2018 |
+
"node": ">= 0.8"
|
| 2019 |
+
}
|
| 2020 |
+
},
|
| 2021 |
+
"node_modules/which": {
|
| 2022 |
+
"version": "1.3.1",
|
| 2023 |
+
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
| 2024 |
+
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
|
| 2025 |
+
"license": "ISC",
|
| 2026 |
+
"dependencies": {
|
| 2027 |
+
"isexe": "^2.0.0"
|
| 2028 |
+
},
|
| 2029 |
+
"bin": {
|
| 2030 |
+
"which": "bin/which"
|
| 2031 |
+
}
|
| 2032 |
+
},
|
| 2033 |
+
"node_modules/wrappy": {
|
| 2034 |
+
"version": "1.0.2",
|
| 2035 |
+
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
| 2036 |
+
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
| 2037 |
+
"license": "ISC"
|
| 2038 |
+
},
|
| 2039 |
+
"node_modules/yt-dlp-wrap": {
|
| 2040 |
+
"version": "2.3.12",
|
| 2041 |
+
"resolved": "https://registry.npmjs.org/yt-dlp-wrap/-/yt-dlp-wrap-2.3.12.tgz",
|
| 2042 |
+
"integrity": "sha512-P8fJ+6M1YjukyJENCTviNLiZ8mokxprR54ho3DsSKPWDcac489OjRiStGEARJr6un6ETS6goTn4CWl/b/rM3aA==",
|
| 2043 |
+
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
|
| 2044 |
+
"license": "MIT"
|
| 2045 |
+
}
|
| 2046 |
+
}
|
| 2047 |
+
}
|
package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "reel-transcriber",
|
| 3 |
+
"version": "1.0.0",
|
| 4 |
+
"description": "",
|
| 5 |
+
"main": "index.js",
|
| 6 |
+
"scripts": {
|
| 7 |
+
"start": "node server.js"
|
| 8 |
+
},
|
| 9 |
+
"engines": {
|
| 10 |
+
"node": ">=18"
|
| 11 |
+
},
|
| 12 |
+
"keywords": [],
|
| 13 |
+
"author": "",
|
| 14 |
+
"license": "ISC",
|
| 15 |
+
"type": "commonjs",
|
| 16 |
+
"dependencies": {
|
| 17 |
+
"@xenova/transformers": "^2.17.2",
|
| 18 |
+
"compression": "^1.8.1",
|
| 19 |
+
"express": "^5.2.1",
|
| 20 |
+
"ffmpeg-static": "^5.3.0",
|
| 21 |
+
"fluent-ffmpeg": "^2.1.3",
|
| 22 |
+
"helmet": "^8.2.0",
|
| 23 |
+
"multer": "^2.1.1",
|
| 24 |
+
"yt-dlp-wrap": "^2.3.12"
|
| 25 |
+
}
|
| 26 |
+
}
|
server.js
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const express = require('express');
|
| 2 |
+
const path = require('path');
|
| 3 |
+
const fs = require('fs');
|
| 4 |
+
const { execFile, spawn } = require('child_process');
|
| 5 |
+
const { randomUUID } = require('crypto');
|
| 6 |
+
const ffmpegStatic = require('ffmpeg-static');
|
| 7 |
+
const YTDlpWrap = require('yt-dlp-wrap').default;
|
| 8 |
+
const multer = require('multer');
|
| 9 |
+
const helmet = require('helmet');
|
| 10 |
+
const compression = require('compression');
|
| 11 |
+
const { analyze, generateTools } = require('./analyze');
|
| 12 |
+
|
| 13 |
+
// ── Config ────────────────────────────────────────────────────
|
| 14 |
+
const PORT = process.env.PORT || 5050;
|
| 15 |
+
const IS_WIN = process.platform === 'win32';
|
| 16 |
+
const DOWNLOADS_DIR = path.join(__dirname, 'downloads');
|
| 17 |
+
const UPLOADS_DIR = path.join(__dirname, 'uploads');
|
| 18 |
+
const YTDLP_PATH = process.env.YTDLP_PATH ||
|
| 19 |
+
path.join(__dirname, 'bin', IS_WIN ? 'yt-dlp.exe' : 'yt-dlp');
|
| 20 |
+
const JOB_TTL_MS = 60 * 60 * 1000; // 1h: jobs e arquivos temporários expiram
|
| 21 |
+
|
| 22 |
+
[DOWNLOADS_DIR, UPLOADS_DIR, path.join(__dirname, 'bin')].forEach(d => fs.mkdirSync(d, { recursive: true }));
|
| 23 |
+
|
| 24 |
+
// ── App ───────────────────────────────────────────────────────
|
| 25 |
+
const app = express();
|
| 26 |
+
app.set('trust proxy', 1);
|
| 27 |
+
app.use(helmet({
|
| 28 |
+
contentSecurityPolicy: false, // página usa estilos/scripts inline + fontes/thumbs externas
|
| 29 |
+
crossOriginEmbedderPolicy: false,
|
| 30 |
+
crossOriginResourcePolicy: false,
|
| 31 |
+
}));
|
| 32 |
+
app.use(compression());
|
| 33 |
+
app.use(express.json({ limit: '10mb' }));
|
| 34 |
+
app.use(express.static(path.join(__dirname, 'public')));
|
| 35 |
+
|
| 36 |
+
const upload = multer({
|
| 37 |
+
dest: UPLOADS_DIR,
|
| 38 |
+
limits: { fileSize: 2 * 1024 * 1024 * 1024 }, // 2 GB
|
| 39 |
+
});
|
| 40 |
+
|
| 41 |
+
// ── In-memory job store (single instance) ─────────────────────
|
| 42 |
+
const jobs = {};
|
| 43 |
+
|
| 44 |
+
function newJob() {
|
| 45 |
+
const id = randomUUID();
|
| 46 |
+
jobs[id] = { status: 'queued', text: '', error: '', language: '', segments: [], createdAt: Date.now() };
|
| 47 |
+
return id;
|
| 48 |
+
}
|
| 49 |
+
function finishJob(id, result) {
|
| 50 |
+
if (!jobs[id]) return;
|
| 51 |
+
Object.assign(jobs[id], {
|
| 52 |
+
status: 'done',
|
| 53 |
+
text: result.text,
|
| 54 |
+
language: result.language || '',
|
| 55 |
+
segments: result.segments || [],
|
| 56 |
+
});
|
| 57 |
+
}
|
| 58 |
+
function failJob(id, msg) {
|
| 59 |
+
if (jobs[id]) Object.assign(jobs[id], { status: 'error', error: msg });
|
| 60 |
+
console.error(`[job ${id}] erro:`, msg);
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
// Limpeza periódica de jobs antigos + arquivos órfãos
|
| 64 |
+
setInterval(() => {
|
| 65 |
+
const now = Date.now();
|
| 66 |
+
for (const [id, job] of Object.entries(jobs)) {
|
| 67 |
+
if (now - (job.createdAt || 0) > JOB_TTL_MS) delete jobs[id];
|
| 68 |
+
}
|
| 69 |
+
for (const dir of [DOWNLOADS_DIR, UPLOADS_DIR]) {
|
| 70 |
+
fs.readdir(dir, (err, files) => {
|
| 71 |
+
if (err) return;
|
| 72 |
+
files.forEach(f => {
|
| 73 |
+
const fp = path.join(dir, f);
|
| 74 |
+
fs.stat(fp, (e, st) => {
|
| 75 |
+
if (!e && now - st.mtimeMs > JOB_TTL_MS) fs.unlink(fp, () => {});
|
| 76 |
+
});
|
| 77 |
+
});
|
| 78 |
+
});
|
| 79 |
+
}
|
| 80 |
+
}, 15 * 60 * 1000).unref();
|
| 81 |
+
|
| 82 |
+
// ── yt-dlp / ffmpeg helpers ───────────────────────────────────
|
| 83 |
+
let ytdlpReady = null;
|
| 84 |
+
async function ensureYtDlp() {
|
| 85 |
+
if (fs.existsSync(YTDLP_PATH)) return;
|
| 86 |
+
if (!ytdlpReady) {
|
| 87 |
+
ytdlpReady = (async () => {
|
| 88 |
+
console.log('Baixando yt-dlp...');
|
| 89 |
+
await YTDlpWrap.downloadFromGithub(YTDLP_PATH);
|
| 90 |
+
if (!IS_WIN) { try { fs.chmodSync(YTDLP_PATH, 0o755); } catch {} }
|
| 91 |
+
console.log('yt-dlp pronto.');
|
| 92 |
+
})();
|
| 93 |
+
}
|
| 94 |
+
return ytdlpReady;
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
async function getVideoInfo(url) {
|
| 98 |
+
const ytdlp = new YTDlpWrap(YTDLP_PATH);
|
| 99 |
+
const raw = await ytdlp.execPromise([url, '--dump-json', '--no-playlist', '--quiet']);
|
| 100 |
+
const info = JSON.parse(raw);
|
| 101 |
+
return {
|
| 102 |
+
title: info.title || '',
|
| 103 |
+
uploader: info.uploader || info.channel || '',
|
| 104 |
+
thumbnail: info.thumbnail || '',
|
| 105 |
+
duration: info.duration || 0,
|
| 106 |
+
platform: info.extractor_key || '',
|
| 107 |
+
};
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
/** Converte qualquer áudio/vídeo para mp3 mono 16kHz (p/ Whisper) */
|
| 111 |
+
function convertToMp3(inputFile, outMp3, deleteInput = false, hq = false) {
|
| 112 |
+
return new Promise((resolve, reject) => {
|
| 113 |
+
const args = hq
|
| 114 |
+
? ['-i', inputFile, '-vn', '-ar', '44100', '-ac', '2', '-b:a', '192k', '-y', outMp3]
|
| 115 |
+
: ['-i', inputFile, '-vn', '-ar', '16000', '-ac', '1', '-b:a', '64k', '-y', outMp3];
|
| 116 |
+
execFile(ffmpegStatic, args, { stdio: 'pipe' }, (err) => {
|
| 117 |
+
if (deleteInput) fs.unlink(inputFile, () => {});
|
| 118 |
+
if (err) reject(new Error('Erro ao converter áudio: ' + err.message));
|
| 119 |
+
else resolve();
|
| 120 |
+
});
|
| 121 |
+
});
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
async function downloadAudioFromUrl(jobId, url, setStatus = () => {}) {
|
| 125 |
+
const outMp3 = path.join(DOWNLOADS_DIR, `${jobId}.mp3`);
|
| 126 |
+
const tmpOut = path.join(DOWNLOADS_DIR, `${jobId}.%(ext)s`);
|
| 127 |
+
const ytdlp = new YTDlpWrap(YTDLP_PATH);
|
| 128 |
+
await ytdlp.execPromise([url, '--format', 'bestaudio/best', '--output', tmpOut, '--no-playlist', '--quiet']);
|
| 129 |
+
const files = fs.readdirSync(DOWNLOADS_DIR).filter(f => f.startsWith(jobId) && !f.endsWith('.mp3'));
|
| 130 |
+
if (!files.length) throw new Error('Não foi possível baixar o vídeo. Verifique o link.');
|
| 131 |
+
setStatus('extracting');
|
| 132 |
+
await convertToMp3(path.join(DOWNLOADS_DIR, files[0]), outMp3, true);
|
| 133 |
+
return outMp3;
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
/** Roda o Whisper num processo filho */
|
| 137 |
+
function transcribeAudio(mp3Path, modelName, language, task = 'transcribe') {
|
| 138 |
+
return new Promise((resolve, reject) => {
|
| 139 |
+
const worker = path.join(__dirname, 'whisper_worker.js');
|
| 140 |
+
const child = spawn(process.execPath, [worker, mp3Path, modelName, language, task], { stdio: ['ignore', 'pipe', 'pipe'] });
|
| 141 |
+
let stdout = '', stderr = '', settled = false;
|
| 142 |
+
child.stdout.on('data', d => { stdout += d.toString(); });
|
| 143 |
+
child.stderr.on('data', d => { const l = d.toString().trim(); if (l) { stderr += l + '\n'; console.log('[worker]', l); } });
|
| 144 |
+
child.on('close', code => {
|
| 145 |
+
if (settled) return; settled = true;
|
| 146 |
+
if (code !== 0) return reject(new Error(stderr.split('\n').filter(Boolean).pop() || `Worker saiu com código ${code}`));
|
| 147 |
+
try { resolve(JSON.parse(stdout.trim())); }
|
| 148 |
+
catch { reject(new Error('Resposta inválida do transcritor.')); }
|
| 149 |
+
});
|
| 150 |
+
child.on('error', err => { if (!settled) { settled = true; reject(err); } });
|
| 151 |
+
});
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
// ── Pipelines ─────────────────────────────────────────────────
|
| 155 |
+
async function runUrlJob(jobId, url, model, language, task) {
|
| 156 |
+
let mp3 = null;
|
| 157 |
+
try {
|
| 158 |
+
jobs[jobId].status = 'downloading_ytdlp'; await ensureYtDlp();
|
| 159 |
+
jobs[jobId].status = 'downloading';
|
| 160 |
+
mp3 = await downloadAudioFromUrl(jobId, url, s => { jobs[jobId].status = s; });
|
| 161 |
+
jobs[jobId].status = 'transcribing';
|
| 162 |
+
finishJob(jobId, await transcribeAudio(mp3, model, language, task));
|
| 163 |
+
} catch (e) { failJob(jobId, e.message); }
|
| 164 |
+
finally { if (mp3 && fs.existsSync(mp3)) fs.unlink(mp3, () => {}); }
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
async function runFileJob(jobId, filePath, model, language, task) {
|
| 168 |
+
let mp3 = null;
|
| 169 |
+
try {
|
| 170 |
+
jobs[jobId].status = 'extracting';
|
| 171 |
+
mp3 = path.join(DOWNLOADS_DIR, `${jobId}.mp3`);
|
| 172 |
+
await convertToMp3(filePath, mp3, true);
|
| 173 |
+
jobs[jobId].status = 'transcribing';
|
| 174 |
+
finishJob(jobId, await transcribeAudio(mp3, model, language, task));
|
| 175 |
+
} catch (e) {
|
| 176 |
+
failJob(jobId, e.message);
|
| 177 |
+
if (filePath && fs.existsSync(filePath)) fs.unlink(filePath, () => {});
|
| 178 |
+
} finally { if (mp3 && fs.existsSync(mp3)) fs.unlink(mp3, () => {}); }
|
| 179 |
+
}
|
| 180 |
+
|
| 181 |
+
// ── Routes ────────────────────────────────────────────────────
|
| 182 |
+
app.get('/', (req, res) => res.sendFile(path.join(__dirname, 'templates', 'index.html')));
|
| 183 |
+
app.get('/health', (req, res) => res.json({ ok: true, uptime: process.uptime() }));
|
| 184 |
+
|
| 185 |
+
app.post('/info', async (req, res) => {
|
| 186 |
+
const { url } = req.body;
|
| 187 |
+
if (!url) return res.status(400).json({ error: 'URL não informada' });
|
| 188 |
+
try { await ensureYtDlp(); res.json(await getVideoInfo(url)); }
|
| 189 |
+
catch (e) { res.status(400).json({ error: 'Não foi possível obter informações do vídeo.' }); }
|
| 190 |
+
});
|
| 191 |
+
|
| 192 |
+
app.post('/transcribe', (req, res) => {
|
| 193 |
+
const { url, model = 'Xenova/whisper-small', language = 'auto', task = 'transcribe' } = req.body;
|
| 194 |
+
if (!url) return res.status(400).json({ error: 'URL não informada' });
|
| 195 |
+
const jobId = newJob();
|
| 196 |
+
runUrlJob(jobId, url, model, language, task);
|
| 197 |
+
res.json({ job_id: jobId });
|
| 198 |
+
});
|
| 199 |
+
|
| 200 |
+
app.post('/transcribe-file', upload.single('file'), (req, res) => {
|
| 201 |
+
if (!req.file) return res.status(400).json({ error: 'Nenhum arquivo enviado.' });
|
| 202 |
+
const { model = 'Xenova/whisper-small', language = 'auto', task = 'transcribe' } = req.body;
|
| 203 |
+
const jobId = newJob();
|
| 204 |
+
runFileJob(jobId, req.file.path, model, language, task);
|
| 205 |
+
res.json({ job_id: jobId });
|
| 206 |
+
});
|
| 207 |
+
|
| 208 |
+
app.post('/analyze', (req, res) => {
|
| 209 |
+
const { text, segments, title } = req.body;
|
| 210 |
+
if (!text) return res.status(400).json({ error: 'Texto não informado' });
|
| 211 |
+
try { res.json(analyze(text, segments || [], title || '')); }
|
| 212 |
+
catch (e) { res.status(400).json({ error: e.message }); }
|
| 213 |
+
});
|
| 214 |
+
|
| 215 |
+
app.post('/generate', (req, res) => {
|
| 216 |
+
const { type, ...params } = req.body;
|
| 217 |
+
if (!type) return res.status(400).json({ error: 'Tipo de ferramenta não informado' });
|
| 218 |
+
try { res.json(generateTools(type, params)); }
|
| 219 |
+
catch (e) { res.status(400).json({ error: e.message }); }
|
| 220 |
+
});
|
| 221 |
+
|
| 222 |
+
app.get('/status/:jobId', (req, res) => {
|
| 223 |
+
const job = jobs[req.params.jobId];
|
| 224 |
+
if (!job) return res.status(404).json({ error: 'Job não encontrado' });
|
| 225 |
+
res.json(job);
|
| 226 |
+
});
|
| 227 |
+
|
| 228 |
+
/** Stream helper: envia arquivo e remove ao terminar */
|
| 229 |
+
function streamAndCleanup(res, filePath, downloadName, contentType) {
|
| 230 |
+
res.setHeader('Content-Disposition', `attachment; filename="${downloadName}"`);
|
| 231 |
+
res.setHeader('Content-Type', contentType);
|
| 232 |
+
const stream = fs.createReadStream(filePath);
|
| 233 |
+
stream.pipe(res);
|
| 234 |
+
const cleanup = () => fs.unlink(filePath, () => {});
|
| 235 |
+
stream.on('close', cleanup);
|
| 236 |
+
res.on('close', cleanup);
|
| 237 |
+
}
|
| 238 |
+
|
| 239 |
+
app.post('/download-video', async (req, res) => {
|
| 240 |
+
const { url } = req.body;
|
| 241 |
+
if (!url) return res.status(400).json({ error: 'URL não informada' });
|
| 242 |
+
try {
|
| 243 |
+
await ensureYtDlp();
|
| 244 |
+
const id = randomUUID();
|
| 245 |
+
const out = path.join(DOWNLOADS_DIR, `${id}.%(ext)s`);
|
| 246 |
+
const ytdlp = new YTDlpWrap(YTDLP_PATH);
|
| 247 |
+
await ytdlp.execPromise([url,
|
| 248 |
+
'--format', 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',
|
| 249 |
+
'--merge-output-format', 'mp4',
|
| 250 |
+
'--ffmpeg-location', ffmpegStatic,
|
| 251 |
+
'--output', out, '--no-playlist', '--quiet']);
|
| 252 |
+
const files = fs.readdirSync(DOWNLOADS_DIR).filter(f => f.startsWith(id));
|
| 253 |
+
if (!files.length) return res.status(500).json({ error: 'Falha ao baixar vídeo.' });
|
| 254 |
+
streamAndCleanup(res, path.join(DOWNLOADS_DIR, files[0]), 'video.mp4', 'video/mp4');
|
| 255 |
+
} catch (e) { res.status(500).json({ error: 'Falha ao baixar vídeo. Pode estar protegido ou indisponível.' }); }
|
| 256 |
+
});
|
| 257 |
+
|
| 258 |
+
app.post('/download-audio', async (req, res) => {
|
| 259 |
+
const { url } = req.body;
|
| 260 |
+
if (!url) return res.status(400).json({ error: 'URL não informada' });
|
| 261 |
+
try {
|
| 262 |
+
await ensureYtDlp();
|
| 263 |
+
const id = randomUUID();
|
| 264 |
+
const mp3Out = path.join(DOWNLOADS_DIR, `${id}.mp3`);
|
| 265 |
+
const tmpOut = path.join(DOWNLOADS_DIR, `${id}.%(ext)s`);
|
| 266 |
+
const ytdlp = new YTDlpWrap(YTDLP_PATH);
|
| 267 |
+
await ytdlp.execPromise([url, '--format', 'bestaudio/best', '--output', tmpOut, '--no-playlist', '--quiet']);
|
| 268 |
+
const files = fs.readdirSync(DOWNLOADS_DIR).filter(f => f.startsWith(id) && !f.endsWith('.mp3'));
|
| 269 |
+
if (!files.length) return res.status(500).json({ error: 'Falha ao baixar áudio.' });
|
| 270 |
+
await convertToMp3(path.join(DOWNLOADS_DIR, files[0]), mp3Out, true, true);
|
| 271 |
+
streamAndCleanup(res, mp3Out, 'audio.mp3', 'audio/mpeg');
|
| 272 |
+
} catch (e) { res.status(500).json({ error: 'Falha ao baixar áudio.' }); }
|
| 273 |
+
});
|
| 274 |
+
|
| 275 |
+
// Handler global de erros (ex.: arquivo grande demais no multer)
|
| 276 |
+
app.use((err, req, res, next) => {
|
| 277 |
+
console.error('Erro não tratado:', err.message);
|
| 278 |
+
if (res.headersSent) return next(err);
|
| 279 |
+
res.status(500).json({ error: 'Erro interno. Tente novamente.' });
|
| 280 |
+
});
|
| 281 |
+
|
| 282 |
+
// ── Start + graceful shutdown ─────────────────────────────────
|
| 283 |
+
const server = app.listen(PORT, () => {
|
| 284 |
+
console.log(`\n✅ CreatorKit rodando em http://localhost:${PORT} (${process.env.NODE_ENV || 'development'})\n`);
|
| 285 |
+
});
|
| 286 |
+
|
| 287 |
+
function shutdown(sig) {
|
| 288 |
+
console.log(`\n${sig} recebido, encerrando...`);
|
| 289 |
+
server.close(() => process.exit(0));
|
| 290 |
+
setTimeout(() => process.exit(0), 10000).unref();
|
| 291 |
+
}
|
| 292 |
+
['SIGTERM', 'SIGINT'].forEach(s => process.on(s, () => shutdown(s)));
|
| 293 |
+
process.on('unhandledRejection', r => console.error('Rejeição não tratada:', r));
|
start.bat
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
@echo off
|
| 2 |
+
echo Iniciando Transcritor de Reels...
|
| 3 |
+
cd /d "%~dp0"
|
| 4 |
+
|
| 5 |
+
where node >nul 2>&1
|
| 6 |
+
if %errorlevel% neq 0 (
|
| 7 |
+
echo ERRO: Node.js nao encontrado. Instale em https://nodejs.org
|
| 8 |
+
pause
|
| 9 |
+
exit /b 1
|
| 10 |
+
)
|
| 11 |
+
|
| 12 |
+
if not exist node_modules (
|
| 13 |
+
echo Instalando dependencias pela primeira vez...
|
| 14 |
+
npm install
|
| 15 |
+
)
|
| 16 |
+
|
| 17 |
+
echo.
|
| 18 |
+
echo Acesse: http://localhost:5050
|
| 19 |
+
echo Pressione Ctrl+C para encerrar.
|
| 20 |
+
echo.
|
| 21 |
+
node server.js
|
| 22 |
+
pause
|
templates/index.html
ADDED
|
@@ -0,0 +1,955 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="pt-BR">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8"/>
|
| 5 |
+
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
|
| 6 |
+
<title>CreatorKit — O kit completo do criador de conteúdo</title>
|
| 7 |
+
<link rel="preconnect" href="https://fonts.googleapis.com"/>
|
| 8 |
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>
|
| 9 |
+
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600;9..144,700&family=Hanken+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"/>
|
| 10 |
+
<style>
|
| 11 |
+
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
|
| 12 |
+
:root{
|
| 13 |
+
--bg:#f7f5f0;--bg2:#fffefb;--ink:#1a1814;--ink2:#5c574e;--ink3:#8f8a7e;
|
| 14 |
+
--line:#e7e3d9;--line2:#d8d3c6;--card:#fffefb;
|
| 15 |
+
--acc:#5b3df5;--acc-d:#4a2fd0;--acc-soft:#ece8ff;
|
| 16 |
+
--pink:#e84e8a;--amber:#f59e0b;--teal:#0d9488;--rose:#f43f5e;
|
| 17 |
+
--ok:#16a34a;--err:#dc2626;
|
| 18 |
+
--r:16px;--rs:10px;--rx:8px;
|
| 19 |
+
--sh:0 1px 2px rgba(26,24,20,.04),0 4px 16px rgba(26,24,20,.05);
|
| 20 |
+
--sh2:0 2px 4px rgba(26,24,20,.05),0 12px 40px rgba(26,24,20,.09);
|
| 21 |
+
}
|
| 22 |
+
html{scroll-behavior:smooth}
|
| 23 |
+
body{background:var(--bg);color:var(--ink);font-family:'Hanken Grotesk',system-ui,sans-serif;font-size:15px;line-height:1.5;-webkit-font-smoothing:antialiased}
|
| 24 |
+
::selection{background:var(--acc-soft);color:var(--acc-d)}
|
| 25 |
+
::-webkit-scrollbar{width:8px;height:8px}
|
| 26 |
+
::-webkit-scrollbar-track{background:transparent}
|
| 27 |
+
::-webkit-scrollbar-thumb{background:var(--line2);border-radius:4px}
|
| 28 |
+
.serif{font-family:'Fraunces',serif}
|
| 29 |
+
a{color:inherit;text-decoration:none}
|
| 30 |
+
.view{display:none}.view.on{display:block}
|
| 31 |
+
|
| 32 |
+
/* ════ NAV ════ */
|
| 33 |
+
.nav{position:sticky;top:0;z-index:90;display:flex;align-items:center;justify-content:space-between;padding:0 28px;height:64px;background:rgba(247,245,240,.82);backdrop-filter:blur(14px);border-bottom:1px solid var(--line)}
|
| 34 |
+
.brand{display:flex;align-items:center;gap:10px;cursor:pointer}
|
| 35 |
+
.bmark{width:30px;height:30px;border-radius:9px;background:var(--ink);color:var(--bg2);display:flex;align-items:center;justify-content:center;font-family:'Fraunces',serif;font-weight:700;font-size:15px}
|
| 36 |
+
.bname{font-family:'Fraunces',serif;font-weight:600;font-size:19px;letter-spacing:-.01em}
|
| 37 |
+
.nlinks{display:flex;align-items:center;gap:30px}
|
| 38 |
+
.nlink{font-size:14px;color:var(--ink2);font-weight:500;transition:color .15s}
|
| 39 |
+
.nlink:hover{color:var(--ink)}
|
| 40 |
+
.nbtn{background:var(--ink);color:var(--bg2);padding:9px 18px;border-radius:100px;font-size:14px;font-weight:600;border:none;cursor:pointer;transition:transform .12s,background .15s}
|
| 41 |
+
.nbtn:hover{transform:translateY(-1px);background:#000}
|
| 42 |
+
@media(max-width:760px){.nlinks .nlink{display:none}}
|
| 43 |
+
|
| 44 |
+
/* ════ HERO ════ */
|
| 45 |
+
.hero{max-width:1080px;margin:0 auto;padding:84px 28px 64px;text-align:center}
|
| 46 |
+
.hpill{display:inline-flex;align-items:center;gap:7px;background:var(--bg2);border:1px solid var(--line);border-radius:100px;padding:6px 14px;font-size:13px;color:var(--ink2);font-weight:500;margin-bottom:28px;box-shadow:var(--sh)}
|
| 47 |
+
.hpill .dot{width:7px;height:7px;border-radius:50%;background:var(--ok);box-shadow:0 0 0 3px rgba(22,163,74,.15)}
|
| 48 |
+
.htitle{font-family:'Fraunces',serif;font-weight:600;font-size:clamp(2.6rem,6.5vw,4.6rem);line-height:1.02;letter-spacing:-.03em;margin-bottom:22px}
|
| 49 |
+
.htitle em{font-style:italic;color:var(--acc)}
|
| 50 |
+
.hsub{font-size:clamp(1rem,2.2vw,1.22rem);color:var(--ink2);max-width:600px;margin:0 auto 36px;line-height:1.55}
|
| 51 |
+
.hcta{display:flex;gap:12px;justify-content:center;flex-wrap:wrap}
|
| 52 |
+
.btn-lg{padding:14px 28px;border-radius:100px;font-size:15px;font-weight:600;cursor:pointer;border:none;transition:transform .12s,box-shadow .15s,background .15s;font-family:inherit}
|
| 53 |
+
.btn-primary{background:var(--acc);color:#fff;box-shadow:0 6px 22px rgba(91,61,245,.32)}
|
| 54 |
+
.btn-primary:hover{transform:translateY(-2px);background:var(--acc-d);box-shadow:0 10px 30px rgba(91,61,245,.4)}
|
| 55 |
+
.btn-ghost{background:var(--bg2);color:var(--ink);border:1px solid var(--line2)}
|
| 56 |
+
.btn-ghost:hover{transform:translateY(-2px);box-shadow:var(--sh)}
|
| 57 |
+
.hnote{margin-top:18px;font-size:13px;color:var(--ink3)}
|
| 58 |
+
|
| 59 |
+
/* hero mock */
|
| 60 |
+
.hmock{max-width:920px;margin:56px auto 0;background:var(--card);border:1px solid var(--line);border-radius:20px;box-shadow:var(--sh2);overflow:hidden}
|
| 61 |
+
.hmock-bar{display:flex;align-items:center;gap:7px;padding:13px 16px;border-bottom:1px solid var(--line);background:var(--bg)}
|
| 62 |
+
.hmock-bar .c{width:11px;height:11px;border-radius:50%}
|
| 63 |
+
.hmock-bar .c1{background:#ff5f57}.hmock-bar .c2{background:#febc2e}.hmock-bar .c3{background:#28c840}
|
| 64 |
+
.hmock-bar .u{margin-left:12px;font-size:12px;color:var(--ink3);font-family:'JetBrains Mono',monospace}
|
| 65 |
+
.hmock-body{display:grid;grid-template-columns:1.1fr 1fr;gap:0}
|
| 66 |
+
@media(max-width:680px){.hmock-body{grid-template-columns:1fr}}
|
| 67 |
+
.hmock-l{padding:24px;border-right:1px solid var(--line);text-align:left}
|
| 68 |
+
.hmock-r{padding:24px;text-align:left;background:var(--bg)}
|
| 69 |
+
.hmock-label{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--ink3);margin-bottom:10px}
|
| 70 |
+
.hmock-input{background:var(--bg2);border:1px solid var(--line2);border-radius:9px;padding:11px 13px;font-size:13px;color:var(--ink2);margin-bottom:14px;font-family:'JetBrains Mono',monospace}
|
| 71 |
+
.hmock-tags{display:flex;flex-wrap:wrap;gap:6px}
|
| 72 |
+
.hmock-tag{background:var(--acc-soft);color:var(--acc-d);border-radius:100px;padding:4px 11px;font-size:12px;font-weight:600}
|
| 73 |
+
.hmock-line{height:9px;border-radius:5px;background:var(--line);margin-bottom:9px}
|
| 74 |
+
.hmock-line.s{width:70%}.hmock-line.m{width:90%}
|
| 75 |
+
|
| 76 |
+
/* ════ MARQUEE / TRUST ════ */
|
| 77 |
+
.trust{padding:40px 28px;text-align:center;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
|
| 78 |
+
.trust-l{font-size:13px;color:var(--ink3);font-weight:600;text-transform:uppercase;letter-spacing:.1em;margin-bottom:22px}
|
| 79 |
+
.trust-row{display:flex;justify-content:center;gap:40px;flex-wrap:wrap;font-family:'Fraunces',serif;font-size:20px;color:var(--ink2);font-weight:500}
|
| 80 |
+
.trust-row span{display:flex;align-items:center;gap:8px}
|
| 81 |
+
|
| 82 |
+
/* ════ SECTION ════ */
|
| 83 |
+
.sec{max-width:1120px;margin:0 auto;padding:88px 28px}
|
| 84 |
+
.sec-head{text-align:center;max-width:640px;margin:0 auto 56px}
|
| 85 |
+
.sec-tag{display:inline-block;font-size:13px;font-weight:700;color:var(--acc);text-transform:uppercase;letter-spacing:.1em;margin-bottom:14px}
|
| 86 |
+
.sec-title{font-family:'Fraunces',serif;font-weight:600;font-size:clamp(2rem,4.5vw,3rem);line-height:1.08;letter-spacing:-.02em;margin-bottom:16px}
|
| 87 |
+
.sec-sub{font-size:1.08rem;color:var(--ink2);line-height:1.55}
|
| 88 |
+
|
| 89 |
+
/* feature grid */
|
| 90 |
+
.fgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
|
| 91 |
+
@media(max-width:880px){.fgrid{grid-template-columns:1fr 1fr}}
|
| 92 |
+
@media(max-width:560px){.fgrid{grid-template-columns:1fr}}
|
| 93 |
+
.fcard{background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:26px;transition:transform .18s,box-shadow .18s,border-color .18s;cursor:pointer;position:relative;overflow:hidden}
|
| 94 |
+
.fcard:hover{transform:translateY(-4px);box-shadow:var(--sh2);border-color:var(--line2)}
|
| 95 |
+
.ficon{width:46px;height:46px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:22px;margin-bottom:16px}
|
| 96 |
+
.fname{font-family:'Fraunces',serif;font-weight:600;font-size:1.25rem;margin-bottom:7px;letter-spacing:-.01em}
|
| 97 |
+
.fdesc{font-size:14px;color:var(--ink2);line-height:1.5}
|
| 98 |
+
.farrow{position:absolute;top:26px;right:26px;color:var(--ink3);opacity:0;transform:translateX(-6px);transition:all .2s;font-size:18px}
|
| 99 |
+
.fcard:hover .farrow{opacity:1;transform:translateX(0)}
|
| 100 |
+
|
| 101 |
+
/* how it works */
|
| 102 |
+
.steps3{display:grid;grid-template-columns:repeat(3,1fr);gap:24px;counter-reset:s}
|
| 103 |
+
@media(max-width:760px){.steps3{grid-template-columns:1fr}}
|
| 104 |
+
.s3{position:relative;padding-top:20px}
|
| 105 |
+
.s3::before{counter-increment:s;content:"0" counter(s);font-family:'Fraunces',serif;font-size:3rem;font-weight:600;color:var(--acc-soft);line-height:1;display:block;margin-bottom:14px}
|
| 106 |
+
.s3 h4{font-family:'Fraunces',serif;font-size:1.3rem;font-weight:600;margin-bottom:8px}
|
| 107 |
+
.s3 p{font-size:14px;color:var(--ink2);line-height:1.55}
|
| 108 |
+
|
| 109 |
+
/* big cta */
|
| 110 |
+
.cta-band{max-width:1120px;margin:40px auto 88px;padding:0 28px}
|
| 111 |
+
.cta-inner{background:var(--ink);border-radius:28px;padding:64px 40px;text-align:center;position:relative;overflow:hidden}
|
| 112 |
+
.cta-inner::before{content:'';position:absolute;inset:0;background:radial-gradient(ellipse 60% 80% at 50% 0%,rgba(91,61,245,.35),transparent 70%);pointer-events:none}
|
| 113 |
+
.cta-inner h2{font-family:'Fraunces',serif;font-weight:600;font-size:clamp(2rem,4.5vw,3rem);color:var(--bg2);line-height:1.08;letter-spacing:-.02em;margin-bottom:16px;position:relative}
|
| 114 |
+
.cta-inner p{color:rgba(255,255,255,.7);font-size:1.05rem;margin-bottom:30px;position:relative}
|
| 115 |
+
|
| 116 |
+
/* footer */
|
| 117 |
+
.foot{border-top:1px solid var(--line);padding:40px 28px}
|
| 118 |
+
.foot-in{max-width:1120px;margin:0 auto;display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:16px}
|
| 119 |
+
.foot-c{font-size:13px;color:var(--ink3)}
|
| 120 |
+
|
| 121 |
+
/* ════════════════════════════════════════════════════════════
|
| 122 |
+
APP VIEW
|
| 123 |
+
════════════════════════════════════════════════════════════ */
|
| 124 |
+
.app-shell{display:flex;height:100vh;overflow:hidden}
|
| 125 |
+
.app-side{width:248px;flex-shrink:0;background:var(--bg2);border-right:1px solid var(--line);display:flex;flex-direction:column;overflow-y:auto}
|
| 126 |
+
.app-side-top{padding:18px 16px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:10px;cursor:pointer}
|
| 127 |
+
.tool-nav{padding:12px 10px;display:flex;flex-direction:column;gap:2px;flex:1}
|
| 128 |
+
.tn-label{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--ink3);padding:12px 10px 6px}
|
| 129 |
+
.tn{display:flex;align-items:center;gap:11px;padding:9px 11px;border-radius:var(--rx);font-size:14px;font-weight:500;color:var(--ink2);cursor:pointer;transition:background .12s,color .12s}
|
| 130 |
+
.tn:hover{background:var(--bg);color:var(--ink)}
|
| 131 |
+
.tn.on{background:var(--acc-soft);color:var(--acc-d);font-weight:600}
|
| 132 |
+
.tn .tn-ico{font-size:16px;width:20px;text-align:center}
|
| 133 |
+
.app-main{flex:1;overflow-y:auto;background:var(--bg)}
|
| 134 |
+
.app-head{padding:22px 32px 0}
|
| 135 |
+
.app-h-title{font-family:'Fraunces',serif;font-size:1.7rem;font-weight:600;letter-spacing:-.01em}
|
| 136 |
+
.app-h-sub{font-size:14px;color:var(--ink2);margin-top:4px}
|
| 137 |
+
.app-body{padding:24px 32px 60px}
|
| 138 |
+
.tool-pane{display:none}.tool-pane.on{display:block;animation:fade .25s ease}
|
| 139 |
+
@keyframes fade{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}
|
| 140 |
+
|
| 141 |
+
/* form bits */
|
| 142 |
+
.fld{margin-bottom:14px}
|
| 143 |
+
.fld-l{display:block;font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--ink3);margin-bottom:7px}
|
| 144 |
+
.inp,.sel,.ta{width:100%;background:var(--bg2);border:1px solid var(--line2);border-radius:var(--rs);color:var(--ink);font-family:inherit;font-size:14px;padding:11px 13px;outline:none;transition:border-color .15s,box-shadow .15s}
|
| 145 |
+
.inp:focus,.sel:focus,.ta:focus{border-color:var(--acc);box-shadow:0 0 0 3px var(--acc-soft)}
|
| 146 |
+
.ta{resize:vertical;min-height:90px;line-height:1.5}
|
| 147 |
+
.row2{display:grid;grid-template-columns:1fr 1fr;gap:12px}
|
| 148 |
+
@media(max-width:560px){.row2{grid-template-columns:1fr}}
|
| 149 |
+
.urlw{position:relative}
|
| 150 |
+
.urlw .pl{position:absolute;left:12px;top:50%;transform:translateY(-50%);font-size:15px;pointer-events:none}
|
| 151 |
+
.urlw .inp{padding-left:36px;padding-right:60px}
|
| 152 |
+
.pbtn{position:absolute;right:7px;top:50%;transform:translateY(-50%);background:var(--bg);border:1px solid var(--line2);border-radius:6px;color:var(--ink2);font-size:12px;font-weight:600;padding:4px 9px;cursor:pointer;font-family:inherit;transition:background .12s}
|
| 153 |
+
.pbtn:hover{background:var(--line)}
|
| 154 |
+
|
| 155 |
+
.run-btn{width:100%;background:var(--acc);color:#fff;border:none;border-radius:var(--rs);padding:13px;font-size:15px;font-weight:600;font-family:inherit;cursor:pointer;transition:transform .12s,background .15s,box-shadow .15s;box-shadow:0 4px 16px rgba(91,61,245,.28)}
|
| 156 |
+
.run-btn:hover:not(:disabled){transform:translateY(-1px);background:var(--acc-d);box-shadow:0 8px 24px rgba(91,61,245,.36)}
|
| 157 |
+
.run-btn:disabled{opacity:.45;cursor:not-allowed;transform:none;box-shadow:none}
|
| 158 |
+
|
| 159 |
+
.card-grid{display:grid;grid-template-columns:1fr 1fr;gap:24px}
|
| 160 |
+
@media(max-width:880px){.card-grid{grid-template-columns:1fr}}
|
| 161 |
+
.panel{background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:22px}
|
| 162 |
+
.panel-t{font-family:'Fraunces',serif;font-size:1.15rem;font-weight:600;margin-bottom:16px}
|
| 163 |
+
|
| 164 |
+
/* tabs (input switch) */
|
| 165 |
+
.itabs{display:flex;background:var(--bg);border:1px solid var(--line2);border-radius:var(--rs);padding:3px;gap:3px;margin-bottom:14px}
|
| 166 |
+
.itab{flex:1;padding:8px;border-radius:7px;font-size:13px;font-weight:600;color:var(--ink2);cursor:pointer;text-align:center;transition:all .12s}
|
| 167 |
+
.itab.on{background:var(--card);color:var(--ink);box-shadow:var(--sh)}
|
| 168 |
+
.tpane{display:none}.tpane.on{display:block}
|
| 169 |
+
|
| 170 |
+
/* drop */
|
| 171 |
+
.dz{border:2px dashed var(--line2);border-radius:var(--rs);padding:26px 14px;text-align:center;cursor:pointer;transition:all .15s}
|
| 172 |
+
.dz:hover,.dz.ov{border-color:var(--acc);background:var(--acc-soft)}
|
| 173 |
+
.dz .i{font-size:24px;margin-bottom:6px}.dz .l{font-size:13px;color:var(--ink2);font-weight:500}.dz .s{font-size:12px;color:var(--ink3);margin-top:3px}
|
| 174 |
+
.fchosen{display:none;margin-top:9px;background:var(--bg);border:1px solid var(--line2);border-radius:var(--rs);padding:9px 12px;font-size:13px;align-items:center;gap:8px}
|
| 175 |
+
.fchosen.on{display:flex}
|
| 176 |
+
.fx{margin-left:auto;background:none;border:none;color:var(--ink3);cursor:pointer;font-size:15px}
|
| 177 |
+
.fx:hover{color:var(--err)}
|
| 178 |
+
|
| 179 |
+
/* video preview */
|
| 180 |
+
.vprev{display:none;margin-top:10px;background:var(--bg);border:1px solid var(--line2);border-radius:var(--rs);padding:9px;gap:10px;align-items:center}
|
| 181 |
+
.vprev.on{display:flex}
|
| 182 |
+
.vprev img{width:64px;height:42px;object-fit:cover;border-radius:6px;background:var(--line)}
|
| 183 |
+
.vprev .t{font-size:13px;font-weight:600;line-height:1.3;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
|
| 184 |
+
.vprev .m{font-size:11px;color:var(--ink3);margin-top:2px}
|
| 185 |
+
|
| 186 |
+
/* steps */
|
| 187 |
+
.pg{display:none;margin-top:16px}
|
| 188 |
+
.steps{display:flex;position:relative}
|
| 189 |
+
.steps::before{content:'';position:absolute;top:11px;left:11px;right:11px;height:2px;background:var(--line2)}
|
| 190 |
+
.step{flex:1;display:flex;flex-direction:column;align-items:center;gap:5px;position:relative;z-index:1}
|
| 191 |
+
.sc{width:23px;height:23px;border-radius:50%;background:var(--bg2);border:2px solid var(--line2);display:flex;align-items:center;justify-content:center;font-size:10px;transition:all .3s}
|
| 192 |
+
.step.ac .sc{border-color:var(--acc);background:var(--acc-soft)}
|
| 193 |
+
.step.ac .sc::after{content:'';width:8px;height:8px;border-radius:50%;background:var(--acc);animation:pulse .8s ease-in-out infinite alternate}
|
| 194 |
+
.step.dn .sc{border-color:var(--ok);background:#dcfce7}
|
| 195 |
+
.step.dn .sc::after{content:'✓';font-size:10px;color:var(--ok);font-weight:700}
|
| 196 |
+
@keyframes pulse{from{transform:scale(.6);opacity:.5}to{transform:scale(1);opacity:1}}
|
| 197 |
+
.slb{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--ink3)}
|
| 198 |
+
.step.ac .slb{color:var(--ink2)}.step.dn .slb{color:var(--ok)}
|
| 199 |
+
|
| 200 |
+
.errbox{display:none;margin-top:14px;background:#fef2f2;border:1px solid #fecaca;border-radius:var(--rs);padding:12px;font-size:13px;color:#b91c1c;line-height:1.5}
|
| 201 |
+
|
| 202 |
+
/* result tabs */
|
| 203 |
+
.outc{display:none}.outc.on{display:block}
|
| 204 |
+
.sbar{display:flex;gap:7px;flex-wrap:wrap;margin-bottom:16px}
|
| 205 |
+
.schip{display:flex;align-items:center;gap:4px;background:var(--bg2);border:1px solid var(--line2);border-radius:100px;padding:4px 11px;font-size:12px;color:var(--ink2);font-weight:500}
|
| 206 |
+
.otnav{display:flex;gap:2px;border-bottom:1px solid var(--line);overflow-x:auto;margin-bottom:18px;padding-bottom:0}
|
| 207 |
+
.otnav::-webkit-scrollbar{height:0}
|
| 208 |
+
.otab{padding:9px 13px;font-size:13px;font-weight:600;color:var(--ink2);cursor:pointer;border-bottom:2px solid transparent;white-space:nowrap;transition:all .12s}
|
| 209 |
+
.otab:hover{color:var(--ink)}
|
| 210 |
+
.otab.on{color:var(--acc);border-bottom-color:var(--acc)}
|
| 211 |
+
.opanel{display:none}.opanel.on{display:block;animation:fade .2s ease}
|
| 212 |
+
|
| 213 |
+
/* content box */
|
| 214 |
+
.cb{background:var(--card);border:1px solid var(--line);border-radius:var(--r);overflow:hidden;margin-bottom:12px}
|
| 215 |
+
.cbh{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px;padding:12px 16px;border-bottom:1px solid var(--line);background:var(--bg2)}
|
| 216 |
+
.cbt{font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--ink3)}
|
| 217 |
+
.cba{display:flex;gap:6px;flex-wrap:wrap}
|
| 218 |
+
.cbb{padding:16px;font-size:14px;line-height:1.7;white-space:pre-wrap;word-break:break-word;max-height:360px;overflow-y:auto}
|
| 219 |
+
.cbb.mono{font-family:'JetBrains Mono',monospace;font-size:12.5px;color:var(--ink2)}
|
| 220 |
+
|
| 221 |
+
.btn{display:inline-flex;align-items:center;gap:5px;background:var(--bg);border:1px solid var(--line2);border-radius:7px;color:var(--ink2);font-family:inherit;font-size:12px;font-weight:600;padding:6px 11px;cursor:pointer;transition:all .12s;white-space:nowrap}
|
| 222 |
+
.btn:hover{background:var(--line);color:var(--ink)}
|
| 223 |
+
.btn.pri{background:var(--acc-soft);border-color:transparent;color:var(--acc-d)}
|
| 224 |
+
.btn.pri:hover{background:#ddd6ff}
|
| 225 |
+
.btn.ok{color:var(--ok)!important;border-color:#bbf7d0!important;background:#f0fdf4!important}
|
| 226 |
+
.btn.ld{opacity:.5;pointer-events:none}
|
| 227 |
+
.btn.sm{padding:4px 9px;font-size:11px}
|
| 228 |
+
|
| 229 |
+
/* search */
|
| 230 |
+
.srchw{position:relative;margin-bottom:12px}
|
| 231 |
+
.srchi{width:100%;background:var(--bg2);border:1px solid var(--line2);border-radius:var(--rs);font-family:inherit;font-size:13px;padding:9px 60px 9px 32px;outline:none;transition:border-color .15s}
|
| 232 |
+
.srchi:focus{border-color:var(--acc)}
|
| 233 |
+
.sico{position:absolute;left:11px;top:50%;transform:translateY(-50%);color:var(--ink3);font-size:13px}
|
| 234 |
+
.scnt{position:absolute;right:11px;top:50%;transform:translateY(-50%);font-size:11px;color:var(--ink3)}
|
| 235 |
+
mark{background:#fde68a;border-radius:2px;padding:0 1px}
|
| 236 |
+
|
| 237 |
+
/* segments */
|
| 238 |
+
.segtog{display:flex;align-items:center;justify-content:space-between;padding:11px 16px;border-top:1px solid var(--line);cursor:pointer;background:var(--bg2)}
|
| 239 |
+
.segtog:hover{background:var(--bg)}
|
| 240 |
+
.segarr{font-size:11px;color:var(--ink3);transition:transform .2s}.segarr.op{transform:rotate(180deg)}
|
| 241 |
+
.seglist{display:none}
|
| 242 |
+
.segitem{display:flex;gap:10px;padding:9px 16px;border-bottom:1px solid var(--line);font-size:13px}
|
| 243 |
+
.segitem:last-child{border-bottom:none}
|
| 244 |
+
.segtime{color:var(--acc);font-family:'JetBrains Mono',monospace;font-size:11px;width:78px;flex-shrink:0;padding-top:2px}
|
| 245 |
+
.segtxt{color:var(--ink2);flex:1;line-height:1.5}
|
| 246 |
+
.segcp{opacity:0;background:none;border:none;color:var(--ink3);cursor:pointer;font-size:11px;transition:opacity .12s}
|
| 247 |
+
.segitem:hover .segcp{opacity:1}
|
| 248 |
+
|
| 249 |
+
/* clouds */
|
| 250 |
+
.cloud{display:flex;flex-wrap:wrap;gap:7px;padding:16px}
|
| 251 |
+
.tag{border-radius:100px;padding:5px 12px;font-size:13px;font-weight:500;cursor:pointer;transition:all .12s}
|
| 252 |
+
.tag.kw{background:var(--bg);border:1px solid var(--line2);color:var(--ink2)}
|
| 253 |
+
.tag.kw.top{background:var(--acc-soft);border-color:transparent;color:var(--acc-d);font-weight:600}
|
| 254 |
+
.tag.ht{background:#eef6ff;border:1px solid #cfe4ff;color:#1d6fd4}
|
| 255 |
+
.tag.ht:hover{background:#dcecff}
|
| 256 |
+
.tag.ht.cp{background:#f0fdf4;border-color:#bbf7d0;color:var(--ok)}
|
| 257 |
+
|
| 258 |
+
/* list items (hooks, ideas, titles) */
|
| 259 |
+
.litem{display:flex;align-items:center;gap:12px;padding:13px 16px;border-bottom:1px solid var(--line);transition:background .1s}
|
| 260 |
+
.litem:last-child{border-bottom:none}
|
| 261 |
+
.litem:hover{background:var(--bg)}
|
| 262 |
+
.litem .num{font-family:'Fraunces',serif;font-size:1.1rem;font-weight:600;color:var(--acc-soft);width:26px;flex-shrink:0}
|
| 263 |
+
.litem .txt{flex:1;font-size:14px;line-height:1.45}
|
| 264 |
+
.fmt-badge{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;padding:3px 8px;border-radius:100px;background:var(--acc-soft);color:var(--acc-d);flex-shrink:0}
|
| 265 |
+
|
| 266 |
+
/* tweet cards */
|
| 267 |
+
.tw{background:var(--bg2);border:1px solid var(--line2);border-radius:var(--r);padding:14px 16px;margin-bottom:8px;font-size:14px;line-height:1.6;white-space:pre-wrap}
|
| 268 |
+
|
| 269 |
+
/* download cards */
|
| 270 |
+
.dlg{display:grid;grid-template-columns:1fr 1fr;gap:10px;padding:16px}
|
| 271 |
+
@media(max-width:560px){.dlg{grid-template-columns:1fr}}
|
| 272 |
+
.dlc{background:var(--bg2);border:1px solid var(--line2);border-radius:var(--r);padding:15px;display:flex;flex-direction:column;gap:6px}
|
| 273 |
+
.dlc .i{font-size:22px}.dlc .n{font-weight:700;font-size:14px}.dlc .d{font-size:12px;color:var(--ink3);line-height:1.4}
|
| 274 |
+
|
| 275 |
+
/* bio cards */
|
| 276 |
+
.biocard{background:var(--bg2);border:1px solid var(--line2);border-radius:var(--r);padding:16px;margin-bottom:10px;white-space:pre-wrap;font-size:14px;line-height:1.6;position:relative}
|
| 277 |
+
.biocard .cp{position:absolute;top:12px;right:12px}
|
| 278 |
+
|
| 279 |
+
/* empty */
|
| 280 |
+
.empty{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:64px 24px;text-align:center;gap:14px}
|
| 281 |
+
.empty .g{width:88px;height:88px;border-radius:50%;background:radial-gradient(circle,var(--acc-soft),transparent 72%);display:flex;align-items:center;justify-content:center;font-size:38px}
|
| 282 |
+
.empty h3{font-family:'Fraunces',serif;font-size:1.4rem;font-weight:600}
|
| 283 |
+
.empty p{font-size:14px;color:var(--ink2);max-width:340px;line-height:1.55}
|
| 284 |
+
|
| 285 |
+
/* hint banner */
|
| 286 |
+
.hint{background:var(--acc-soft);border:1px solid #d9d0ff;border-radius:var(--rs);padding:11px 14px;font-size:13px;color:var(--acc-d);line-height:1.5;margin-bottom:18px}
|
| 287 |
+
.hint b{font-weight:700}
|
| 288 |
+
</style>
|
| 289 |
+
</head>
|
| 290 |
+
<body>
|
| 291 |
+
|
| 292 |
+
<!-- ═══════════════ LANDING VIEW ═══════════════ -->
|
| 293 |
+
<div class="view on" id="view-landing">
|
| 294 |
+
|
| 295 |
+
<nav class="nav">
|
| 296 |
+
<div class="brand" onclick="goLanding()">
|
| 297 |
+
<div class="bmark">CK</div>
|
| 298 |
+
<span class="bname">CreatorKit</span>
|
| 299 |
+
</div>
|
| 300 |
+
<div class="nlinks">
|
| 301 |
+
<a class="nlink" href="#tools">Ferramentas</a>
|
| 302 |
+
<a class="nlink" href="#how">Como funciona</a>
|
| 303 |
+
<a class="nlink" href="#why">Por quê</a>
|
| 304 |
+
<button class="nbtn" onclick="openApp()">Abrir app →</button>
|
| 305 |
+
</div>
|
| 306 |
+
</nav>
|
| 307 |
+
|
| 308 |
+
<!-- HERO -->
|
| 309 |
+
<section class="hero">
|
| 310 |
+
<div class="hpill"><span class="dot"></span> 7 ferramentas · 100% local · sem mensalidade</div>
|
| 311 |
+
<h1 class="htitle">O kit completo<br>do <em>criador de conteúdo</em></h1>
|
| 312 |
+
<p class="hsub">Transcreva vídeos, gere hooks que prendem, descubra ideias, crie hashtags, bios e um calendário de postagens — tudo em um só lugar, em segundos.</p>
|
| 313 |
+
<div class="hcta">
|
| 314 |
+
<button class="btn-lg btn-primary" onclick="openApp()">Começar agora — é grátis</button>
|
| 315 |
+
<button class="btn-lg btn-ghost" onclick="document.getElementById('tools').scrollIntoView()">Ver ferramentas</button>
|
| 316 |
+
</div>
|
| 317 |
+
<div class="hnote">✦ Roda no seu computador · seus dados nunca saem da sua máquina</div>
|
| 318 |
+
|
| 319 |
+
<!-- HERO MOCK -->
|
| 320 |
+
<div class="hmock">
|
| 321 |
+
<div class="hmock-bar"><span class="c c1"></span><span class="c c2"></span><span class="c c3"></span><span class="u">creatorkit.app/estudio</span></div>
|
| 322 |
+
<div class="hmock-body">
|
| 323 |
+
<div class="hmock-l">
|
| 324 |
+
<div class="hmock-label">🎬 Estúdio de vídeo</div>
|
| 325 |
+
<div class="hmock-input">https://instagram.com/reel/...</div>
|
| 326 |
+
<div class="hmock-label">Gerando conteúdo</div>
|
| 327 |
+
<div class="hmock-line m"></div><div class="hmock-line s"></div><div class="hmock-line m"></div>
|
| 328 |
+
</div>
|
| 329 |
+
<div class="hmock-r">
|
| 330 |
+
<div class="hmock-label"># Hashtags geradas</div>
|
| 331 |
+
<div class="hmock-tags">
|
| 332 |
+
<span class="hmock-tag">#marketing</span><span class="hmock-tag">#conteúdo</span>
|
| 333 |
+
<span class="hmock-tag">#dicas</span><span class="hmock-tag">#viral</span>
|
| 334 |
+
<span class="hmock-tag">#reels</span><span class="hmock-tag">#criador</span>
|
| 335 |
+
<span class="hmock-tag">#engajamento</span><span class="hmock-tag">#instagram</span>
|
| 336 |
+
</div>
|
| 337 |
+
</div>
|
| 338 |
+
</div>
|
| 339 |
+
</div>
|
| 340 |
+
</section>
|
| 341 |
+
|
| 342 |
+
<!-- TRUST -->
|
| 343 |
+
<section class="trust">
|
| 344 |
+
<div class="trust-l">Tudo que você posta, em um fluxo só</div>
|
| 345 |
+
<div class="trust-row">
|
| 346 |
+
<span>📸 Instagram</span><span>▶️ YouTube</span><span>🎵 TikTok</span>
|
| 347 |
+
<span>𝕏 Twitter</span><span>💼 LinkedIn</span><span>📰 Blog</span>
|
| 348 |
+
</div>
|
| 349 |
+
</section>
|
| 350 |
+
|
| 351 |
+
<!-- TOOLS / FEATURES -->
|
| 352 |
+
<section class="sec" id="tools">
|
| 353 |
+
<div class="sec-head">
|
| 354 |
+
<span class="sec-tag">Ferramentas</span>
|
| 355 |
+
<h2 class="sec-title">Seis ferramentas, um só painel</h2>
|
| 356 |
+
<p class="sec-sub">Cada uma resolve uma dor real de quem cria conteúdo todos os dias.</p>
|
| 357 |
+
</div>
|
| 358 |
+
<div class="fgrid" id="fgrid">
|
| 359 |
+
<div class="fcard" onclick="openApp('video')">
|
| 360 |
+
<div class="ficon" style="background:#ece8ff">🎬</div>
|
| 361 |
+
<div class="fname">Estúdio de Vídeo</div>
|
| 362 |
+
<div class="fdesc">Cole um link ou suba um arquivo. Gera transcrição, resumo, caption, thread, post de blog e mais — tudo do áudio do vídeo.</div>
|
| 363 |
+
<span class="farrow">→</span>
|
| 364 |
+
</div>
|
| 365 |
+
<div class="fcard" onclick="openApp('hooks')">
|
| 366 |
+
<div class="ficon" style="background:#fde8f1">🪝</div>
|
| 367 |
+
<div class="fname">Gerador de Hooks</div>
|
| 368 |
+
<div class="fdesc">As primeiras frases decidem se alguém assiste ou rola pra baixo. Gere 10 ganchos prontos a partir do seu tema.</div>
|
| 369 |
+
<span class="farrow">→</span>
|
| 370 |
+
</div>
|
| 371 |
+
<div class="fcard" onclick="openApp('ideas')">
|
| 372 |
+
<div class="ficon" style="background:#fef3c7">💡</div>
|
| 373 |
+
<div class="fname">Ideias de Conteúdo</div>
|
| 374 |
+
<div class="fdesc">Nunca mais trave na frente da câmera. Receba 9 pautas com formato sugerido (Reels, Carrossel, Story, YouTube).</div>
|
| 375 |
+
<span class="farrow">→</span>
|
| 376 |
+
</div>
|
| 377 |
+
<div class="fcard" onclick="openApp('script')">
|
| 378 |
+
<div class="ficon" style="background:#e0e7ff">📝</div>
|
| 379 |
+
<div class="fname">Roteiro de Vídeo</div>
|
| 380 |
+
<div class="fdesc">Da ideia à gravação: receba um roteiro completo com gancho, desenvolvimento, virada e chamada pra ação, dividido por blocos.</div>
|
| 381 |
+
<span class="farrow">→</span>
|
| 382 |
+
</div>
|
| 383 |
+
<div class="fcard" onclick="openApp('hashtags')">
|
| 384 |
+
<div class="ficon" style="background:#e0f2fe">#️⃣</div>
|
| 385 |
+
<div class="fname">Hashtags por Tema</div>
|
| 386 |
+
<div class="fdesc">Digite um tópico e receba hashtags relevantes, misturando palavras-chave e tags de nicho. Clique pra copiar.</div>
|
| 387 |
+
<span class="farrow">→</span>
|
| 388 |
+
</div>
|
| 389 |
+
<div class="fcard" onclick="openApp('bio')">
|
| 390 |
+
<div class="ficon" style="background:#dcfce7">✍️</div>
|
| 391 |
+
<div class="fname">Bio de Perfil</div>
|
| 392 |
+
<div class="fdesc">Gere variações de bio otimizadas para Instagram e TikTok, com emojis, proposta de valor e chamada pra ação.</div>
|
| 393 |
+
<span class="farrow">→</span>
|
| 394 |
+
</div>
|
| 395 |
+
<div class="fcard" onclick="openApp('calendar')">
|
| 396 |
+
<div class="ficon" style="background:#ffe4e6">📅</div>
|
| 397 |
+
<div class="fname">Calendário de Posts</div>
|
| 398 |
+
<div class="fdesc">Um plano semanal de postagem pronto, com tema, formato e melhor horário para cada dia da semana.</div>
|
| 399 |
+
<span class="farrow">→</span>
|
| 400 |
+
</div>
|
| 401 |
+
</div>
|
| 402 |
+
</section>
|
| 403 |
+
|
| 404 |
+
<!-- HOW IT WORKS -->
|
| 405 |
+
<section class="sec" id="how" style="background:var(--bg2);border-top:1px solid var(--line);border-bottom:1px solid var(--line);max-width:none">
|
| 406 |
+
<div style="max-width:1120px;margin:0 auto">
|
| 407 |
+
<div class="sec-head">
|
| 408 |
+
<span class="sec-tag">Como funciona</span>
|
| 409 |
+
<h2 class="sec-title">Do link ao post em 3 passos</h2>
|
| 410 |
+
</div>
|
| 411 |
+
<div class="steps3">
|
| 412 |
+
<div class="s3"><h4>Cole ou escreva</h4><p>Um link de vídeo, um arquivo do seu PC, ou só o tema sobre o qual você quer falar.</p></div>
|
| 413 |
+
<div class="s3"><h4>A mágica acontece</h4><p>O CreatorKit processa localmente e gera todo o material — sem enviar nada para a nuvem.</p></div>
|
| 414 |
+
<div class="s3"><h4>Copie e publique</h4><p>Cada bloco tem um botão de copiar. Leve direto para o Instagram, YouTube ou onde quiser.</p></div>
|
| 415 |
+
</div>
|
| 416 |
+
</div>
|
| 417 |
+
</section>
|
| 418 |
+
|
| 419 |
+
<!-- WHY -->
|
| 420 |
+
<section class="sec" id="why">
|
| 421 |
+
<div class="sec-head">
|
| 422 |
+
<span class="sec-tag">Por quê</span>
|
| 423 |
+
<h2 class="sec-title">Feito para quem posta de verdade</h2>
|
| 424 |
+
</div>
|
| 425 |
+
<div class="fgrid">
|
| 426 |
+
<div class="fcard" style="cursor:default">
|
| 427 |
+
<div class="ficon" style="background:#dcfce7">🔒</div>
|
| 428 |
+
<div class="fname">100% privado</div>
|
| 429 |
+
<div class="fdesc">Roda no seu computador. Nenhum vídeo, áudio ou texto é enviado para servidores externos.</div>
|
| 430 |
+
</div>
|
| 431 |
+
<div class="fcard" style="cursor:default">
|
| 432 |
+
<div class="ficon" style="background:#fef3c7">⚡</div>
|
| 433 |
+
<div class="fname">Sem mensalidade</div>
|
| 434 |
+
<div class="fdesc">Esqueça assinaturas caras de IA. Aqui você gera quanto conteúdo quiser, sem limite e sem custo.</div>
|
| 435 |
+
</div>
|
| 436 |
+
<div class="fcard" style="cursor:default">
|
| 437 |
+
<div class="ficon" style="background:#ece8ff">🎯</div>
|
| 438 |
+
<div class="fname">Tudo num lugar</div>
|
| 439 |
+
<div class="fdesc">Pare de pular entre cinco apps diferentes. Transcrição, hooks, ideias e planejamento no mesmo painel.</div>
|
| 440 |
+
</div>
|
| 441 |
+
</div>
|
| 442 |
+
</section>
|
| 443 |
+
|
| 444 |
+
<!-- CTA -->
|
| 445 |
+
<div class="cta-band">
|
| 446 |
+
<div class="cta-inner">
|
| 447 |
+
<h2>Pronto pra criar<br>sem travar?</h2>
|
| 448 |
+
<p>Abra o painel e gere seu primeiro pacote de conteúdo agora mesmo.</p>
|
| 449 |
+
<button class="btn-lg btn-primary" onclick="openApp()" style="position:relative">Abrir CreatorKit →</button>
|
| 450 |
+
</div>
|
| 451 |
+
</div>
|
| 452 |
+
|
| 453 |
+
<footer class="foot">
|
| 454 |
+
<div class="foot-in">
|
| 455 |
+
<div class="brand"><div class="bmark">CK</div><span class="bname">CreatorKit</span></div>
|
| 456 |
+
<div class="foot-c">Feito para criadores · Processamento 100% local · <span id="ano"></span></div>
|
| 457 |
+
</div>
|
| 458 |
+
</footer>
|
| 459 |
+
</div>
|
| 460 |
+
|
| 461 |
+
<!-- ═══════════════ APP VIEW ═══════════════ -->
|
| 462 |
+
<div class="view" id="view-app">
|
| 463 |
+
<div class="app-shell">
|
| 464 |
+
|
| 465 |
+
<!-- SIDEBAR -->
|
| 466 |
+
<aside class="app-side">
|
| 467 |
+
<div class="app-side-top" onclick="goLanding()">
|
| 468 |
+
<div class="bmark">CK</div>
|
| 469 |
+
<span class="bname" style="font-size:17px">CreatorKit</span>
|
| 470 |
+
</div>
|
| 471 |
+
<nav class="tool-nav">
|
| 472 |
+
<div class="tn-label">Ferramentas</div>
|
| 473 |
+
<div class="tn on" data-tool="video"><span class="tn-ico">🎬</span> Estúdio de Vídeo</div>
|
| 474 |
+
<div class="tn" data-tool="hooks"><span class="tn-ico">🪝</span> Gerador de Hooks</div>
|
| 475 |
+
<div class="tn" data-tool="ideas"><span class="tn-ico">💡</span> Ideias de Conteúdo</div>
|
| 476 |
+
<div class="tn" data-tool="script"><span class="tn-ico">📝</span> Roteiro de Vídeo</div>
|
| 477 |
+
<div class="tn" data-tool="hashtags"><span class="tn-ico">#️⃣</span> Hashtags por Tema</div>
|
| 478 |
+
<div class="tn" data-tool="bio"><span class="tn-ico">✍️</span> Bio de Perfil</div>
|
| 479 |
+
<div class="tn" data-tool="calendar"><span class="tn-ico">📅</span> Calendário de Posts</div>
|
| 480 |
+
<div class="tn-label">Geral</div>
|
| 481 |
+
<div class="tn" onclick="goLanding()"><span class="tn-ico">←</span> Voltar ao início</div>
|
| 482 |
+
</nav>
|
| 483 |
+
</aside>
|
| 484 |
+
|
| 485 |
+
<!-- MAIN -->
|
| 486 |
+
<main class="app-main">
|
| 487 |
+
<div class="app-head">
|
| 488 |
+
<div class="app-h-title" id="app-title">Estúdio de Vídeo</div>
|
| 489 |
+
<div class="app-h-sub" id="app-sub">Transcreva e transforme qualquer vídeo em conteúdo para todas as redes.</div>
|
| 490 |
+
</div>
|
| 491 |
+
<div class="app-body">
|
| 492 |
+
|
| 493 |
+
<!-- ════ TOOL: VIDEO ════ -->
|
| 494 |
+
<div class="tool-pane on" id="tool-video">
|
| 495 |
+
<div class="card-grid">
|
| 496 |
+
<!-- INPUT -->
|
| 497 |
+
<div class="panel">
|
| 498 |
+
<div class="itabs">
|
| 499 |
+
<div class="itab on" data-for="url">🔗 Link</div>
|
| 500 |
+
<div class="itab" data-for="file">📂 Arquivo</div>
|
| 501 |
+
</div>
|
| 502 |
+
<div class="tpane on" id="pane-url">
|
| 503 |
+
<div class="fld">
|
| 504 |
+
<span class="fld-l">URL do vídeo</span>
|
| 505 |
+
<div class="urlw">
|
| 506 |
+
<span class="pl" id="plat-ico">🔗</span>
|
| 507 |
+
<input class="inp" type="url" id="url-inp" placeholder="Cole o link aqui..." autocomplete="off" spellcheck="false"/>
|
| 508 |
+
<button class="pbtn" id="paste-btn">Colar</button>
|
| 509 |
+
</div>
|
| 510 |
+
</div>
|
| 511 |
+
<div id="info-load" style="font-size:12px;color:var(--ink3);display:none">⏳ Buscando...</div>
|
| 512 |
+
<div class="vprev" id="vprev"><img id="vthumb" src="" alt=""/><div><div class="t" id="vtitle"></div><div class="m" id="vmeta"></div></div></div>
|
| 513 |
+
</div>
|
| 514 |
+
<div class="tpane" id="pane-file">
|
| 515 |
+
<div class="dz" id="dz"><div class="i">📁</div><div class="l">Arraste ou clique para selecionar</div><div class="s">MP4, MOV, MP3, WAV — até 2 GB</div></div>
|
| 516 |
+
<input type="file" id="fi" accept="video/*,audio/*" style="display:none"/>
|
| 517 |
+
<div class="fchosen" id="fcho"><span id="fname" style="flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"></span><button class="fx" id="fclr">✕</button></div>
|
| 518 |
+
</div>
|
| 519 |
+
<div class="row2" style="margin-top:8px">
|
| 520 |
+
<div class="fld" style="margin-bottom:0">
|
| 521 |
+
<span class="fld-l">Modelo</span>
|
| 522 |
+
<select class="sel" id="model-sel">
|
| 523 |
+
<option value="Xenova/whisper-tiny">Tiny — rápido</option>
|
| 524 |
+
<option value="Xenova/whisper-base">Base</option>
|
| 525 |
+
<option value="Xenova/whisper-small" selected>Small ✦</option>
|
| 526 |
+
<option value="Xenova/whisper-medium">Medium</option>
|
| 527 |
+
<option value="Xenova/whisper-large-v3">Large</option>
|
| 528 |
+
</select>
|
| 529 |
+
</div>
|
| 530 |
+
<div class="fld" style="margin-bottom:0">
|
| 531 |
+
<span class="fld-l">Idioma</span>
|
| 532 |
+
<select class="sel" id="lang-sel">
|
| 533 |
+
<option value="auto">🌐 Auto</option><option value="pt">🇧🇷 PT</option><option value="en">🇺🇸 EN</option>
|
| 534 |
+
<option value="es">🇪🇸 ES</option><option value="fr">🇫🇷 FR</option><option value="de">🇩🇪 DE</option>
|
| 535 |
+
<option value="it">🇮🇹 IT</option><option value="ja">🇯🇵 JA</option>
|
| 536 |
+
</select>
|
| 537 |
+
</div>
|
| 538 |
+
</div>
|
| 539 |
+
<div class="fld" style="margin-top:12px">
|
| 540 |
+
<span class="fld-l">Modo</span>
|
| 541 |
+
<div class="itabs" style="margin-bottom:0">
|
| 542 |
+
<div class="itab on" data-task="transcribe">📝 Transcrever</div>
|
| 543 |
+
<div class="itab" data-task="translate">🌍 Traduzir → EN</div>
|
| 544 |
+
</div>
|
| 545 |
+
</div>
|
| 546 |
+
<button class="run-btn" id="proc-btn" style="margin-top:16px">⚡ Processar vídeo</button>
|
| 547 |
+
<div class="pg" id="pg">
|
| 548 |
+
<div class="steps">
|
| 549 |
+
<div class="step" id="s0"><div class="sc"></div><div class="slb">Baixar</div></div>
|
| 550 |
+
<div class="step" id="s1"><div class="sc"></div><div class="slb">Extrair</div></div>
|
| 551 |
+
<div class="step" id="s2"><div class="sc"></div><div class="slb">Transcrever</div></div>
|
| 552 |
+
<div class="step" id="s3"><div class="sc"></div><div class="slb">Gerar</div></div>
|
| 553 |
+
</div>
|
| 554 |
+
</div>
|
| 555 |
+
<div class="errbox" id="errbox"></div>
|
| 556 |
+
<button class="btn pri" id="demo-btn" style="width:100%;margin-top:12px;justify-content:center;padding:10px">▶ Ver demonstração de exemplo</button>
|
| 557 |
+
</div>
|
| 558 |
+
|
| 559 |
+
<!-- OUTPUT -->
|
| 560 |
+
<div class="panel" style="padding:0;overflow:hidden">
|
| 561 |
+
<div class="empty" id="v-empty">
|
| 562 |
+
<div class="g">✦</div>
|
| 563 |
+
<h3>Seu conteúdo aparece aqui</h3>
|
| 564 |
+
<p>Processe um vídeo ou clique em "Ver demonstração" para ver as 9 abas de conteúdo geradas.</p>
|
| 565 |
+
</div>
|
| 566 |
+
<div class="outc" id="outc" style="padding:20px">
|
| 567 |
+
<div class="sbar" id="sbar"></div>
|
| 568 |
+
<div class="otnav">
|
| 569 |
+
<div class="otab on" data-tab="transcript">📝 Texto</div>
|
| 570 |
+
<div class="otab" data-tab="summary">✨ Resumo</div>
|
| 571 |
+
<div class="otab" data-tab="instagram">📸 Instagram</div>
|
| 572 |
+
<div class="otab" data-tab="youtube">▶️ YouTube</div>
|
| 573 |
+
<div class="otab" data-tab="twitter">🐦 Twitter</div>
|
| 574 |
+
<div class="otab" data-tab="linkedin">💼 LinkedIn</div>
|
| 575 |
+
<div class="otab" data-tab="blog">📰 Blog</div>
|
| 576 |
+
<div class="otab" data-tab="hashtags">#️⃣ Tags</div>
|
| 577 |
+
<div class="otab" data-tab="downloads">⬇️ Baixar</div>
|
| 578 |
+
</div>
|
| 579 |
+
<div class="opanels">
|
| 580 |
+
<div class="opanel on" id="panel-transcript">
|
| 581 |
+
<div class="srchw"><span class="sico">🔍</span><input class="srchi" id="srch" placeholder="Buscar..."/><span class="scnt" id="scnt"></span></div>
|
| 582 |
+
<div class="cb">
|
| 583 |
+
<div class="cbh"><span class="cbt">Transcrição</span><div class="cba"><button class="btn pri" id="cpy-tr">📋 Copiar</button><button class="btn" id="exp-txt">.txt</button><button class="btn" id="exp-srt">.srt</button><button class="btn" id="exp-json">.json</button></div></div>
|
| 584 |
+
<div class="cbb mono" id="trbody"></div>
|
| 585 |
+
<div class="segtog" id="segtog"><span class="cbt">Segmentos com tempo</span><span class="segarr" id="segarr">▼</span></div>
|
| 586 |
+
<div class="seglist" id="seglist"></div>
|
| 587 |
+
</div>
|
| 588 |
+
</div>
|
| 589 |
+
<div class="opanel" id="panel-summary">
|
| 590 |
+
<div class="cb"><div class="cbh"><span class="cbt">Resumo</span><div class="cba"><button class="btn pri" onclick="cpEl('sumbody',this)">📋 Copiar</button></div></div><div class="cbb" id="sumbody"></div></div>
|
| 591 |
+
<div class="cb"><div class="cbh"><span class="cbt">Palavras-chave</span></div><div class="cloud" id="kwcloud"></div></div>
|
| 592 |
+
</div>
|
| 593 |
+
<div class="opanel" id="panel-instagram"><div class="cb"><div class="cbh"><span class="cbt">Caption Instagram</span><div class="cba"><button class="btn pri" onclick="cpEl('igbody',this)">📋 Copiar</button></div></div><div class="cbb" id="igbody"></div></div></div>
|
| 594 |
+
<div class="opanel" id="panel-youtube">
|
| 595 |
+
<div class="cb"><div class="cbh"><span class="cbt">Sugestões de título</span></div><div id="yttitles"></div></div>
|
| 596 |
+
<div class="cb"><div class="cbh"><span class="cbt">Descrição + capítulos</span><div class="cba"><button class="btn pri" onclick="cpEl('ytdesc',this)">📋 Copiar</button></div></div><div class="cbb mono" id="ytdesc"></div></div>
|
| 597 |
+
<div class="cb"><div class="cbh"><span class="cbt">Tags</span><div class="cba"><button class="btn sm" onclick="cpEl('yttags',this)">📋</button></div></div><div class="cbb" id="yttags" style="color:var(--ink2);font-size:13px"></div></div>
|
| 598 |
+
</div>
|
| 599 |
+
<div class="opanel" id="panel-twitter">
|
| 600 |
+
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px"><span class="cbt">Thread Twitter/X</span><button class="btn pri" id="cpy-thread">📋 Copiar thread</button></div>
|
| 601 |
+
<div id="twlist"></div>
|
| 602 |
+
</div>
|
| 603 |
+
<div class="opanel" id="panel-linkedin"><div class="cb"><div class="cbh"><span class="cbt">Post LinkedIn</span><div class="cba"><button class="btn pri" onclick="cpEl('libody',this)">📋 Copiar</button></div></div><div class="cbb" id="libody"></div></div></div>
|
| 604 |
+
<div class="opanel" id="panel-blog"><div class="cb"><div class="cbh"><span class="cbt">Post de Blog (Markdown)</span><div class="cba"><button class="btn pri" onclick="cpEl('blbody',this)">📋 Copiar</button><button class="btn" id="exp-md">.md</button></div></div><div class="cbb mono" id="blbody"></div></div></div>
|
| 605 |
+
<div class="opanel" id="panel-hashtags">
|
| 606 |
+
<div class="cb"><div class="cbh"><span class="cbt">Hashtags</span><div class="cba"><button class="btn pri" id="cpy-tags">📋 Copiar todas</button></div></div><div class="cloud" id="htcloud"></div></div>
|
| 607 |
+
</div>
|
| 608 |
+
<div class="opanel" id="panel-downloads">
|
| 609 |
+
<div class="cb"><div class="cbh"><span class="cbt">Mídia original</span></div>
|
| 610 |
+
<div class="dlg" id="dlmedia">
|
| 611 |
+
<div class="dlc"><div class="i">🎞️</div><div class="n">Vídeo MP4</div><div class="d">Baixar o vídeo original</div><button class="btn pri" id="dl-vid" style="margin-top:4px;justify-content:center">Baixar vídeo</button></div>
|
| 612 |
+
<div class="dlc"><div class="i">🎵</div><div class="n">Áudio MP3</div><div class="d">Áudio em 192kbps</div><button class="btn" id="dl-aud" style="margin-top:4px;justify-content:center">Baixar áudio</button></div>
|
| 613 |
+
</div>
|
| 614 |
+
<div id="dlnote" style="display:none;padding:16px;font-size:13px;color:var(--ink3)">Arquivo local — download de mídia indisponível.</div>
|
| 615 |
+
</div>
|
| 616 |
+
<div class="cb"><div class="cbh"><span class="cbt">Exportar transcrição</span></div>
|
| 617 |
+
<div class="dlg">
|
| 618 |
+
<div class="dlc"><div class="i">📄</div><div class="n">.txt</div><div class="d">Texto puro</div><button class="btn" onclick="expTxt()" style="margin-top:4px;justify-content:center">Baixar</button></div>
|
| 619 |
+
<div class="dlc"><div class="i">🎬</div><div class="n">.srt</div><div class="d">Legenda c/ tempo</div><button class="btn" onclick="expSrt()" style="margin-top:4px;justify-content:center">Baixar</button></div>
|
| 620 |
+
<div class="dlc"><div class="i">📦</div><div class="n">.json</div><div class="d">Dados + análise</div><button class="btn" onclick="expJson()" style="margin-top:4px;justify-content:center">Baixar</button></div>
|
| 621 |
+
<div class="dlc"><div class="i">📝</div><div class="n">.md</div><div class="d">Post de blog</div><button class="btn" onclick="expMd()" style="margin-top:4px;justify-content:center">Baixar</button></div>
|
| 622 |
+
</div>
|
| 623 |
+
</div>
|
| 624 |
+
</div>
|
| 625 |
+
</div>
|
| 626 |
+
</div>
|
| 627 |
+
</div>
|
| 628 |
+
</div>
|
| 629 |
+
</div>
|
| 630 |
+
|
| 631 |
+
<!-- ════ TOOL: HOOKS ════ -->
|
| 632 |
+
<div class="tool-pane" id="tool-hooks">
|
| 633 |
+
<div class="card-grid">
|
| 634 |
+
<div class="panel">
|
| 635 |
+
<div class="hint">🪝 <b>Hooks</b> são as primeiras frases do seu vídeo ou post. Elas decidem se a pessoa continua ou rola pra baixo.</div>
|
| 636 |
+
<div class="fld"><span class="fld-l">Sobre o que é o conteúdo?</span><input class="inp" id="hook-inp" placeholder="ex: marketing digital, treino em casa, finanças..."/></div>
|
| 637 |
+
<button class="run-btn" id="hook-btn">🪝 Gerar 10 hooks</button>
|
| 638 |
+
</div>
|
| 639 |
+
<div class="panel" style="padding:0;overflow:hidden">
|
| 640 |
+
<div class="empty" id="hook-empty"><div class="g">🪝</div><h3>Ganchos que prendem</h3><p>Digite um tema e gere 10 aberturas testadas para seus vídeos e posts.</p></div>
|
| 641 |
+
<div class="cb" id="hook-out" style="display:none;margin:0;border:none"><div class="cbh"><span class="cbt">10 hooks gerados</span><button class="btn pri" id="hook-cpy">📋 Copiar todos</button></div><div id="hook-list"></div></div>
|
| 642 |
+
</div>
|
| 643 |
+
</div>
|
| 644 |
+
</div>
|
| 645 |
+
|
| 646 |
+
<!-- ════ TOOL: IDEAS ════ -->
|
| 647 |
+
<div class="tool-pane" id="tool-ideas">
|
| 648 |
+
<div class="card-grid">
|
| 649 |
+
<div class="panel">
|
| 650 |
+
<div class="hint">💡 Receba pautas prontas com o <b>formato ideal</b> sugerido para cada uma.</div>
|
| 651 |
+
<div class="fld"><span class="fld-l">Qual é o seu nicho?</span><input class="inp" id="idea-inp" placeholder="ex: culinária fitness, viagens, tecnologia..."/></div>
|
| 652 |
+
<button class="run-btn" id="idea-btn">💡 Gerar 9 ideias</button>
|
| 653 |
+
</div>
|
| 654 |
+
<div class="panel" style="padding:0;overflow:hidden">
|
| 655 |
+
<div class="empty" id="idea-empty"><div class="g">💡</div><h3>Nunca mais trave</h3><p>Digite seu nicho e receba 9 ideias com formato sugerido (Reels, Carrossel, Story...).</p></div>
|
| 656 |
+
<div class="cb" id="idea-out" style="display:none;margin:0;border:none"><div class="cbh"><span class="cbt">Ideias de conteúdo</span><button class="btn pri" id="idea-cpy">📋 Copiar</button></div><div id="idea-list"></div></div>
|
| 657 |
+
</div>
|
| 658 |
+
</div>
|
| 659 |
+
</div>
|
| 660 |
+
|
| 661 |
+
<!-- ════ TOOL: SCRIPT ════ -->
|
| 662 |
+
<div class="tool-pane" id="tool-script">
|
| 663 |
+
<div class="card-grid">
|
| 664 |
+
<div class="panel">
|
| 665 |
+
<div class="hint">📝 Recebe um roteiro completo em blocos: <b>gancho → contexto → 3 pontos → virada → CTA</b>. Pronto pra gravar.</div>
|
| 666 |
+
<div class="fld"><span class="fld-l">Tema do vídeo</span><input class="inp" id="scr-inp" placeholder="ex: como economizar dinheiro, receita rápida..."/></div>
|
| 667 |
+
<div class="fld"><span class="fld-l">Formato</span><select class="sel" id="scr-fmt"><option value="reels">🎬 Reels / TikTok (curto)</option><option value="youtube">▶️ YouTube (com intro)</option></select></div>
|
| 668 |
+
<button class="run-btn" id="scr-btn">📝 Gerar roteiro</button>
|
| 669 |
+
</div>
|
| 670 |
+
<div class="panel" style="padding:0;overflow:hidden">
|
| 671 |
+
<div class="empty" id="scr-empty"><div class="g">📝</div><h3>Roteiro pronto pra gravar</h3><p>Digite o tema e receba um roteiro estruturado bloco a bloco, com dicas de direção.</p></div>
|
| 672 |
+
<div class="cb" id="scr-out" style="display:none;margin:0;border:none"><div class="cbh"><span class="cbt" id="scr-dur">Roteiro</span><button class="btn pri" id="scr-cpy">📋 Copiar roteiro</button></div><div id="scr-list"></div></div>
|
| 673 |
+
</div>
|
| 674 |
+
</div>
|
| 675 |
+
</div>
|
| 676 |
+
|
| 677 |
+
<!-- ════ TOOL: HASHTAGS ════ -->
|
| 678 |
+
<div class="tool-pane" id="tool-hashtags">
|
| 679 |
+
<div class="card-grid">
|
| 680 |
+
<div class="panel">
|
| 681 |
+
<div class="hint">#️⃣ Combina palavras-chave do seu tema com hashtags de nicho. <b>Clique em cada tag pra copiar.</b></div>
|
| 682 |
+
<div class="fld"><span class="fld-l">Tema ou descrição do post</span><textarea class="ta" id="ht-inp" placeholder="ex: dicas de produtividade para quem trabalha em casa"></textarea></div>
|
| 683 |
+
<button class="run-btn" id="ht-btn">#️⃣ Gerar hashtags</button>
|
| 684 |
+
</div>
|
| 685 |
+
<div class="panel" style="padding:0;overflow:hidden">
|
| 686 |
+
<div class="empty" id="ht-empty"><div class="g">#️⃣</div><h3>Tags relevantes</h3><p>Descreva o post e receba hashtags prontas para aumentar o alcance.</p></div>
|
| 687 |
+
<div class="cb" id="ht-out" style="display:none;margin:0;border:none"><div class="cbh"><span class="cbt">Hashtags</span><button class="btn pri" id="ht-cpy">📋 Copiar todas</button></div><div class="cloud" id="ht-cloud"></div></div>
|
| 688 |
+
</div>
|
| 689 |
+
</div>
|
| 690 |
+
</div>
|
| 691 |
+
|
| 692 |
+
<!-- ════ TOOL: BIO ════ -->
|
| 693 |
+
<div class="tool-pane" id="tool-bio">
|
| 694 |
+
<div class="card-grid">
|
| 695 |
+
<div class="panel">
|
| 696 |
+
<div class="hint">✍️ Gera <b>4 variações</b> de bio prontas para colar no seu perfil.</div>
|
| 697 |
+
<div class="fld"><span class="fld-l">Seu nome / marca (opcional)</span><input class="inp" id="bio-name" placeholder="ex: Ana Souza"/></div>
|
| 698 |
+
<div class="fld"><span class="fld-l">Seu nicho</span><input class="inp" id="bio-niche" placeholder="ex: finanças pessoais"/></div>
|
| 699 |
+
<div class="fld"><span class="fld-l">Chamada / link (opcional)</span><input class="inp" id="bio-cta" placeholder="ex: 👇 Baixe meu e-book grátis"/></div>
|
| 700 |
+
<button class="run-btn" id="bio-btn">✍️ Gerar bios</button>
|
| 701 |
+
</div>
|
| 702 |
+
<div class="panel" style="padding:0;overflow:hidden">
|
| 703 |
+
<div class="empty" id="bio-empty"><div class="g">✍️</div><h3>Bio que converte</h3><p>Preencha seu nicho e receba variações otimizadas com emojis e CTA.</p></div>
|
| 704 |
+
<div id="bio-out" style="display:none;padding:20px"></div>
|
| 705 |
+
</div>
|
| 706 |
+
</div>
|
| 707 |
+
</div>
|
| 708 |
+
|
| 709 |
+
<!-- ════ TOOL: CALENDAR ════ -->
|
| 710 |
+
<div class="tool-pane" id="tool-calendar">
|
| 711 |
+
<div class="card-grid">
|
| 712 |
+
<div class="panel">
|
| 713 |
+
<div class="hint">📅 Monta um <b>plano semanal</b> com tema, formato e melhor horário por dia.</div>
|
| 714 |
+
<div class="fld"><span class="fld-l">Seu nicho</span><input class="inp" id="cal-niche" placeholder="ex: moda sustentável"/></div>
|
| 715 |
+
<div class="fld"><span class="fld-l">Posts por semana</span><select class="sel" id="cal-freq"><option value="3">3 posts</option><option value="5" selected>5 posts</option><option value="7">7 posts (todo dia)</option></select></div>
|
| 716 |
+
<button class="run-btn" id="cal-btn">📅 Gerar calendário</button>
|
| 717 |
+
</div>
|
| 718 |
+
<div class="panel" style="padding:0;overflow:hidden">
|
| 719 |
+
<div class="empty" id="cal-empty"><div class="g">📅</div><h3>Planejamento pronto</h3><p>Receba um cronograma semanal completo, dia a dia, pra nunca ficar sem postar.</p></div>
|
| 720 |
+
<div class="cb" id="cal-out" style="display:none;margin:0;border:none"><div class="cbh"><span class="cbt">Plano da semana</span><button class="btn pri" id="cal-cpy">📋 Copiar</button></div><div id="cal-list"></div></div>
|
| 721 |
+
</div>
|
| 722 |
+
</div>
|
| 723 |
+
</div>
|
| 724 |
+
|
| 725 |
+
</div>
|
| 726 |
+
</main>
|
| 727 |
+
</div>
|
| 728 |
+
</div>
|
| 729 |
+
|
| 730 |
+
<script>
|
| 731 |
+
const G=id=>document.getElementById(id);
|
| 732 |
+
const esc=s=>(s||'').replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
|
| 733 |
+
const fmt=s=>s==null?'?':`${Math.floor(s/60)}:${Math.floor(s%60).toString().padStart(2,'0')}`;
|
| 734 |
+
const pad=n=>n.toString().padStart(2,'0');
|
| 735 |
+
const wc=t=>t.trim().split(/\s+/).filter(Boolean).length;
|
| 736 |
+
function cpTxt(txt,btn,lbl){navigator.clipboard.writeText(txt).then(()=>{const o=btn.textContent;btn.textContent='✓ Copiado!';btn.classList.add('ok');setTimeout(()=>{btn.textContent=lbl||o;btn.classList.remove('ok');},1800);});}
|
| 737 |
+
function cpEl(id,btn){cpTxt(G(id).textContent,btn);}
|
| 738 |
+
function dl(blob,name){const a=Object.assign(document.createElement('a'),{href:URL.createObjectURL(blob),download:name});a.click();setTimeout(()=>URL.revokeObjectURL(a.href),5000);}
|
| 739 |
+
async function api(path,body){const r=await fetch(path,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(body)});const d=await r.json();if(d.error)throw new Error(d.error);return d;}
|
| 740 |
+
|
| 741 |
+
// fill year
|
| 742 |
+
G('ano').textContent=new Date().getFullYear();
|
| 743 |
+
|
| 744 |
+
// ════ VIEW ROUTING ════
|
| 745 |
+
function openApp(tool){G('view-landing').classList.remove('on');G('view-app').classList.add('on');window.scrollTo(0,0);if(tool)selectTool(tool);}
|
| 746 |
+
function goLanding(){G('view-app').classList.remove('on');G('view-landing').classList.add('on');window.scrollTo(0,0);}
|
| 747 |
+
window.openApp=openApp;window.goLanding=goLanding;window.cpEl=cpEl;
|
| 748 |
+
|
| 749 |
+
const TOOL_META={
|
| 750 |
+
video:{t:'Estúdio de Vídeo',s:'Transcreva e transforme qualquer vídeo em conteúdo para todas as redes.'},
|
| 751 |
+
hooks:{t:'Gerador de Hooks',s:'Crie aberturas que prendem a atenção nos primeiros segundos.'},
|
| 752 |
+
ideas:{t:'Ideias de Conteúdo',s:'Pautas prontas com o formato ideal para cada uma.'},
|
| 753 |
+
script:{t:'Roteiro de Vídeo',s:'Roteiro completo em blocos, da abertura à chamada pra ação.'},
|
| 754 |
+
hashtags:{t:'Hashtags por Tema',s:'Gere hashtags relevantes a partir de qualquer tópico.'},
|
| 755 |
+
bio:{t:'Bio de Perfil',s:'Variações de bio otimizadas para seu perfil.'},
|
| 756 |
+
calendar:{t:'Calendário de Posts',s:'Um plano semanal de postagem pronto pra usar.'},
|
| 757 |
+
};
|
| 758 |
+
function selectTool(name){
|
| 759 |
+
document.querySelectorAll('.tn[data-tool]').forEach(t=>t.classList.toggle('on',t.dataset.tool===name));
|
| 760 |
+
document.querySelectorAll('.tool-pane').forEach(p=>p.classList.remove('on'));
|
| 761 |
+
G(`tool-${name}`).classList.add('on');
|
| 762 |
+
G('app-title').textContent=TOOL_META[name].t;
|
| 763 |
+
G('app-sub').textContent=TOOL_META[name].s;
|
| 764 |
+
}
|
| 765 |
+
document.querySelectorAll('.tn[data-tool]').forEach(t=>t.addEventListener('click',()=>selectTool(t.dataset.tool)));
|
| 766 |
+
|
| 767 |
+
// ════════════════════ VIDEO STUDIO ════════════════════
|
| 768 |
+
const S={text:'',segs:[],analysis:null,url:'',vtitle:'',isFile:false,task:'transcribe',itab:'url',poll:null,file:null,segOpen:false};
|
| 769 |
+
|
| 770 |
+
const PLATS=[{re:/instagram\.com/,ico:'📸'},{re:/youtu\.?be/,ico:'▶️'},{re:/tiktok\.com/,ico:'🎵'},{re:/(twitter|x)\.com/,ico:'𝕏'},{re:/facebook\.com|fb\.watch/,ico:'📘'},{re:/twitch\.tv/,ico:'🟣'}];
|
| 771 |
+
const plat=u=>{for(const p of PLATS)if(p.re.test(u))return p;return{ico:'🔗'};};
|
| 772 |
+
|
| 773 |
+
document.querySelectorAll('#tool-video .itab[data-for]').forEach(t=>t.addEventListener('click',()=>{
|
| 774 |
+
document.querySelectorAll('#tool-video .itab[data-for]').forEach(x=>x.classList.remove('on'));
|
| 775 |
+
document.querySelectorAll('#tool-video .tpane').forEach(x=>x.classList.remove('on'));
|
| 776 |
+
t.classList.add('on');S.itab=t.dataset.for;G(`pane-${S.itab}`).classList.add('on');
|
| 777 |
+
}));
|
| 778 |
+
document.querySelectorAll('#tool-video .itab[data-task]').forEach(b=>b.addEventListener('click',()=>{
|
| 779 |
+
document.querySelectorAll('#tool-video .itab[data-task]').forEach(x=>x.classList.remove('on'));
|
| 780 |
+
b.classList.add('on');S.task=b.dataset.task;
|
| 781 |
+
}));
|
| 782 |
+
|
| 783 |
+
let infoT;
|
| 784 |
+
G('url-inp').addEventListener('input',()=>{
|
| 785 |
+
const u=G('url-inp').value.trim();G('plat-ico').textContent=plat(u).ico;G('vprev').classList.remove('on');
|
| 786 |
+
clearTimeout(infoT);if(u.startsWith('http'))infoT=setTimeout(()=>fetchInfo(u),900);
|
| 787 |
+
});
|
| 788 |
+
async function fetchInfo(u){G('info-load').style.display='block';try{const d=await api('/info',{url:u});if(d.title){G('vthumb').src=d.thumbnail||'';G('vthumb').style.display=d.thumbnail?'block':'none';G('vtitle').textContent=d.title.slice(0,75);G('vmeta').textContent=[d.uploader,d.duration?`⏱ ${fmt(d.duration)}`:''].filter(Boolean).join(' · ');G('vprev').classList.add('on');S.vtitle=d.title;}}catch{}G('info-load').style.display='none';}
|
| 789 |
+
G('paste-btn').addEventListener('click',async()=>{try{G('url-inp').value=await navigator.clipboard.readText();G('url-inp').dispatchEvent(new Event('input'));}catch{}});
|
| 790 |
+
|
| 791 |
+
G('dz').addEventListener('click',()=>G('fi').click());
|
| 792 |
+
G('dz').addEventListener('dragover',e=>{e.preventDefault();G('dz').classList.add('ov');});
|
| 793 |
+
G('dz').addEventListener('dragleave',()=>G('dz').classList.remove('ov'));
|
| 794 |
+
G('dz').addEventListener('drop',e=>{e.preventDefault();G('dz').classList.remove('ov');setFile(e.dataTransfer.files[0]);});
|
| 795 |
+
G('fi').addEventListener('change',()=>setFile(G('fi').files[0]));
|
| 796 |
+
G('fclr').addEventListener('click',()=>{S.file=null;G('fi').value='';G('fcho').classList.remove('on');});
|
| 797 |
+
function setFile(f){if(!f)return;S.file=f;G('fname').textContent=`📎 ${f.name} · ${(f.size/1024/1024).toFixed(1)} MB`;G('fcho').classList.add('on');}
|
| 798 |
+
|
| 799 |
+
const SMAP={downloading_ytdlp:0,downloading:0,extracting:1,transcribing:2,analyzing:3,done:'all'};
|
| 800 |
+
function setSteps(st){const a=SMAP[st];[0,1,2,3].forEach(i=>{const el=G(`s${i}`);el.classList.remove('ac','dn');if(a==='all')el.classList.add('dn');else if(i===a){el.classList.add('ac');for(let j=0;j<i;j++)G(`s${j}`).classList.add('dn');}});}
|
| 801 |
+
|
| 802 |
+
G('proc-btn').addEventListener('click',startProc);
|
| 803 |
+
G('url-inp').addEventListener('keydown',e=>{if(e.key==='Enter')startProc();});
|
| 804 |
+
async function startProc(){
|
| 805 |
+
G('errbox').style.display='none';G('outc').classList.remove('on');G('v-empty').style.display='flex';
|
| 806 |
+
G('pg').style.display='block';G('proc-btn').disabled=true;G('proc-btn').textContent='⏳ Processando...';
|
| 807 |
+
try{
|
| 808 |
+
let jobId;
|
| 809 |
+
if(S.itab==='url'){
|
| 810 |
+
const url=G('url-inp').value.trim();if(!url)throw new Error('Informe uma URL.');
|
| 811 |
+
S.url=url;S.isFile=false;setSteps('downloading');
|
| 812 |
+
const d=await api('/transcribe',{url,model:G('model-sel').value,language:G('lang-sel').value,task:S.task});jobId=d.job_id;
|
| 813 |
+
}else{
|
| 814 |
+
if(!S.file)throw new Error('Selecione um arquivo.');
|
| 815 |
+
S.url='';S.isFile=true;setSteps('extracting');
|
| 816 |
+
const fd=new FormData();fd.append('file',S.file);fd.append('model',G('model-sel').value);fd.append('language',G('lang-sel').value);fd.append('task',S.task);
|
| 817 |
+
const r=await fetch('/transcribe-file',{method:'POST',body:fd});const d=await r.json();if(d.error)throw new Error(d.error);jobId=d.job_id;
|
| 818 |
+
}
|
| 819 |
+
clearInterval(S.poll);S.poll=setInterval(()=>poll(jobId),2000);
|
| 820 |
+
}catch(e){showErr(e.message);}
|
| 821 |
+
}
|
| 822 |
+
async function poll(id){try{const job=await(await fetch(`/status/${id}`)).json();setSteps(job.status);if(job.status==='done'){clearInterval(S.poll);setSteps('analyzing');await build(job);}else if(job.status==='error'){clearInterval(S.poll);showErr(job.error||'Erro');}}catch{}}
|
| 823 |
+
async function build(job){
|
| 824 |
+
S.text=job.text||'';S.segs=job.segments||[];
|
| 825 |
+
try{const d=await api('/analyze',{text:S.text,segments:S.segs,title:S.vtitle});S.analysis=d;}catch{S.analysis=null;}
|
| 826 |
+
setSteps('done');G('pg').style.display='none';G('proc-btn').disabled=false;G('proc-btn').textContent='⚡ Processar vídeo';
|
| 827 |
+
G('v-empty').style.display='none';populate(job);G('outc').classList.add('on');switchTab('transcript');
|
| 828 |
+
}
|
| 829 |
+
function populate(job){
|
| 830 |
+
const c=[];if(job.language)c.push(`🌐 ${job.language.toUpperCase()}`);c.push(`📝 ${wc(S.text)} palavras`);if(S.segs.length)c.push(`⏱ ${fmt(S.segs.at(-1)?.end)}`);if(S.analysis?.stats)c.push(`📖 ~${S.analysis.stats.readingTime}min`);
|
| 831 |
+
G('sbar').innerHTML=c.map(x=>`<span class="schip">${esc(x)}</span>`).join('');
|
| 832 |
+
G('trbody').textContent=S.text;
|
| 833 |
+
const sl=G('seglist');sl.innerHTML='';
|
| 834 |
+
S.segs.forEach(s=>{const d=document.createElement('div');d.className='segitem';d.innerHTML=`<span class="segtime">${fmt(s.start)}→${fmt(s.end)}</span><span class="segtxt">${esc(s.text)}</span><button class="segcp">📋</button>`;d.querySelector('.segcp').onclick=e=>{navigator.clipboard.writeText(s.text);e.target.textContent='✓';setTimeout(()=>e.target.textContent='📋',1400);};sl.appendChild(d);});
|
| 835 |
+
if(S.analysis){
|
| 836 |
+
G('sumbody').textContent=S.analysis.summary||'';
|
| 837 |
+
const kc=G('kwcloud');kc.innerHTML='';(S.analysis.keywords||[]).forEach((k,i)=>{const sp=document.createElement('span');sp.className='tag kw'+(i<3?' top':'');sp.textContent=`${k.word} (${k.count})`;kc.appendChild(sp);});
|
| 838 |
+
G('igbody').textContent=S.analysis.instagram||'';
|
| 839 |
+
const yt=S.analysis.youtube||{};const tl=G('yttitles');tl.innerHTML='';(yt.titles||[]).forEach(t=>{const d=document.createElement('div');d.className='litem';d.innerHTML=`<span class="txt">${esc(t)}</span><button class="btn sm">📋</button>`;d.querySelector('button').onclick=e=>{navigator.clipboard.writeText(t);e.target.textContent='✓';setTimeout(()=>e.target.textContent='📋',1400);};tl.appendChild(d);});
|
| 840 |
+
G('ytdesc').textContent=yt.description||'';G('yttags').textContent=yt.tags||'';
|
| 841 |
+
const th=S.analysis.twitter||[];const tw=G('twlist');tw.innerHTML='';th.forEach(t=>{const d=document.createElement('div');d.className='tw';d.textContent=t;tw.appendChild(d);});
|
| 842 |
+
G('cpy-thread').onclick=()=>cpTxt(th.join('\n\n---\n\n'),G('cpy-thread'),'📋 Copiar thread');
|
| 843 |
+
G('libody').textContent=S.analysis.linkedin||'';G('blbody').textContent=S.analysis.blog||'';
|
| 844 |
+
const tags=S.analysis.hashtags||[];const hc=G('htcloud');hc.innerHTML='';tags.forEach(tag=>{const sp=document.createElement('span');sp.className='tag ht';sp.textContent=tag;sp.onclick=()=>{navigator.clipboard.writeText(tag);sp.classList.add('cp');setTimeout(()=>sp.classList.remove('cp'),1400);};hc.appendChild(sp);});
|
| 845 |
+
G('cpy-tags').onclick=()=>cpTxt(tags.join(' '),G('cpy-tags'),'📋 Copiar todas');
|
| 846 |
+
}
|
| 847 |
+
const has=!S.isFile&&S.url;G('dlmedia').style.display=has?'grid':'none';G('dlnote').style.display=has?'none':'block';
|
| 848 |
+
}
|
| 849 |
+
document.querySelectorAll('#tool-video .otab').forEach(t=>t.addEventListener('click',()=>switchTab(t.dataset.tab)));
|
| 850 |
+
function switchTab(n){document.querySelectorAll('#tool-video .otab').forEach(t=>t.classList.toggle('on',t.dataset.tab===n));document.querySelectorAll('#tool-video .opanel').forEach(p=>p.classList.remove('on'));const p=G(`panel-${n}`);if(p)p.classList.add('on');}
|
| 851 |
+
let sT;G('srch').addEventListener('input',()=>{clearTimeout(sT);sT=setTimeout(()=>{const q=G('srch').value.trim();if(!q){G('trbody').textContent=S.text;G('scnt').textContent='';return;}const re=new RegExp(`(${q.replace(/[.*+?^${}()|[\]\\]/g,'\\$&')})`,'gi');G('trbody').innerHTML=S.text.split(re).map(p=>re.test(p)?`<mark>${p}</mark>`:esc(p)).join('');const m=G('trbody').querySelectorAll('mark');G('scnt').textContent=m.length?`${m.length} result.`:'0';},200);});
|
| 852 |
+
G('segtog').addEventListener('click',()=>{S.segOpen=!S.segOpen;G('seglist').style.display=S.segOpen?'block':'none';G('segarr').classList.toggle('op',S.segOpen);});
|
| 853 |
+
G('cpy-tr').addEventListener('click',()=>cpTxt(S.text,G('cpy-tr'),'📋 Copiar'));
|
| 854 |
+
function toSrt(s){const h=Math.floor(s/3600),m=Math.floor((s%3600)/60),sec=Math.floor(s%60),ms=Math.round((s%1)*1000);return`${pad(h)}:${pad(m)}:${pad(sec)},${ms.toString().padStart(3,'0')}`;}
|
| 855 |
+
function expTxt(){dl(new Blob([S.text],{type:'text/plain;charset=utf-8'}),'transcricao.txt');}
|
| 856 |
+
function expSrt(){dl(new Blob([S.segs.map((s,i)=>`${i+1}\n${toSrt(s.start)} --> ${toSrt(s.end)}\n${s.text}\n`).join('\n')],{type:'text/plain;charset=utf-8'}),'transcricao.srt');}
|
| 857 |
+
function expJson(){dl(new Blob([JSON.stringify({text:S.text,segments:S.segs,analysis:S.analysis},null,2)],{type:'application/json'}),'creatorkit.json');}
|
| 858 |
+
function expMd(){dl(new Blob([S.analysis?.blog||S.text],{type:'text/plain;charset=utf-8'}),'post.md');}
|
| 859 |
+
window.expTxt=expTxt;window.expSrt=expSrt;window.expJson=expJson;window.expMd=expMd;
|
| 860 |
+
G('exp-txt').onclick=expTxt;G('exp-srt').onclick=expSrt;G('exp-json').onclick=expJson;G('exp-md').onclick=expMd;
|
| 861 |
+
async function mediaDl(ep,fn,btn,lbl){btn.classList.add('ld');btn.textContent='⏳ Baixando...';try{const r=await fetch(ep,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({url:S.url})});if(!r.ok)throw new Error((await r.json()).error);dl(await r.blob(),fn);btn.textContent='✓ Pronto!';}catch(e){btn.textContent='⚠️ Erro';showErr(e.message);}setTimeout(()=>{btn.textContent=lbl;btn.classList.remove('ld');},2500);}
|
| 862 |
+
G('dl-vid').onclick=()=>mediaDl('/download-video','video.mp4',G('dl-vid'),'Baixar vídeo');
|
| 863 |
+
G('dl-aud').onclick=()=>mediaDl('/download-audio','audio.mp3',G('dl-aud'),'Baixar áudio');
|
| 864 |
+
function showErr(m){G('proc-btn').disabled=false;G('proc-btn').textContent='⚡ Processar vídeo';G('pg').style.display='none';G('errbox').style.display='block';G('errbox').innerHTML=`<strong>⚠️ Erro</strong><br>${esc(m)}`;}
|
| 865 |
+
|
| 866 |
+
// demo
|
| 867 |
+
G('demo-btn').addEventListener('click',async()=>{
|
| 868 |
+
const b=G('demo-btn');b.classList.add('ld');b.textContent='⏳ Gerando...';
|
| 869 |
+
const t='Hoje eu vou te ensinar as três estratégias que mudaram completamente o meu Instagram. A primeira coisa que você precisa entender é que consistência vence talento. Postar todos os dias no mesmo horário treina o algoritmo a entregar o seu conteúdo. A segunda estratégia é dominar os primeiros três segundos do seu Reels, porque é nesse momento que a pessoa decide se vai continuar assistindo. Use uma pergunta forte ou um gancho visual. A terceira e mais importante é responder todos os comentários nos primeiros trinta minutos depois de postar. Isso aumenta o engajamento e mostra para a plataforma que o seu conteúdo gera conversa.';
|
| 870 |
+
const segs=[{start:0,end:6,text:'Hoje eu vou te ensinar as três estratégias que mudaram meu Instagram.'},{start:6,end:14,text:'A primeira coisa é que consistência vence talento.'},{start:14,end:24,text:'A segunda é dominar os primeiros três segundos do Reels.'},{start:24,end:34,text:'A terceira é responder comentários nos primeiros trinta minutos.'}];
|
| 871 |
+
try{const d=await api('/analyze',{text:t,segments:segs,title:'3 estratégias para crescer no Instagram'});S.text=t;S.segs=segs;S.analysis=d;S.url='https://instagram.com/reel/exemplo';S.isFile=false;G('v-empty').style.display='none';populate({language:'pt'});G('outc').classList.add('on');switchTab('transcript');}catch(e){showErr(e.message);}
|
| 872 |
+
b.classList.remove('ld');b.textContent='▶ Ver demonstração de exemplo';
|
| 873 |
+
});
|
| 874 |
+
|
| 875 |
+
// ════════════════════ HOOKS ════════════════════
|
| 876 |
+
G('hook-btn').addEventListener('click',async()=>{
|
| 877 |
+
const v=G('hook-inp').value.trim();if(!v)return G('hook-inp').focus();
|
| 878 |
+
const b=G('hook-btn');b.disabled=true;b.textContent='⏳ Gerando...';
|
| 879 |
+
try{const d=await api('/generate',{type:'hooks',topic:v});
|
| 880 |
+
G('hook-empty').style.display='none';G('hook-out').style.display='block';
|
| 881 |
+
const l=G('hook-list');l.innerHTML='';
|
| 882 |
+
d.hooks.forEach((h,i)=>{const div=document.createElement('div');div.className='litem';div.innerHTML=`<span class="num">${i+1}</span><span class="txt">${esc(h)}</span><button class="btn sm">📋</button>`;div.querySelector('button').onclick=e=>{navigator.clipboard.writeText(h);e.target.textContent='✓';setTimeout(()=>e.target.textContent='📋',1400);};l.appendChild(div);});
|
| 883 |
+
G('hook-cpy').onclick=()=>cpTxt(d.hooks.join('\n'),G('hook-cpy'),'📋 Copiar todos');
|
| 884 |
+
}catch(e){alert(e.message);}b.disabled=false;b.textContent='🪝 Gerar 10 hooks';
|
| 885 |
+
});
|
| 886 |
+
G('hook-inp').addEventListener('keydown',e=>{if(e.key==='Enter')G('hook-btn').click();});
|
| 887 |
+
|
| 888 |
+
// ════════════════════ IDEAS ════════════════════
|
| 889 |
+
G('idea-btn').addEventListener('click',async()=>{
|
| 890 |
+
const v=G('idea-inp').value.trim();if(!v)return G('idea-inp').focus();
|
| 891 |
+
const b=G('idea-btn');b.disabled=true;b.textContent='⏳ Gerando...';
|
| 892 |
+
try{const d=await api('/generate',{type:'ideas',niche:v});
|
| 893 |
+
G('idea-empty').style.display='none';G('idea-out').style.display='block';
|
| 894 |
+
const l=G('idea-list');l.innerHTML='';
|
| 895 |
+
d.ideas.forEach(it=>{const div=document.createElement('div');div.className='litem';div.innerHTML=`<span class="num">${it.icon}</span><span class="txt">${esc(it.title)}</span><span class="fmt-badge">${esc(it.fmt)}</span>`;l.appendChild(div);});
|
| 896 |
+
G('idea-cpy').onclick=()=>cpTxt(d.ideas.map(i=>`• ${i.title} (${i.fmt})`).join('\n'),G('idea-cpy'),'📋 Copiar');
|
| 897 |
+
}catch(e){alert(e.message);}b.disabled=false;b.textContent='💡 Gerar 9 ideias';
|
| 898 |
+
});
|
| 899 |
+
G('idea-inp').addEventListener('keydown',e=>{if(e.key==='Enter')G('idea-btn').click();});
|
| 900 |
+
|
| 901 |
+
// ════════════════════ SCRIPT ════════════════════
|
| 902 |
+
G('scr-btn').addEventListener('click',async()=>{
|
| 903 |
+
const v=G('scr-inp').value.trim();if(!v)return G('scr-inp').focus();
|
| 904 |
+
const b=G('scr-btn');b.disabled=true;b.textContent='⏳ Gerando...';
|
| 905 |
+
try{const d=await api('/generate',{type:'script',topic:v,format:G('scr-fmt').value});
|
| 906 |
+
G('scr-empty').style.display='none';G('scr-out').style.display='block';
|
| 907 |
+
G('scr-dur').textContent=`Roteiro · ~${d.estSeconds}s de vídeo`;
|
| 908 |
+
const l=G('scr-list');l.innerHTML='';
|
| 909 |
+
d.sections.forEach(s=>{
|
| 910 |
+
const div=document.createElement('div');div.style.cssText='padding:14px 16px;border-bottom:1px solid var(--line)';
|
| 911 |
+
div.innerHTML=`<div style="display:flex;justify-content:space-between;align-items:center;gap:8px;margin-bottom:6px"><span style="font-weight:700;font-size:13px;color:var(--acc-d)">${esc(s.label)}</span><button class="btn sm">📋</button></div><div style="font-size:14px;line-height:1.6;margin-bottom:5px">${esc(s.text)}</div><div style="font-size:12px;color:var(--ink3);font-style:italic">💡 ${esc(s.tip)}</div>`;
|
| 912 |
+
div.querySelector('button').onclick=e=>{navigator.clipboard.writeText(s.text);e.target.textContent='✓';setTimeout(()=>e.target.textContent='📋',1400);};
|
| 913 |
+
l.appendChild(div);
|
| 914 |
+
});
|
| 915 |
+
G('scr-cpy').onclick=()=>cpTxt(d.full,G('scr-cpy'),'📋 Copiar roteiro');
|
| 916 |
+
}catch(e){alert(e.message);}b.disabled=false;b.textContent='📝 Gerar roteiro';
|
| 917 |
+
});
|
| 918 |
+
G('scr-inp').addEventListener('keydown',e=>{if(e.key==='Enter')G('scr-btn').click();});
|
| 919 |
+
|
| 920 |
+
// ════════════════════ HASHTAGS ════════════════════
|
| 921 |
+
G('ht-btn').addEventListener('click',async()=>{
|
| 922 |
+
const v=G('ht-inp').value.trim();if(!v)return G('ht-inp').focus();
|
| 923 |
+
const b=G('ht-btn');b.disabled=true;b.textContent='⏳ Gerando...';
|
| 924 |
+
try{const d=await api('/generate',{type:'hashtags',topic:v});
|
| 925 |
+
G('ht-empty').style.display='none';G('ht-out').style.display='block';
|
| 926 |
+
const c=G('ht-cloud');c.innerHTML='';
|
| 927 |
+
d.hashtags.forEach(tag=>{const sp=document.createElement('span');sp.className='tag ht';sp.textContent=tag;sp.onclick=()=>{navigator.clipboard.writeText(tag);sp.classList.add('cp');setTimeout(()=>sp.classList.remove('cp'),1400);};c.appendChild(sp);});
|
| 928 |
+
G('ht-cpy').onclick=()=>cpTxt(d.hashtags.join(' '),G('ht-cpy'),'📋 Copiar todas');
|
| 929 |
+
}catch(e){alert(e.message);}b.disabled=false;b.textContent='#️⃣ Gerar hashtags';
|
| 930 |
+
});
|
| 931 |
+
|
| 932 |
+
// ════════════════════ BIO ════════════════════
|
| 933 |
+
G('bio-btn').addEventListener('click',async()=>{
|
| 934 |
+
const niche=G('bio-niche').value.trim();if(!niche)return G('bio-niche').focus();
|
| 935 |
+
const b=G('bio-btn');b.disabled=true;b.textContent='⏳ Gerando...';
|
| 936 |
+
try{const d=await api('/generate',{type:'bio',name:G('bio-name').value.trim(),niche,cta:G('bio-cta').value.trim()});
|
| 937 |
+
G('bio-empty').style.display='none';const o=G('bio-out');o.style.display='block';o.innerHTML='';
|
| 938 |
+
d.bios.forEach(bio=>{const div=document.createElement('div');div.className='biocard';div.innerHTML=`<button class="btn sm cp">📋</button>${esc(bio)}`;div.querySelector('.cp').onclick=e=>{navigator.clipboard.writeText(bio);e.target.textContent='✓';setTimeout(()=>e.target.textContent='📋',1400);};o.appendChild(div);});
|
| 939 |
+
}catch(e){alert(e.message);}b.disabled=false;b.textContent='✍️ Gerar bios';
|
| 940 |
+
});
|
| 941 |
+
|
| 942 |
+
// ════════════════════ CALENDAR ════════════════════
|
| 943 |
+
G('cal-btn').addEventListener('click',async()=>{
|
| 944 |
+
const niche=G('cal-niche').value.trim();if(!niche)return G('cal-niche').focus();
|
| 945 |
+
const b=G('cal-btn');b.disabled=true;b.textContent='⏳ Gerando...';
|
| 946 |
+
try{const d=await api('/generate',{type:'calendar',niche,perWeek:G('cal-freq').value});
|
| 947 |
+
G('cal-empty').style.display='none';G('cal-out').style.display='block';
|
| 948 |
+
const l=G('cal-list');l.innerHTML='';
|
| 949 |
+
d.plan.forEach(p=>{const div=document.createElement('div');div.className='litem';div.innerHTML=`<span class="num" style="width:auto;font-size:.85rem;color:var(--acc-d);font-weight:700;min-width:62px">${esc(p.day)}</span><span class="txt"><b>${p.icon} ${esc(p.theme)}</b><br><span style="font-size:12px;color:var(--ink3)">⏰ ${esc(p.best)}</span></span><span class="fmt-badge">${esc(p.fmt)}</span>`;l.appendChild(div);});
|
| 950 |
+
G('cal-cpy').onclick=()=>cpTxt(d.plan.map(p=>`${p.day}: ${p.theme} [${p.fmt}] — ${p.best}`).join('\n'),G('cal-cpy'),'📋 Copiar');
|
| 951 |
+
}catch(e){alert(e.message);}b.disabled=false;b.textContent='📅 Gerar calendário';
|
| 952 |
+
});
|
| 953 |
+
</script>
|
| 954 |
+
</body>
|
| 955 |
+
</html>
|
whisper_worker.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Runs as: node whisper_worker.js <audioPath> <model> <language>
|
| 2 |
+
const [, , audioPath, modelName, language, task = 'transcribe'] = process.argv;
|
| 3 |
+
const fs = require('fs');
|
| 4 |
+
const path = require('path');
|
| 5 |
+
const { execFileSync } = require('child_process');
|
| 6 |
+
const ffmpegStatic = require('ffmpeg-static');
|
| 7 |
+
|
| 8 |
+
async function main() {
|
| 9 |
+
const { pipeline, env } = await import('@xenova/transformers');
|
| 10 |
+
|
| 11 |
+
env.cacheDir = process.env.XENOVA_CACHE_DIR || path.join(__dirname, '.cache');
|
| 12 |
+
// Suppress verbose ONNX logs
|
| 13 |
+
env.backends.onnx.logLevel = 'error';
|
| 14 |
+
|
| 15 |
+
process.stderr.write(`Carregando modelo ${modelName}...\n`);
|
| 16 |
+
|
| 17 |
+
const transcriber = await pipeline('automatic-speech-recognition', modelName);
|
| 18 |
+
|
| 19 |
+
process.stderr.write('Convertendo áudio para PCM...\n');
|
| 20 |
+
|
| 21 |
+
// Convert audio to raw 32-bit float PCM (16kHz mono) using ffmpeg
|
| 22 |
+
const rawPath = audioPath + '.f32le';
|
| 23 |
+
execFileSync(ffmpegStatic, [
|
| 24 |
+
'-i', audioPath,
|
| 25 |
+
'-ar', '16000',
|
| 26 |
+
'-ac', '1',
|
| 27 |
+
'-f', 'f32le',
|
| 28 |
+
'-y', rawPath,
|
| 29 |
+
], { stdio: 'pipe' });
|
| 30 |
+
|
| 31 |
+
const rawBuffer = fs.readFileSync(rawPath);
|
| 32 |
+
fs.unlink(rawPath, () => {});
|
| 33 |
+
|
| 34 |
+
// Build Float32Array from raw PCM bytes
|
| 35 |
+
const audioData = new Float32Array(
|
| 36 |
+
rawBuffer.buffer,
|
| 37 |
+
rawBuffer.byteOffset,
|
| 38 |
+
rawBuffer.byteLength / 4
|
| 39 |
+
);
|
| 40 |
+
|
| 41 |
+
process.stderr.write('Transcrevendo...\n');
|
| 42 |
+
|
| 43 |
+
const opts = {
|
| 44 |
+
return_timestamps: true,
|
| 45 |
+
chunk_length_s: 30,
|
| 46 |
+
stride_length_s: 5,
|
| 47 |
+
};
|
| 48 |
+
if (language && language !== 'auto') opts.language = language;
|
| 49 |
+
opts.task = task === 'translate' ? 'translate' : 'transcribe';
|
| 50 |
+
|
| 51 |
+
const result = await transcriber(audioData, opts);
|
| 52 |
+
|
| 53 |
+
const segments = (result.chunks || []).map(c => ({
|
| 54 |
+
start: c.timestamp?.[0] ?? 0,
|
| 55 |
+
end: c.timestamp?.[1] ?? 0,
|
| 56 |
+
text: c.text.trim(),
|
| 57 |
+
}));
|
| 58 |
+
|
| 59 |
+
process.stdout.write(JSON.stringify({
|
| 60 |
+
text: result.text.trim(),
|
| 61 |
+
language: language !== 'auto' ? language : '',
|
| 62 |
+
segments,
|
| 63 |
+
}));
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
main().catch(e => {
|
| 67 |
+
process.stderr.write('ERRO: ' + e.message + '\n');
|
| 68 |
+
process.exit(1);
|
| 69 |
+
});
|