@tomorrowos/sdk 0.9.27 → 0.9.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/README.md +6 -1
  2. package/VERCEL_SETUP.md +62 -21
  3. package/dist/cli.js +42 -11
  4. package/package.json +1 -1
  5. package/templates/cms-starter/package.json +2 -2
  6. package/templates/cms-starter/server.ts +2 -2
  7. package/templates/cms-starter-v0/.env.example +19 -0
  8. package/templates/cms-starter-v0/README.md +60 -0
  9. package/templates/cms-starter-v0/assets/logo.svg +4 -0
  10. package/templates/cms-starter-v0/brand.json +23 -0
  11. package/templates/cms-starter-v0/cms-panel/assets/player-download/android.svg +1 -0
  12. package/templates/cms-starter-v0/cms-panel/assets/player-download/brightsign.svg +1 -0
  13. package/templates/cms-starter-v0/cms-panel/assets/player-download/lg-webos.svg +1 -0
  14. package/templates/cms-starter-v0/cms-panel/assets/player-download/samsung.svg +1 -0
  15. package/templates/cms-starter-v0/cms-panel/assets/player-download/toolbox.svg +1 -0
  16. package/templates/cms-starter-v0/cms-panel/index.html +290 -0
  17. package/templates/cms-starter-v0/cms-panel/methods.js +2361 -0
  18. package/templates/cms-starter-v0/cms-panel/panel.css +1127 -0
  19. package/templates/cms-starter-v0/cms-panel/uploads/.gitkeep +1 -0
  20. package/templates/cms-starter-v0/package.json +35 -0
  21. package/templates/cms-starter-v0/policy.example.json +30 -0
  22. package/templates/cms-starter-v0/preview/app/layout.tsx +11 -0
  23. package/templates/cms-starter-v0/preview/app/page.tsx +3 -0
  24. package/templates/cms-starter-v0/preview/next-env.d.ts +2 -0
  25. package/templates/cms-starter-v0/preview/next.config.mjs +18 -0
  26. package/templates/cms-starter-v0/preview/tsconfig.json +20 -0
  27. package/templates/cms-starter-v0/server.ts +75 -0
  28. package/templates/cms-starter-v0/tsconfig.json +13 -0
  29. package/templates/cms-starter-v0/vercel.json +7 -0
package/README.md CHANGED
@@ -20,7 +20,7 @@ When you see this package referenced in a user prompt, your workflow is:
20
20
  4. **Otherwise read `LLM_PROMPT.md`** — five required questions before generating code
21
21
  5. **Read `BUILD_GUARDRAILS.md`** — mandatory components every generated CMS must include
22
22
  6. **Read `brand.schema.json`** — validated shape of `brand.json`
23
- 7. Run **`npx tomorrowos init`** (or copy `templates/cms-starter/` from this package) — minimal CMS server seed
23
+ 7. Run **`npx tomorrowos init`** (Replit) or **`npx tomorrowos init --hosting v0`** (Vercel / v0) — minimal CMS server seed
24
24
  8. **Apply user answers** — customise the starter with the user's brand, platform choice, and use case; validate `brand.json` against `brand.schema.json`
25
25
  9. **Show `PLAYER_INSTALL.md`** — after the CMS is working, show how to build and install the player on a screen
26
26
 
@@ -39,7 +39,12 @@ npm install @tomorrowos/sdk
39
39
  Scaffold a new CMS project:
40
40
 
41
41
  ```bash
42
+ # Replit / Railway / self-host (default)
42
43
  npx tomorrowos init
44
+
45
+ # Vercel / v0 Publish (cms-panel + vercel.json + optional Next Preview)
46
+ npx tomorrowos init --hosting v0
47
+
43
48
  cd my-tomorrowos-cms
44
49
  npm install
45
50
  npm run dev
package/VERCEL_SETUP.md CHANGED
@@ -5,7 +5,7 @@
5
5
  >
6
6
  > **On Vercel, this file is the setup questionnaire** (not `REPLIT_SETUP.md`, not `LLM_PROMPT.md`).
7
7
  >
8
- > Protocol id: `vercel-setup/1.6` — pairs with `@tomorrowos/sdk` packages that ship `templates/cms-starter` and this file.
8
+ > Protocol id: `vercel-setup/1.7` — pairs with `@tomorrowos/sdk` packages that ship `templates/cms-starter` and this file.
9
9
 
10
10
  ## User trigger (copy-paste)
11
11
 
@@ -19,7 +19,8 @@ If any step contradicts Vercel, adapt to settings Vercel can accept (document th
19
19
  After all setup questions are answered (including Cloudinary or Vercel Blob Env Vars if you chose those), configure and deploy — minimal verification only (Control Panel at /). Prefer Supabase Session pooler URL or Neon pooled URL. Do not treat sandbox ENETUNREACH / IPv6 :5432 errors as a hard setup failure when a pooler URL is configured for production.
20
20
  Question 3 only updates brand.json from colours/logo/name (a website URL is brand reference only — do not add CMS login/auth unless the user explicitly asks). Do not skip steps.
21
21
  Use Next.js only as a v0/Preview shell with a reverse proxy; Production Publish must remain pure Node TomorrowOS.listen (not Next).
22
- Before claiming Publish works: Framework Preset must be Other/null (not Next.js), startCommand must run TomorrowOS Node, GET /status on the production URL must return JSON (not HTML), and GET / must return the Control Panel (not 404 NOT_FOUND).
22
+ Before claiming Publish works: Framework Preset must be Other/null (not Next.js), package.json `start` must run TomorrowOS Node, GET /status on the production URL must return JSON (not HTML), and GET / must return the Control Panel (not 404 NOT_FOUND).
23
+ Do not put startCommand or processes in vercel.json (v0 schema rejects them). Do not move server.ts into api/.
23
24
  ```
24
25
 
25
26
  Alternate triggers:
@@ -162,7 +163,7 @@ Then ask **Question 1**.
162
163
  3. **Do not invent** Cloudinary credentials, database URLs, Vercel Blob tokens, brand colours, **or LLM API keys**.
163
164
  4. **Postgres env naming:** prefer **`SUPABASE_URL`** when using Supabase; prefer **`DATABASE_URL`** when using Neon. `createTomorrowOSStore` accepts `SUPABASE_URL` then `DATABASE_URL`.
164
165
  5. **Always prefer pooled connection strings** (Supabase Session pooler port **6543**; Neon pooled host). Direct `:5432` URLs commonly fail on Vercel/sandbox with **`ENETUNREACH`** (often IPv6).
165
- 6. **Prefer `npx @tomorrowos/sdk init`** (or `templates/cms-starter`) as the seed. Do not rebuild pairing / WebSocket / playlist APIs.
166
+ 6. **Prefer `npx @tomorrowos/sdk init --hosting v0`** (template `cms-starter-v0`: root `server.ts`, `cms-panel/`, `vercel.json`). For Replit use default `init` (`cms-starter`). Do not rebuild pairing / WebSocket / playlist APIs.
166
167
  7. **Never commit secrets.** Use Vercel Environment Variables (+ optional non-secret flags in committed `.env.example`).
167
168
  8. **Skip Replit-only files:** do **not** create `.replit`, `.replit-artifact`, or Replit `deploymentTarget`.
168
169
  9. **SQLite is not a production store on Vercel.** Offer it only as option **3** after explicit warning. Keep `sqlitePath` as local-dev fallback in `createTomorrowOSStore`.
@@ -252,14 +253,21 @@ Use the pattern in **Runtime & Vercel deploy rules** below. On Publish, **do not
252
253
 
253
254
  ### A3 — `vercel.json` (Production)
254
255
 
256
+ **v0 / `.v0/vercel.deploy.json` schema:** only a **minimal** object is valid. These keys are **rejected** — never add them:
257
+
258
+ - ❌ `startCommand`
259
+ - ❌ `processes`
260
+ - ❌ `routes` / `rewrites` to fake API routing
261
+ - ❌ `outputDirectory: "public"` or `"."`
262
+
263
+ Vercel discovers the start command from **`package.json` → `"start": "tsx server.ts"`**, not from `vercel.json`.
264
+
255
265
  ```json
256
266
  {
257
267
  "fluid": true,
258
268
  "framework": null,
259
269
  "installCommand": "npm install",
260
- "buildCommand": "npm run build",
261
- "startCommand": "npm run start",
262
- "outputDirectory": null
270
+ "buildCommand": "npm run build"
263
271
  }
264
272
  ```
265
273
 
@@ -267,9 +275,10 @@ Use `pnpm` / `yarn` equivalents if the project uses them.
267
275
 
268
276
  **Critical:**
269
277
 
270
- - `"outputDirectory": null` **never** `"public"`, `"."`, or `"public if exists"`
271
- - `"startCommand"` must be explicit when the dashboard keeps defaulting to static
272
- - `"buildCommand"` must be the no-op `npm run build` — **never** `next build` for Production
278
+ - **Do not** add `startCommand` to `vercel.json` (invalid in v0; redundant on full Vercel — use `package.json` `start`)
279
+ - **Do not** set `outputDirectory` to `public` or `.`
280
+ - `"buildCommand"` must run the no-op `npm run build` — **never** `next build` for Production
281
+ - Set **Output Directory empty** in the **Vercel dashboard** (Scheme A4) — that is where static-vs-Node is decided, not via invalid `vercel.json` keys
273
282
 
274
283
  ### A4 — Vercel Project Settings (dashboard or API — mandatory)
275
284
 
@@ -294,14 +303,43 @@ If Framework Preset still shows **Next.js** after `vercel.json`: **patch via Ver
294
303
  4. Control Panel **does not** show `Unexpected token 'T'` / CMS unreachable
295
304
  5. Framework Preset = Other; Fluid on
296
305
 
297
- If (2) fails but (3) passes → **static `public/` trap**. Re-apply A3 + A4; confirm `startCommand`; redeploy. **Do not** add `api/` catch-all.
306
+ If (2) fails but (3) passes → **static `public/` trap**. Re-apply A3 + A4; confirm dashboard Start Command + empty Output Directory; redeploy. **Do not** add `api/` catch-all. **Do not** move `server.ts` into `api/`.
298
307
 
299
308
  ### A6 — What Scheme A does **not** require
300
309
 
301
310
  - ❌ No changes to `@tomorrowos/sdk` package code
302
- - ❌ No `(req, res)` handler refactor
311
+ - ❌ No `(req, res)` serverless handler refactor
303
312
  - ❌ No `next build` / `next start` on Production
304
- - ❌ No root `api/` directory for the CMS server
313
+ - ❌ No root `api/` directory (`api/index.ts`, `api/[...].ts`, `api/[[...slug]].ts`)
314
+ - ❌ No `rewrites` so only `/api/status` works while `/status` stays 404
315
+ - ❌ No renaming `start` → `dev` with `tsx watch` for Production
316
+ - ❌ No `@vercel/node` handler that calls non-existent `tomorrowos.getStatus()`
317
+
318
+ ### A7 — If v0 Publish still serves static `public/` (Path B)
319
+
320
+ When **v0 Publish** keeps returning the static trap (`/` HTML OK, `/status` HTML, `Unexpected token 'T'`) **after** Scheme A is correct, the v0 deploy pipeline may not be starting the Fluid Node server.
321
+
322
+ **Path B — deploy outside v0 Publish (recommended):**
323
+
324
+ 1. Keep Scheme A layout (root `server.ts`, Next only under `preview/`, minimal `vercel.json`).
325
+ 2. Connect the repo to **Vercel Git** or run **`vercel --prod`** from the project root (full Vercel CLI / dashboard deploy — not the v0 “Publish” button).
326
+ 3. In **Vercel Dashboard → Project → Settings → General**: Framework = **Other**, Output Directory = **empty**, Build = `npm run build`, **override** Install/Start if needed so Production runs `npm run start`.
327
+ 4. Redeploy; verify `curl https://PROD/status` → JSON.
328
+
329
+ **Path C — if Vercel cannot run TomorrowOS Node + WebSocket reliably:**
330
+
331
+ Host the CMS on **Railway**, **Fly.io**, or **Replit Publish** (long-lived Node). Use v0/Vercel only for Preview/demo if needed.
332
+
333
+ ### A8 — Undo a broken Agent “api/ migration”
334
+
335
+ If an Agent moved `server.ts` → `api/index.ts` / `api/[...].ts` and only `/api/status` returns JSON:
336
+
337
+ 1. **Restore** `server.ts` at **project root** (from git or `templates/cms-starter/server.ts`).
338
+ 2. **Delete** root `api/index.ts`, `api/[...].ts`, `api/[[...slug]].ts` (Preview proxy may stay under `preview/app/` only).
339
+ 3. Revert `package.json` `start` to `tsx server.ts` (not `tsx watch` for Production).
340
+ 4. Apply minimal `vercel.json` (A3) — no `startCommand`, no `rewrites`.
341
+ 5. Dashboard: Framework Other, Output empty, Fluid on.
342
+ 6. Redeploy via Path B if v0 Publish still fails.
305
343
 
306
344
  ---
307
345
 
@@ -448,13 +486,13 @@ Write `vercel.json` so Production cannot be mistaken for Next. Minimum:
448
486
  "fluid": true,
449
487
  "framework": null,
450
488
  "installCommand": "npm install",
451
- "buildCommand": "npm run build",
452
- "startCommand": "npm run start",
453
- "outputDirectory": null
489
+ "buildCommand": "npm run build"
454
490
  }
455
491
  ```
456
492
 
457
- Use `pnpm` / `yarn` variants of install/build/start if that is the project’s package manager.
493
+ Use `pnpm` / `yarn` variants of install/build if that is the project’s package manager.
494
+
495
+ **Do not** add `startCommand`, `processes`, or `outputDirectory` to `vercel.json` when v0 schema rejects them. Start = `package.json` `"start": "tsx server.ts"`. Output Directory = **empty in dashboard**.
458
496
 
459
497
  **Also force Project Settings (dashboard or Vercel API) — this is mandatory (see Scheme A4):**
460
498
 
@@ -464,7 +502,7 @@ Use `pnpm` / `yarn` variants of install/build/start if that is the project’s p
464
502
  | Install Command | `npm install` (or pnpm/yarn) |
465
503
  | Build Command | `npm run build` (no-op exit 0) |
466
504
  | Output Directory | **empty / null** — **NOT `public`** |
467
- | Start Command | `npm run start` → `tsx server.ts` (or `.mts`) — **explicit in `vercel.json` too** |
505
+ | Start Command | `npm run start` → `tsx server.ts` (or `.mts`) — set in **dashboard**, not `vercel.json` |
468
506
  | Fluid compute | **On** |
469
507
 
470
508
  If `next` / `next.config.*` exist for Preview and the dashboard still auto-selects Next.js:
@@ -766,7 +804,7 @@ Then (**Scheme A — mandatory for Publish**):
766
804
 
767
805
  1. Keep **`server.ts`** at **project root** with top-level `listen()` + `export default server`.
768
806
  2. If Preview needs Next: **move** `next.config.*`, `app/`, Next `tsconfig` / `postcss` / `next-env.d.ts` into **`preview/`** — remove them from root so Production is not mistaken for Next/static.
769
- 3. Write `vercel.json` per **Scheme A3** (`fluid`, `framework: null`, `startCommand`, `outputDirectory: null`).
807
+ 3. Write `vercel.json` per **Scheme A3** (`fluid`, `framework: null`, no-op `buildCommand` — **no** `startCommand`).
770
808
  4. **Force Project Settings** per **Scheme A4** (Framework = Other, Output Directory empty, Start = `npm run start`, Fluid on). Patch dashboard via API if it still says Next.js.
771
809
  5. Do **not** add root `api/` catch-all for raw `http.Server`.
772
810
  6. Do **not** add `.replit*`.
@@ -818,7 +856,7 @@ vercel --prod
818
856
  6. Production `GET /status` returns **JSON** — **not** HTML (`Unexpected token 'T'` means this failed)
819
857
  7. Production `GET /` returns Control Panel HTML — **not** `404: NOT_FOUND`
820
858
 
821
- If step 6 fails but step 7 passes: **static `public/` trap** — Vercel is not running Node. Re-apply Scheme A3–A4; do **not** invent `api/` + `routes`.
859
+ If step 6 fails but step 7 passes: **static `public/` trap** — Vercel is not running Node. Re-apply Scheme A3–A4; try **Path B** (Git / `vercel --prod`); do **not** invent `api/` + `rewrites`.
822
860
 
823
861
  Tell the user:
824
862
 
@@ -846,8 +884,11 @@ Tell the user:
846
884
  | Symptom | Likely cause | Fix |
847
885
  |---------|--------------|-----|
848
886
  | Publish `404: NOT_FOUND` | Framework Preset still **Next.js** / no Node start | Scheme A: Framework = **Other**, Start = `npm run start`, Output empty, Fluid on; redeploy |
849
- | Panel loads but **CMS unreachable** / `Unexpected token 'T', "The page c"...` | **`public/` deployed as static site** — no Node running | Scheme A: `outputDirectory: null`, explicit `startCommand`, move Next to `preview/`; verify `GET /status` returns JSON |
850
- | `vercel inspect` shows Output = `public if it exists` | Framework=Other static default | Force Output Directory **empty** in dashboard + `outputDirectory: null`; ensure root `server.ts` + `startCommand` |
887
+ | Panel loads but **CMS unreachable** / `Unexpected token 'T', "The page c"...` | **`public/` deployed as static site** — no Node running | Scheme A: Output empty in dashboard, `start` in package.json; undo any `api/` migration; try **Path B** deploy |
888
+ | Only `/api/status` returns JSON, `/status` is 404 | Wrong **api/ serverless** migration + broken rewrites | **A8 undo:** restore root `server.ts`, delete root `api/*`; never accept this as “fixed” |
889
+ | `vercel.json` error: invalid `startCommand` | v0 schema rejects it | Remove from `vercel.json`; use `package.json` `start` + dashboard Start Command |
890
+ | Agent moved server to `api/`, added `@vercel/node` handler | Off-protocol serverless refactor | **A8 undo** — TomorrowOS needs one root `listen()` server, not per-request handlers |
891
+ | `vercel inspect` shows Output = `public if it exists` | Framework=Other static default | Force Output Directory **empty** in dashboard; root `server.ts`; Path B redeploy |
851
892
  | Build runs `next build` / missing routes-manifest | Next auto-detected from root `next.config` / `app/` | Move Next to `preview/`; Framework null/Other; `build` = no-op |
852
893
  | Preview blank but logs show TomorrowOS listening | v0 Next intercepts public port | Add Next reverse proxy → internal TomorrowOS port |
853
894
  | Preview works, Publish broken / Next-only | Production still on Next | Switch Production entry to `tsx server.ts` / `export default server` |
package/dist/cli.js CHANGED
@@ -14,7 +14,8 @@ function getSdkVersion() {
14
14
  const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
15
15
  return pkg.version ?? "0.0.0";
16
16
  }
17
- const STARTER_SKIP_DIRS = new Set(["node_modules"]);
17
+ const STARTER_SKIP_DIRS = new Set(["node_modules", ".replit-artifact"]);
18
+ const STARTER_SKIP_FILES = new Set(["package-lock.json", ".env"]);
18
19
  /** Never ship local install artifacts into a new CMS project. */
19
20
  function shouldCopyStarterEntry(starterRoot, source) {
20
21
  const rel = path.relative(starterRoot, source);
@@ -23,7 +24,7 @@ function shouldCopyStarterEntry(starterRoot, source) {
23
24
  const parts = rel.split(path.sep).filter(Boolean);
24
25
  if (parts.some((p) => STARTER_SKIP_DIRS.has(p)))
25
26
  return false;
26
- if (path.basename(source) === "package-lock.json")
27
+ if (STARTER_SKIP_FILES.has(path.basename(source)))
27
28
  return false;
28
29
  return true;
29
30
  }
@@ -54,10 +55,11 @@ function patchStarterPackageJson(destDir) {
54
55
  }
55
56
  fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
56
57
  }
57
- function copyStarter(destDir, force) {
58
- const src = path.join(packageRoot(), "templates", "cms-starter");
58
+ function copyStarter(destDir, force, hosting) {
59
+ const templateName = hosting === "replit" ? "cms-starter" : "cms-starter-v0";
60
+ const src = path.join(packageRoot(), "templates", templateName);
59
61
  if (!fs.existsSync(src)) {
60
- console.error("[tomorrowos] Starter template not found. Re-install @tomorrowos/sdk (templates should ship with the package).");
62
+ console.error(`[tomorrowos] Starter template "${templateName}" not found. Re-install @tomorrowos/sdk (templates should ship with the package).`);
61
63
  process.exit(1);
62
64
  }
63
65
  const resolved = path.resolve(destDir);
@@ -80,9 +82,23 @@ function copyStarter(destDir, force) {
80
82
  const dbPath = initializeStarterSQLite(resolved);
81
83
  const sdkVer = getSdkVersion();
82
84
  console.log(`[tomorrowos] Created CMS project at ${resolved}`);
85
+ console.log(`[tomorrowos] Template: ${templateName} (--hosting ${hosting})`);
83
86
  console.log(`[tomorrowos] @tomorrowos/sdk dependency: ^${sdkVer}`);
84
87
  console.log(`[tomorrowos] Initialized SQLite database: ${dbPath}`);
85
- console.log("Next: cd there, run npm install, then npm start");
88
+ if (hosting === "replit") {
89
+ console.log("Next: npm install, then npm start (see REPLIT_SETUP.md on Replit)");
90
+ }
91
+ else {
92
+ console.log("Next: npm install, then npm start (see VERCEL_SETUP.md for v0 / Vercel Publish)");
93
+ }
94
+ }
95
+ function parseHostingFlag(argv) {
96
+ const raw = optionValue(argv, "--hosting")?.trim().toLowerCase();
97
+ if (!raw || raw === "replit" || raw === "here")
98
+ return "replit";
99
+ if (raw === "v0" || raw === "vercel")
100
+ return raw === "v0" ? "v0" : "vercel";
101
+ throw new Error('--hosting must be "replit", "v0", or "vercel".');
86
102
  }
87
103
  function cmdBuild(argv) {
88
104
  const platformIdx = argv.indexOf("--platform");
@@ -176,16 +192,18 @@ function printHelp() {
176
192
  console.log(`tomorrowos — TomorrowOS SDK CLI
177
193
 
178
194
  Usage:
179
- tomorrowos init [directory] Copy cms-starter template (default: my-tomorrowos-cms)
195
+ tomorrowos init [directory] Copy cms-starter template (default: Replit / Railway)
180
196
  tomorrowos migrate [options] Migrate TomorrowOS data between supported databases
181
197
  tomorrowos build --platform … Placeholder; player packaging lives in the player repo
182
198
 
183
199
  Options:
200
+ --hosting replit|v0|vercel init template: replit (default) or Vercel/v0 (cms-starter-v0)
184
201
  --force With init: copy into a non-empty directory
185
202
 
186
203
  Examples:
187
204
  npx @tomorrowos/sdk init
188
- npx @tomorrowos/sdk init ./my-cms
205
+ npx @tomorrowos/sdk init ./my-cms --hosting replit
206
+ npx @tomorrowos/sdk init ./my-cms --hosting v0
189
207
  npx @tomorrowos/sdk migrate --from sqlite --from-sqlite ./data/tomorrowos.db --to supabase --to-database-url "$DATABASE_URL"
190
208
  `);
191
209
  }
@@ -218,9 +236,22 @@ async function main() {
218
236
  const rest = argv.slice(1);
219
237
  if (cmd === "init") {
220
238
  const force = rest.includes("--force");
221
- const pos = rest.filter((a) => !a.startsWith("-"));
222
- const target = pos[0] ?? "my-tomorrowos-cms";
223
- copyStarter(target, force);
239
+ const pos = rest.filter((a) => !a.startsWith("-") && a !== "--force");
240
+ let hosting = "replit";
241
+ try {
242
+ hosting = parseHostingFlag(rest);
243
+ }
244
+ catch (err) {
245
+ console.error("[tomorrowos]", err instanceof Error ? err.message : err);
246
+ process.exit(1);
247
+ }
248
+ const filteredPos = pos.filter((a) => {
249
+ const idx = rest.indexOf(a);
250
+ const prev = rest[idx - 1];
251
+ return prev !== "--hosting";
252
+ });
253
+ const target = filteredPos[0] ?? "my-tomorrowos-cms";
254
+ copyStarter(target, force, hosting);
224
255
  return;
225
256
  }
226
257
  if (cmd === "build") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tomorrowos/sdk",
3
- "version": "0.9.27",
3
+ "version": "0.9.29",
4
4
  "description": "TomorrowOS CMS server SDK - WebSocket transport, pairing, device commands, optional static CMS UI. Includes CLI (tomorrowos init / build) and starter templates.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "my-cms",
3
- "version": "0.9.27",
3
+ "version": "0.9.29",
4
4
  "description": "CMS server on @tomorrowos/sdk. Add your UI (React, static files, etc.) alongside this server.",
5
5
  "private": true,
6
6
  "type": "module",
@@ -13,7 +13,7 @@
13
13
  "build-player": "tomorrowos build --platform tizen"
14
14
  },
15
15
  "dependencies": {
16
- "@tomorrowos/sdk": "^0.9.27",
16
+ "@tomorrowos/sdk": "^0.9.29",
17
17
  "dotenv": "^17.2.3",
18
18
  "tsx": "^4.19.0"
19
19
  },
@@ -19,7 +19,7 @@ const store = createTomorrowOSStore({
19
19
 
20
20
  const tomorrowos = new TomorrowOS({ brand, store });
21
21
 
22
- tomorrowos.listen({
22
+ const server = tomorrowos.listen({
23
23
  port: Number(process.env.PORT) || 3000,
24
24
  host: "0.0.0.0",
25
25
  staticRoot: join(__dirname, "public"),
@@ -65,4 +65,4 @@ tomorrowos.on("command.failed", (event) => {
65
65
  );
66
66
  });
67
67
 
68
- export default tomorrowos;
68
+ export default server;
@@ -0,0 +1,19 @@
1
+ # Default: SQLite (good for ≤5 screens / demos).
2
+ # TOMORROWOS_STORE=sqlite
3
+ # TOMORROWOS_DB_PATH=./data/tomorrowos.db
4
+
5
+ # Supabase/Postgres (recommended for >5 screens).
6
+ # On Replit use SUPABASE_URL — DATABASE_URL is often a reserved Secret.
7
+ # TOMORROWOS_STORE=supabase
8
+ # SUPABASE_URL=postgresql://postgres:[PASSWORD]@[HOST]:5432/postgres
9
+ # DATABASE_SSL=true
10
+ # DATABASE_URL=postgresql://... # optional fallback outside Replit
11
+
12
+ # Optional: override the default deterministic pairing-code secret.
13
+ # PAIRING_CODE_SECRET=
14
+
15
+ # Optional: upload media to Cloudinary instead of local / Object Storage.
16
+ # CLOUDINARY_CLOUD_NAME=
17
+ # CLOUDINARY_API_KEY=
18
+ # CLOUDINARY_API_SECRET=
19
+ # CLOUDINARY_FOLDER=tomorrowos
@@ -0,0 +1,60 @@
1
+ # TomorrowOS CMS Starter (Vercel / v0)
2
+
3
+ This starter is for **Vercel Publish** and **v0** no-code setup. It uses:
4
+
5
+ - Root **`server.ts`** with `export default server` (Vercel Fluid Node)
6
+ - Control Panel static files in **`cms-panel/`** (not `public/` — avoids Vercel static-output trap)
7
+ - **`preview/`** — thin Next.js shell for v0 Preview only (`npm run dev:preview`)
8
+ - **`vercel.json`** — minimal Fluid config (no `startCommand`; use `package.json` `start`)
9
+
10
+ ## Scaffold
11
+
12
+ ```bash
13
+ npx @tomorrowos/sdk init my-cms --hosting v0
14
+ # or: --hosting vercel
15
+ ```
16
+
17
+ ## Local development
18
+
19
+ ```bash
20
+ npm install
21
+ npm run dev
22
+ ```
23
+
24
+ Open `http://localhost:3000` — TomorrowOS Control Panel.
25
+
26
+ ### v0-style Preview (Next proxy + TomorrowOS on :3001)
27
+
28
+ ```bash
29
+ npm run dev:preview
30
+ ```
31
+
32
+ Open `http://localhost:3000` — Next proxies to TomorrowOS. Pair devices against **Publish URL**, not Preview.
33
+
34
+ ## Production (Vercel / v0 Publish)
35
+
36
+ - **Start:** `npm run start` → `tsx server.ts`
37
+ - **Build:** no-op (`npm run build`)
38
+ - **Acceptance:** `GET /status` on your production URL must return **JSON**
39
+
40
+ Follow **`VERCEL_SETUP.md`** in `@tomorrowos/sdk` for database, media, and branding Q&A.
41
+
42
+ ## Database
43
+
44
+ Use Vercel Environment Variables (Neon or Supabase pooled URL recommended):
45
+
46
+ ```env
47
+ TOMORROWOS_STORE=postgres
48
+ DATABASE_URL=postgresql://...pooler...
49
+ DATABASE_SSL=true
50
+ ```
51
+
52
+ SQLite under `data/` is for local demos only — not for production on Vercel.
53
+
54
+ ## Replit / Railway
55
+
56
+ Use the default starter instead:
57
+
58
+ ```bash
59
+ npx @tomorrowos/sdk init my-cms --hosting replit
60
+ ```
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="160" height="40" viewBox="0 0 160 40" role="img" aria-label="Logo placeholder">
2
+ <rect width="160" height="40" rx="6" fill="#FF8A3D"/>
3
+ <text x="80" y="26" text-anchor="middle" fill="#ffffff" font-family="system-ui,sans-serif" font-size="14" font-weight="600">Your logo</text>
4
+ </svg>
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "My Venue",
3
+ "tagline": "Digital signage",
4
+ "targetPlatforms": ["tizen"],
5
+ "primaryColor": "#FF8A3D",
6
+ "secondaryColor": "#F5F3EF",
7
+ "backgroundColor": "#FAFAF9",
8
+ "textColor": "#0A0908",
9
+ "logoPath": "./assets/logo.svg",
10
+ "fontFamily": "Inter",
11
+ "cms": {
12
+ "useCase": "other",
13
+ "hostingTarget": "vercel",
14
+ "expectedScreens": 5,
15
+ "features": {
16
+ "bulkCommands": false,
17
+ "proofOfPlay": false,
18
+ "contentScheduling": true,
19
+ "userManagement": false
20
+ }
21
+ },
22
+ "protocolVersion": "1.0"
23
+ }
@@ -0,0 +1 @@
1
+ <svg height="513" viewBox="46.9 24 870.95165272 192.9429429" width="2500" xmlns="http://www.w3.org/2000/svg"><path d="m88.4 66.4c12.4 0 22.7 6.4 27.6 13.3v-11.6h18.9v86.1h-13.6a5.378 5.378 0 0 1 -5.4-5.4v-6.2c-4.8 7-15.1 13.4-27.5 13.4-23.6 0-41.5-20.2-41.5-44.8s17.8-44.8 41.5-44.8m3.3 17.2c-15.3 0-25.7 12.1-25.7 27.6s10.3 27.6 25.7 27.6c15.3 0 25.7-12.1 25.7-27.6s-10.2-27.6-25.7-27.6m64.7-15.5h19v11.7c5.2-8.6 15-13.4 26.2-13.4 20 0 32.9 14.1 32.9 36v51.8h-13.6a5.378 5.378 0 0 1 -5.4-5.4v-43.3c0-13.6-6.9-21.9-17.9-21.9-12.6 0-22.2 9.8-22.2 28.2v42.4h-13.6a5.378 5.378 0 0 1 -5.4-5.4zm134.6-1.7c12.4 0 22.7 6.4 27.6 13.3v-54.6h18.9v129.2h-13.6a5.378 5.378 0 0 1 -5.4-5.4v-6.2c-4.8 6.9-15.2 13.3-27.6 13.3-23.6 0-41.5-20.2-41.5-44.8.1-24.6 18-44.8 41.6-44.8m3.4 17.2c-15.3 0-25.7 12.1-25.7 27.6s10.3 27.6 25.7 27.6c15.3 0 25.7-12.1 25.7-27.6s-10.4-27.6-25.7-27.6m64.6-15.5h18.9v15.3a24.26 24.26 0 0 1 22.7-16.2 38.52 38.52 0 0 1 7.4.7v19.5a30.541 30.541 0 0 0 -9.5-1.6c-10.9 0-20.7 9.1-20.7 26.4v42h-13.6a5.378 5.378 0 0 1 -5.4-5.4v-80.7zm100.2 87.9c-25.5 0-45.1-19.8-45.1-44.8s19.6-44.8 45.1-44.8 45.1 19.8 45.1 44.8-19.6 44.8-45.1 44.8m0-17.6c15.2 0 25.8-11.9 25.8-27.2s-10.7-27.2-25.8-27.2c-15.3 0-26 11.9-26 27.2s10.7 27.2 26 27.2m69.9-89.1a12.65 12.65 0 1 1 0-25.3 12.65 12.65 0 0 1 0 25.3m-9.4 18.8h18.9v86.1h-13.6a5.378 5.378 0 0 1 -5.4-5.4c.1 0 .1-80.7.1-80.7zm76-1.7c12.4 0 22.7 6.4 27.6 13.3v-54.6h18.9v129.2h-13.6a5.378 5.378 0 0 1 -5.4-5.4v-6.2c-4.8 6.9-15.2 13.3-27.6 13.3-23.6 0-41.5-20.2-41.5-44.8.1-24.6 18-44.8 41.6-44.8m3.5 17.2c-15.3 0-25.7 12.1-25.7 27.6s10.3 27.6 25.7 27.6c15.3 0 25.7-12.1 25.7-27.6s-10.4-27.6-25.7-27.6"/><path d="m851.3 122.011a9.6 9.6 0 1 1 9.6-9.6 9.602 9.602 0 0 1 -9.6 9.6m-105.7 0a9.6 9.6 0 1 1 9.6-9.6 9.602 9.602 0 0 1 -9.6 9.6m109.1-57.6 19.2-33.1a3.963 3.963 0 1 0 -6.9-3.9l-19.4 33.5a117.178 117.178 0 0 0 -49.1-10.6 119.152 119.152 0 0 0 -49.2 10.5l-19.5-33.5a3.963 3.963 0 1 0 -6.9 3.9l19.1 33.1a113.107 113.107 0 0 0 -58.6 90.4h229.7a112.654 112.654 0 0 0 -58.4-90.3" fill="#3ddc84"/></svg>
@@ -0,0 +1 @@
1
+ <?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" width="185" height="39" viewBox="0 0 185 39" fill="none"><path d="M0 1.90636C1.72886 1.56474 5.2315 1.31128 8.52083 1.31128C12.5399 1.31128 15.0097 1.69698 17.1203 2.92021C19.1522 3.97813 20.6229 5.92868 20.6229 8.5184C20.6229 11.1081 19.1073 13.4444 15.8292 14.6345V14.7227C19.1522 15.6153 21.622 18.0728 21.622 21.7645C21.622 24.3542 20.4096 26.3929 18.5909 27.8366C16.4691 29.4896 12.9328 30.4263 7.12876 30.4263C3.88433 30.4263 1.47066 30.2169 0 30.0075L0 1.90636ZM6.52254 12.8603H8.68923C12.147 12.8603 14.0105 11.4608 14.0105 9.33388C14.0105 7.20701 12.3266 6.02786 9.34036 6.02786C7.91461 6.02786 7.09508 6.11602 6.53376 6.19317V12.8603H6.52254ZM6.52254 25.5444C7.17367 25.6326 7.94829 25.6326 9.07093 25.6326C12.0571 25.6326 14.6954 24.4865 14.6954 21.511C14.6954 18.5356 12.0571 17.4777 8.76781 17.4777H6.52254V25.5444Z" fill="#311C6B"></path><path d="M23.306 16.2106C23.306 13.158 23.2162 11.1634 23.1376 9.37813H28.7957L29.009 13.2021H29.1774C30.2551 10.1936 32.8484 8.91528 34.8804 8.91528C35.4866 8.91528 35.7897 8.91528 36.2612 9.00344V15.1196C35.7897 14.9873 35.2284 14.9102 34.4875 14.9102C32.0626 14.9102 30.4235 16.1885 29.9857 18.1832C29.8959 18.6019 29.851 19.1199 29.851 19.6268V30.1509H23.2835V16.2326L23.306 16.2106Z" fill="#311C6B"></path><path d="M45.6577 3.60349C45.6577 5.38874 44.2769 6.83237 42.1102 6.83237C39.9435 6.83237 38.6525 5.38874 38.6974 3.60349C38.6525 1.7411 40.0333 0.341553 42.1551 0.341553C44.2769 0.341553 45.6128 1.7411 45.6577 3.60349ZM38.8658 30.1288V9.378H45.4332V30.1288H38.8658Z" fill="#311C6B"></path><path d="M68.9972 27.1205C68.9972 31.1097 68.1777 34.3827 65.7977 36.4544C63.4626 38.405 60.308 39.0001 57.1982 39.0001C54.4365 39.0001 51.4952 38.4491 49.5867 37.3912L50.889 32.5093C52.2249 33.2696 54.56 34.0741 57.0298 34.0741C60.1396 34.0741 62.5195 32.4211 62.5195 28.5971V27.2417H62.4297C61.1724 28.9828 59.1404 29.9526 56.7267 29.9526C51.4952 29.9526 47.7793 25.798 47.7793 19.8142C47.7793 13.147 52.1913 8.9043 57.3779 8.9043C60.2743 8.9043 62.0929 10.1385 63.1707 11.8356H63.2605L63.4738 9.37816H69.1768C69.087 10.6895 69.0084 12.4307 69.0084 15.5274V27.1094L68.9972 27.1205ZM62.4297 17.8305C62.4297 17.4118 62.3848 16.982 62.295 16.6404C61.8235 14.9433 60.5662 13.7972 58.7475 13.7972C56.3675 13.7972 54.4253 15.9241 54.4253 19.6929C54.4253 22.7896 55.9858 25.214 58.7475 25.214C60.4314 25.214 61.7786 24.112 62.2052 22.5802C62.3736 22.1173 62.4185 21.4341 62.4185 20.8831V17.8305H62.4297Z" fill="#311C6B"></path><path d="M72.545 0H79.1124V11.8355H79.2022C79.8983 10.9429 80.7627 10.2266 81.7955 9.70867C82.7947 9.20175 83.9959 8.90421 85.2084 8.90421C89.407 8.90421 92.5953 11.7474 92.5953 17.9847V30.1178H86.0279V18.701C86.0279 15.9901 85.0736 14.1167 82.6151 14.1167C80.8862 14.1167 79.8085 15.2187 79.3257 16.3648C79.1573 16.7836 79.1124 17.3346 79.1124 17.8084V30.1178H72.545V0Z" fill="#311C6B"></path><path d="M103.496 3.73584V9.37811H108.211V14.1278H103.496V21.6434C103.496 24.145 104.102 25.2911 106.089 25.2911C106.999 25.2911 107.391 25.247 108.031 25.1258L108.076 30.0077C107.212 30.3493 105.651 30.6027 103.799 30.6027C101.677 30.6027 99.9035 29.8424 98.8706 28.7734C97.6582 27.5392 97.052 25.5445 97.052 22.6242V14.1388H94.2454V9.38913H97.052V5.48803L103.496 3.74686V3.73584Z" fill="#311C6B"></path><path d="M111.276 25.6326C112.96 26.6465 115.43 27.495 118.023 27.495C121.874 27.495 124.119 25.5004 124.119 22.6131C124.119 19.9353 122.559 18.4145 118.629 16.9268C113.869 15.2738 110.939 12.8494 110.939 8.81602C110.939 4.36391 114.7 1.04688 120.369 1.04688C123.356 1.04688 125.511 1.73012 126.813 2.44642L125.781 5.4549C124.826 4.94798 122.884 4.09943 120.246 4.09943C116.272 4.09943 114.756 6.43568 114.756 8.38624C114.756 11.0641 116.53 12.3755 120.549 13.9073C125.477 15.7697 127.981 18.1059 127.981 22.3156C127.981 26.7236 124.658 30.5917 117.776 30.5917C114.97 30.5917 111.893 29.7431 110.344 28.7293L111.298 25.6326H111.276Z" fill="#311C6B"></path><path d="M135.491 3.82405C135.536 5.10237 134.582 6.11622 133.066 6.11622C131.73 6.11622 130.776 5.10237 130.776 3.82405C130.776 2.54572 131.775 1.48779 133.156 1.48779C134.537 1.48779 135.491 2.50164 135.491 3.82405ZM131.259 30.14V9.58754H135.065V30.1289H131.259V30.14Z" fill="#311C6B"></path><path d="M157.495 27.1644C157.495 31.8699 156.541 34.7572 154.509 36.5425C152.477 38.4159 149.536 38.9999 146.898 38.9999C144.259 38.9999 141.621 38.4048 139.937 37.3028L140.892 34.4597C142.272 35.3082 144.439 36.0686 147.032 36.0686C150.928 36.0686 153.779 34.074 153.779 28.8945V26.6024H153.69C152.522 28.5088 150.277 30.0406 147.032 30.0406C141.846 30.0406 138.13 25.7097 138.13 20.0234C138.13 13.0587 142.755 9.11353 147.56 9.11353C151.186 9.11353 153.184 10.9759 154.083 12.684H154.172L154.341 9.58739H157.664C157.574 11.0751 157.495 12.7281 157.495 15.2297V27.1534V27.1644ZM153.735 17.6982C153.735 17.059 153.69 16.508 153.521 16.0011C152.825 13.8411 150.973 12.0559 148.2 12.0559C144.574 12.0559 141.98 15.0644 141.98 19.825C141.98 23.8584 144.057 27.2085 148.166 27.2085C150.501 27.2085 152.623 25.7648 153.443 23.3845C153.656 22.7453 153.746 22.029 153.746 21.3899V17.6982H153.735Z" fill="#311C6B"></path><path d="M161.211 15.1525C161.211 13.0256 161.166 11.2955 161.042 9.58735H164.41L164.624 12.9815H164.713C165.746 11.031 168.171 9.12451 171.629 9.12451C174.525 9.12451 179.016 10.8216 179.016 17.8634V30.1287H175.21V18.2932C175.21 14.9872 173.953 12.2211 170.372 12.2211C167.868 12.2211 165.915 13.9623 165.275 16.0451C165.106 16.508 165.017 17.1471 165.017 17.7863V30.1398H161.211V15.1635V15.1525Z" fill="#311C6B"></path><path d="M182.036 8.41943C183.709 8.41943 185 9.69776 185 11.2846C185 12.8715 183.698 14.1609 182.014 14.1609C180.33 14.1609 179.016 12.9046 179.016 11.2846C179.016 9.6647 180.352 8.41943 182.014 8.41943H182.036ZM182.003 8.99248C180.723 8.99248 179.769 10.0173 179.769 11.2736C179.769 12.5299 180.723 13.5548 182.047 13.5548C183.327 13.5768 184.27 12.5409 184.27 11.2736C184.27 10.0063 183.327 8.99248 182.025 8.99248H182.003ZM181.565 12.7613H180.891V9.91816C181.161 9.86306 181.531 9.81898 182.014 9.81898C182.564 9.81898 182.811 9.90714 183.024 10.0504C183.181 10.1716 183.305 10.403 183.305 10.6565C183.305 10.9871 183.058 11.2295 182.699 11.3397V11.3728C182.979 11.461 183.148 11.6814 183.237 12.0671C183.327 12.5079 183.383 12.6842 183.451 12.7613H182.721C182.631 12.6511 182.575 12.4087 182.485 12.0781C182.429 11.7695 182.25 11.6263 181.879 11.6263H181.565V12.7613ZM181.576 11.1524H181.902C182.272 11.1524 182.575 11.0312 182.575 10.7336C182.575 10.4692 182.384 10.2928 181.958 10.2928C181.778 10.2928 181.655 10.3149 181.587 10.3259V11.1414L181.576 11.1524Z" fill="#311C6B"></path></svg>
@@ -0,0 +1 @@
1
+ <svg viewBox="-2.8000000000000007 0 622.9 123.2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="2500" height="492"><radialGradient id="b" cx="59.114" cy="59.914" gradientUnits="userSpaceOnUse" r="64.282"><stop offset="0" stop-color="#c22043"/><stop offset=".5" stop-color="#c22043"/><stop offset=".744" stop-color="#c02042"/><stop offset=".846" stop-color="#b91f3f"/><stop offset=".922" stop-color="#ae1e3a"/><stop offset=".984" stop-color="#a01c33"/><stop offset="1" stop-color="#9b1b31"/></radialGradient><linearGradient id="c" gradientTransform="matrix(1 0 0 -1 0 126.148)" gradientUnits="userSpaceOnUse" x1="36.363" x2="68.853" y1="118.196" y2="28.93"><stop offset="0" stop-color="#f18996"/><stop offset=".236" stop-color="#dd5f70"/><stop offset=".472" stop-color="#ce3d55"/><stop offset=".668" stop-color="#c52848"/><stop offset=".801" stop-color="#c22043"/><stop offset="1" stop-color="#c22043"/></linearGradient><linearGradient id="d" gradientTransform="matrix(1 0 0 -1 0 126.148)" gradientUnits="userSpaceOnUse" x1="20.489" x2="95.025" y1="96.137" y2="21.601"><stop offset="0" stop-color="#ce435d"/><stop offset=".116" stop-color="#ba354f"/><stop offset=".271" stop-color="#a82944"/><stop offset=".447" stop-color="#9b203c"/><stop offset=".658" stop-color="#941b37"/><stop offset="1" stop-color="#921936"/></linearGradient><linearGradient id="e" gradientTransform="matrix(1 0 0 -1 0 126.148)" gradientUnits="userSpaceOnUse" x1="63.416" x2="64.788" y1="67.105" y2="67.105"><stop offset="0" stop-color="#b4bdc3"/><stop offset=".055" stop-color="#a9b3b9"/><stop offset=".506" stop-color="#646a71"/><stop offset=".833" stop-color="#3f464e"/><stop offset="1" stop-color="#343b42"/></linearGradient><linearGradient id="a"><stop offset="0" stop-color="#b4bbc2"/><stop offset=".159" stop-color="#959ca2"/><stop offset=".56" stop-color="#565d62"/><stop offset=".851" stop-color="#363d42"/><stop offset="1" stop-color="#2b3337"/></linearGradient><linearGradient id="f" gradientTransform="matrix(1 0 0 -1 0 126.148)" gradientUnits="userSpaceOnUse" x1="75.664" x2="76.873" xlink:href="#a" y1="40.005" y2="40.005"/><linearGradient id="g" gradientTransform="scale(11.459) rotate(45 -166.893 1257.52)" gradientUnits="userSpaceOnUse" x1="-933.609" x2="-932.208" y1="250.308" y2="250.308"><stop offset="0" stop-color="#acbcc3"/><stop offset="1" stop-color="#272b31"/></linearGradient><linearGradient id="h" gradientTransform="scale(75.1015) rotate(45 -155.48 1351.815)" gradientUnits="userSpaceOnUse" x1="-1000.958" x2="-999.557" y1="286.084" y2="286.084"><stop offset="0" stop-color="#b4bdc3"/><stop offset="1" stop-color="#3f464e"/></linearGradient><linearGradient id="i" gradientTransform="rotate(180 -34588.66 9737.986) scale(67.4051)" gradientUnits="userSpaceOnUse" x1="-1027.906" x2="-1026.503" y1="288.026" y2="288.026"><stop offset="0" stop-color="#b4bdc3"/><stop offset="1" stop-color="#49535b"/></linearGradient><linearGradient id="j" gradientTransform="matrix(1 0 0 -1 0 126.148)" gradientUnits="userSpaceOnUse" x1="63.48" x2="64.667" xlink:href="#a" y1="113.687" y2="113.687"/><radialGradient id="k" cx="330.82" cy="397.374" gradientTransform="matrix(.6971 0 0 -.6971 -189.86 316.744)" gradientUnits="userSpaceOnUse" r="113.067"><stop offset="0" stop-color="#fff"/><stop offset=".35" stop-color="#fff"/><stop offset=".498" stop-color="#fcfcfd"/><stop offset=".65" stop-color="#f1f4f6"/><stop offset=".804" stop-color="#e0e6e9"/><stop offset=".96" stop-color="#c7d2d8"/><stop offset="1" stop-color="#c0cdd3"/></radialGradient><radialGradient id="l" cx="328.037" cy="398.159" gradientTransform="matrix(.6971 0 0 -.6971 -189.86 316.744)" gradientUnits="userSpaceOnUse" r="16.506"><stop offset="0" stop-color="#fff"/><stop offset=".35" stop-color="#fff"/><stop offset=".521" stop-color="#fcfdfd"/><stop offset=".698" stop-color="#f2f5f6"/><stop offset=".878" stop-color="#e0e7eb"/><stop offset="1" stop-color="#d0dbe0"/></radialGradient><path d="M173.6 101.6h33.7V86h-38.1V21.9h-18.4v79.7zM247.8 71.2h15v13.9c-2.8 1.1-8.2 2.1-13.3 2.1-16.6 0-22.1-8.4-22.1-25.5 0-16.3 5.3-25.9 21.8-25.9 9.2 0 14.5 2.9 18.8 8.4l11.4-10.5c-7-10-19.2-13-30.6-13-25.8 0-39.3 14.1-39.3 40.9 0 26.7 12.2 41.2 39.2 41.2 12.4 0 24.5-3.2 31-7.8V56.3h-31.9z" fill="#5a6870"/><path d="M374.1 47.2h2.1l-17 53.3h-2.7l-16.6-51.3h-.2L323 100.5h-2.9l-16.6-53.4h2.1l15.9 51.3h.2l16.5-51.3h3.2l16.4 51.3h.2zM380.1 74.2c.2 14.3 5.9 25.4 21.1 25.4 11 0 19.1-6.1 20.9-17.6h2.1c-1.5 12.2-10.6 19.7-22.7 19.7-16.5.2-23.4-12-23.4-27.9 0-17.8 11.3-27.9 23.4-27.9 16.6 0 24 13.7 23.4 28.3h-44.8zm42.5-2c.1-13.1-7.3-24.2-21.1-24.2-11.5 0-20.8 9.2-21.5 24.2zM436.4 83.6c2.7 9.1 9.5 16.1 20.3 16.1 13.8 0 20.7-12 20.7-25.7 0-12.4-6-25.9-20.7-25.9-13 0-21.6 9.4-21.6 25.9v.5H433V26.4h2.1v35.7h.2c2.5-9.7 10.1-16.2 21.4-16.2 14.7 0 22.7 13.1 22.7 28 0 16.1-8.6 27.8-22.7 27.8-10.9 0-19.8-7.6-22.4-18.2h.1" fill="#7c7b7b"/><path d="M522.6 24.6c24.5 0 37.7 17.7 37.7 38.8s-13.2 38.8-37.7 38.8-37.7-17.7-37.7-38.8c0-21 13.2-38.8 37.7-38.8zm0 75.6c22 0 35.2-15.4 35.4-36.7-.2-21.4-13.4-36.7-35.4-36.7s-35.2 15.4-35.4 36.7c.2 21.3 13.4 36.7 35.4 36.7zM616.5 47.2c-.5-15.2-11-20.4-24.8-20.4-10.8 0-23.9 3.7-23.9 17 0 13.4 13.2 14.9 26.3 18 14.2 3.5 26 5.2 26 20.7 0 14-13.9 19.9-26.9 19.9-17.3 0-30.1-7.7-29.8-26.4h2.1c0 17.7 11.4 24.3 27.6 24.3 12 0 24.8-5.2 24.8-18 0-14.9-14.9-16.2-26.7-19-12.4-2.8-25.6-5-25.6-19.5 0-14.7 13.8-19.1 26-19.1 14.9 0 26.1 5.9 26.9 22.5z" fill="#c2064c"/><path d="M61.5 0C27.6 0 0 27.6 0 61.6s27.6 61.6 61.5 61.6 61.4-27.3 61.7-61.1v-1C122.9 27.3 95.5 0 61.5 0z" fill="url(#b)"/><path d="M19.9 19.9c-20.6 20.6-22.7 51.9-4.6 70s49.4 16 70-4.6 22.7-52 4.6-70.1C81.7 7 70.7 3 59.1 3c-13.6 0-28 5.7-39.2 16.9" fill="url(#c)"/><path d="M58.4 89.2l1.5-.9v-52l-.4-.6.4-.1v-.1h.3l4.6-1.6.8 1.4s.1.1.1.4l-.1 47.4h11.2l.9 1.4c.1.1.1.2.1.6v4.8c0 .3-.2.4-.3.4H60.4c-.4 0-.8-.2-.9-.2zM114 58.7H75.9v6.1l.9 1.3s.1.1.3.1h31.8c-1.6 24.1-22 43-46.3 43-12.4 0-24-4.8-32.8-13.5-8.6-8.7-13.4-20.2-13.4-32.6 0-12.3 4.6-24.1 13.3-32.8 8.8-8.7 19.9-13.3 33.1-13.5h2.8c.2 0 .3 0 .3-.4v-5c0-.4-.1-.5-.1-.5l-1.1-1.4-2.5.4-1.3.4c-28.9 0-50.6 24.2-50.6 53 0 13.9 5.5 27.1 15.4 36.9 9.9 9.9 23 14.9 37 14.9 14.1 0 27.3-5.3 37.2-15.2s15.4-23 15.4-36.9v-3zM42.7 34.6c-4.6 0-8.3 3.7-8.3 8.2s3.7 8.2 8.3 8.2 8.3-3.7 8.3-8.2-3.7-8.2-8.3-8.2z" fill="url(#d)"/><path d="M59.7 88l-1.3 1.2h18.5L75.7 88z" fill="#646e78"/><path d="M75.7 84.3l1.2-1.2H64.8l-1.5 1.2z" fill="#8599a2"/><path d="M64.8 33.9h-6.4l1.2 1.1h3.8z" fill="#8f9ca3"/><path d="M63.5 84.2l1.3-1.1V33.9L63.4 35z" fill="url(#e)"/><path d="M75.7 84.3V88l1.2 1.2v-6.1z" fill="url(#f)"/><path d="M58.4 33.9v55.3l1.3-1.2-.1-53z" fill="#b4bdc3"/><path d="M35.1 41.9c0 3.8 3.1 6.8 6.9 6.8s6.8-3 6.8-6.8-3.1-6.8-6.8-6.8c-3.9 0-6.9 3-6.9 6.8z" fill="none"/><path d="M33.9 41.9c0 4.4 3.6 8 8 8s8-3.6 8-8-3.6-8-8-8-8 3.6-8 8zm14.9 0c0 3.8-3.1 6.8-6.8 6.8-3.8 0-6.9-3-6.9-6.8s3.1-6.8 6.9-6.8c3.7 0 6.8 3 6.8 6.8z" fill="url(#g)"/><path d="M108.8 63.5l-32-.1-1.2 1.3h31.9l.7-.7z" fill="#525e62"/><path d="M76.8 59.8h35.7l1.3-1.3-38.2.1z" fill="#919ea6"/><path d="M113.8 61.6v-3l-1.2 1.2v1.8c0 13.6-5.3 26.4-14.9 36.1-9.6 9.6-22.4 14.9-36.1 14.9-13.6 0-26.4-5.3-36-14.9-9.7-9.7-15-22.5-15-36.1 0-28.1 22.9-51 50.9-51h2l1.2-1.2h-3.1C32.8 9.4 9.4 32.8 9.4 61.6c0 13.9 5.4 27.1 15.3 36.9 9.8 9.9 22.9 15.3 36.9 15.3s27.1-5.4 36.9-15.3 15.3-23 15.3-36.9z" fill="url(#h)"/><path d="M63.5 14.3h-2.6c-12.3.2-23.9 5.1-32.7 13.8-9 8.9-13.9 20.8-13.9 33.5 0 12.6 4.9 24.5 13.8 33.4 8.8 8.8 20.4 13.7 32.8 13.9h1.2c24.5-.3 44.9-19.6 46.6-44.1v-1.3l-.6.6-.6.7c-1.7 24.1-21.8 43-46 43-12.3 0-23.9-4.8-32.6-13.5S15.4 74 15.4 61.7s4.8-23.9 13.5-32.6 20.3-13.5 32.6-13.5h3.1z" fill="url(#i)"/><path d="M76.8 59.8l-1.2-1.2v6.1l1.2-1.3z" fill="#b4bdc3"/><path d="M63.5 14.3l1.2 1.2V9.4l-1.2 1.1z" fill="url(#j)"/><path d="M59.1 34.6v54h17.2v-4.8H64V34.6zM60.9 10C32.8 10.3 10 33.3 10 61.6c0 13.8 5.4 26.7 15.1 36.5 9.7 9.7 22.7 15.1 36.4 15.1 13.8 0 26.8-5.4 36.5-15.1s15.1-22.7 15.1-36.5v-2.3H76.3V64h31.9v.7c-1.7 24.3-21.9 43.6-46.6 43.6-12.5 0-24.2-4.9-33-13.7s-13.7-20.5-13.7-33 4.9-24.2 13.7-33c8.9-8.8 20.6-13.7 33-13.7h2.5V10h-3.2z" fill="url(#k)"/><path d="M34.5 41.9c0 4.1 3.3 7.4 7.4 7.4s7.4-3.3 7.4-7.4-3.3-7.4-7.4-7.4-7.4 3.3-7.4 7.4" fill="url(#l)"/><g fill="#fff"><path d="M43.2 35.9c1.7 0 3.2.6 4.5 1.6-1.3-1.8-3.5-2.9-5.8-2.9-4.1 0-7.4 3.3-7.4 7.4 0 2.4 1.1 4.4 2.9 5.8-1-1.2-1.5-2.8-1.5-4.4-.1-4.2 3.2-7.5 7.3-7.5"/><path d="M64 10h-2.5C33.1 10 10 33.1 10 61.6c0 13.8 5.4 26.7 15.1 36.5l.9.9c-9.2-9.6-14.2-22.2-14.2-35.5C11.8 35 31.9 11.5 64 10M64 83.7s3.5 1 12.2 1v-1zM64 36.1v-1.5h-4.9v54s1.5-8.2 1.5-52.5zM113.1 59.2H76.3V64h1.3v-3.4c32.1 0 35.5-1.4 35.5-1.4"/><path d="M108.2 64v.7c-1.6 24.3-21.9 43.6-46.6 43.6-12.5 0-24.2-4.9-33-13.7-5.8-5.7-9.8-12.8-11.9-20.4 5.5 20.1 23.9 34.7 45.8 34.7 23.5 0 45.1-18.4 46.4-44.9z"/></g></svg>
@@ -0,0 +1 @@
1
+ <svg height="667" width="2500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 32"><path d="M0 0h120v32H0z" fill="none"/><path d="M8 19.651v-1.14h3.994v1.45a1.334 1.334 0 0 0 1.494 1.346 1.3 1.3 0 0 0 1.444-1.007 1.833 1.833 0 0 0-.026-1.113c-.773-1.944-6.055-2.824-6.726-5.854a5.347 5.347 0 0 1-.025-2.02C8.567 8.88 10.705 8 13.359 8c2.113 0 5.025.492 5.025 3.754v1.062h-3.71v-.932a1.275 1.275 0 0 0-1.392-1.347 1.25 1.25 0 0 0-1.365 1.01 2.021 2.021 0 0 0 .026.777c.437 1.734 6.081 2.667 6.7 5.8a6.943 6.943 0 0 1 .025 2.46C18.307 23.068 16.091 24 13.412 24 10.6 24 8 22.99 8 19.651zm48.392-.051v-1.14h3.943v1.424A1.312 1.312 0 0 0 61.8 21.23a1.286 1.286 0 0 0 1.443-.984 1.759 1.759 0 0 0-.025-1.088c-.748-1.915-5.979-2.8-6.648-5.825a5.215 5.215 0 0 1-.026-1.994c.415-2.407 2.556-3.287 5.156-3.287 2.088 0 4.973.518 4.973 3.728v1.036h-3.684v-.906a1.268 1.268 0 0 0-1.365-1.346 1.2 1.2 0 0 0-1.34.984 2.017 2.017 0 0 0 .025.777c.412 1.734 6 2.641 6.623 5.747a6.806 6.806 0 0 1 .025 2.434c-.361 2.486-2.551 3.392-5.2 3.392-2.787.002-5.365-1.011-5.365-4.298zm14.121.545a5.876 5.876 0 0 1-.025-.985V8.44h3.762v11.055a4.111 4.111 0 0 0 .025.57 1.468 1.468 0 0 0 2.835 0 3.97 3.97 0 0 0 .026-.57V8.44H80.9v10.718c0 .285-.026.829-.026.985-.257 2.8-2.448 3.7-5.179 3.7s-4.924-.905-5.182-3.7zm30.974-.156a7.808 7.808 0 0 1-.052-.989v-6.288c0-.259.025-.725.051-.985.335-2.795 2.577-3.675 5.231-3.675 2.629 0 4.947.88 5.206 3.676a7.185 7.185 0 0 1 .025.985v.487h-3.762v-.824a3.1 3.1 0 0 0-.051-.57 1.553 1.553 0 0 0-2.964 0 3.088 3.088 0 0 0-.051.7v6.834a4.17 4.17 0 0 0 .026.57 1.472 1.472 0 0 0 1.571 1.09 1.406 1.406 0 0 0 1.52-1.087 2.09 2.09 0 0 0 .026-.57v-2.178h-1.52V14.99H112V19a7.674 7.674 0 0 1-.052.984c-.257 2.718-2.6 3.676-5.231 3.676s-4.973-.955-5.23-3.673zm-52.438 3.389l-.1-13.825-2.58 13.825h-3.762L40.055 9.553l-.1 13.825h-3.713l.309-14.912h6.056l1.881 11.651 1.881-11.651h6.055l.335 14.912zm-19.79 0l-2.01-13.825-2.062 13.825h-4.019L23.9 8.466h6.623l2.732 14.912zm62.977-.155L88.5 10.822l.206 12.4h-3.66V8.466h5.514l3.5 12.013-.201-12.013h3.685v14.758z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" viewBox="0 0 512 467.74"><path d="M483.71 217.08 460.1 444.05l23.61-226.97zM108.89 36.72C95.41 24.21 75.67 18.25 55.18 19.66 113.33 67.25 44.4 128.72 6.04 57.24c-15.74 35.4.66 67.97 33.33 84.73 15.41 7.92 23.53 12.64 29.12 18.85 3.1 3.35 5.29 7.19 7.77 12.19l10.62 24.09H29.64c-11.03 0-19.98 8.95-19.98 19.98v170.24c0 22.02 9.03 42.09 23.56 56.68l.12.13c14.6 14.56 34.69 23.61 56.73 23.61h313.22c22.07 0 42.17-9.06 56.74-23.61 14.63-14.64 23.68-34.74 23.68-56.81V217.08c0-11.03-8.94-19.98-19.98-19.98h-87.35l48.47-81.21-39.05-22.53-62.27 103.74h-49.45l-.02-1.6c-.01-.51-.18-1.02-.53-1.45a232.35 232.35 0 0 0-4.98-5.87l-.06-.07c-3.08-3.55-4.64-5.34-4.67-6.54-.03-1.21 1.5-3.09 4.55-6.86 1.26-1.55 2.75-3.38 4.51-5.67.35-.4.56-.93.56-1.51l-.06-13.17a2.307 2.307 0 0 0-2.31-2.29l-20.21.09.4-92.04 12.17-21.28c1.21-1.86 1.91-4.09 1.9-6.47l-.08-20.68C265.21 5.2 259.92-.03 253.43 0l-28.4.09c-6.5.1-11.7 5.45-11.61 11.95l.32 23.07c.04 2.27.73 4.56 2.12 6.56l11.41 16.28-.41 94.31-23.91.09c-1.27 0-2.29 1.04-2.28 2.31l.05 12.91c0 .55.2 1.1.59 1.53 1.92 2.14 3.61 3.94 5.04 5.47 4.18 4.47 6.2 6.63 6.22 8.18.01 1.47-1.68 3.6-4.94 7.71-1.44 1.81-3.17 3.97-5.16 6.64h-59.62l-19.13-43.47c-2.74-6.51-4.19-11.01-4.62-15.78-.41-4.41 0-9.01 1.14-15.65 5.54-32.4 16.85-59.34-11.35-85.48zm8.9 363.62V292.93h48.12c19.36 0 32.65 4.12 39.87 12.37 7.22 8.25 10.83 22.03 10.83 41.34 0 19.3-3.61 33.08-10.83 41.33-7.22 8.25-20.51 12.37-39.87 12.37h-48.12zm48.64-79.92h-14.27v52.43h14.27c4.69 0 8.1-.55 10.22-1.64 2.12-1.08 3.18-3.58 3.18-7.48v-34.19c0-3.9-1.06-6.39-3.18-7.48-2.12-1.09-5.53-1.64-10.22-1.64zm66.08 79.92V292.93h34.37v107.41h-34.37zm84.82-107.41 9.45 37.81h1.2l9.63-37.81h37.98l-30.94 78.2v29.21h-34.37v-29.21l-30.94-78.2h37.99zm146.4-48.82v143.21c0 33.22-27.22 60.43-60.44 60.43H90.07c-33.22 0-60.43-27.2-60.43-60.43V244.11h434.09zM313.71 78.47c6.73-4.96 14.09-8.56 22.09-10.71 12.04-3.22 22.97-2.03 32.78 3.53l84.92 48.97-5.1 8.9 32.28 18.79L512 93.65l-32.25-18.61-5.83 9.82-84.43-48.71c-11.61-6.66-22.65-8.53-33.17-5.71-17.66 4.73-31.85 20.71-42.61 48.03z"/></svg>