@olwiba/dx 0.0.21 → 0.0.22

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.
package/dist/index.d.ts CHANGED
@@ -26,18 +26,20 @@ declare function createDevBannerPlugin(project: string | BannerOptions | LegacyB
26
26
 
27
27
  declare function findFreePort(start: number, attempts?: number): Promise<number>;
28
28
  /**
29
- * Resolve the dev server port, or fail.
29
+ * Resolve the dev server port for a preferred base port, falling back to the
30
+ * next free one and saying so loudly.
30
31
  *
31
- * Deliberately does **not** fall back to the next free port. Silently moving to
32
- * 3001 looks like it worked and then breaks something unrelated several minutes
33
- * later: `BETTER_AUTH_TRUSTED_ORIGINS` pins an origin, so the app boots fine and
34
- * every sign-in fails with "Invalid origin" a message that points at auth
35
- * config rather than at the port that actually moved.
32
+ * Falling back is the right default a second app should start rather than
33
+ * refuse but the move used to be near-silent, and the port is not the thing
34
+ * that breaks. What breaks is anything holding an absolute localhost URL:
35
+ * sign-in fails "Invalid origin" if the origin is pinned, and magic links point
36
+ * at the port you are no longer on.
36
37
  *
37
- * Running a second app at the same time is still supported, but has to be said
38
- * out loud: `PORT=3001 bun run dev`.
38
+ * So callers are expected to do two things, and the log says so:
39
+ * - trust localhost on any port in dev (`http://localhost:*`)
40
+ * - derive `BETTER_AUTH_URL` from the port this returns, not from `.env`
39
41
  */
40
- declare function resolveDevPort(preferred: number): Promise<number>;
42
+ declare function resolveDevPort(preferred: number, attempts?: number): Promise<number>;
41
43
 
42
44
  type ProjectBrandAccent = {
43
45
  hex: string;
package/dist/index.js CHANGED
@@ -1446,17 +1446,19 @@ async function findFreePort(start, attempts = 20) {
1446
1446
  }
1447
1447
  throw new Error(`No free port found in range ${start}-${start + attempts - 1}`);
1448
1448
  }
1449
- async function resolveDevPort(preferred) {
1450
- if (await isFree(preferred)) return preferred;
1451
- throw new Error(
1452
- `Port ${preferred} is already in use.
1453
-
1454
- Free it, or start this app on another port explicitly:
1455
- PORT=${preferred + 1} bun run dev
1456
-
1457
- If you pick another port, add its origin to BETTER_AUTH_TRUSTED_ORIGINS
1458
- or sign-in will fail with "Invalid origin".`
1459
- );
1449
+ async function resolveDevPort(preferred, attempts = 20) {
1450
+ const port = await findFreePort(preferred, attempts);
1451
+ if (port !== preferred) {
1452
+ console.warn(
1453
+ `
1454
+ \u26A0 Port ${preferred} is in use \u2014 this dev server is on ${port} instead.
1455
+ Absolute URLs built from .env still say ${preferred}. Anything that
1456
+ emails you a link (magic link, email verification) will point at the
1457
+ wrong port unless BETTER_AUTH_URL is derived from ${port}.
1458
+ `
1459
+ );
1460
+ }
1461
+ return port;
1460
1462
  }
1461
1463
 
1462
1464
  // src/project-brand.ts
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ascii/compose.ts","../src/ascii/fonts/dosrebel-data.ts","../src/ascii/fonts.ts","../src/ascii/figlet.ts","../src/dos-rebel-font.ts","../src/dev-banner.ts","../src/find-free-port.ts","../src/project-brand.ts"],"names":["segments","renderDosRebel"],"mappings":";;;;;;;;;;;;;AAcO,SAAS,gBAAA,CAAiB,MAAkB,IAAA,EAA+B;AAChF,EAAA,MAAM,aAAwD,EAAC;AAE/D,EAAA,KAAA,MAAW,MAAM,IAAA,EAAM;AACrB,IAAA,MAAM,IAAA,GAAO,EAAA,CAAG,UAAA,CAAW,CAAC,CAAA;AAC5B,IAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA,IAAK,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,EAAE,CAAA;AACvD,IAAA,IAAI,CAAC,KAAA,EAAO;AAEZ,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,GAAG,KAAA,CAAM,IAAI,CAAC,IAAA,KAAS,IAAA,CAAK,MAAM,CAAC,CAAA;AAC1D,IAAA,UAAA,CAAW,IAAA,CAAK;AAAA,MACd,KAAA,EAAO,MAAM,GAAA,CAAI,CAAC,SAAS,IAAA,CAAK,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,MAC7C;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,IAAA,GAAO,WAAW,MAAA,CAAO,CAAC,KAAK,KAAA,KAAU,GAAA,GAAM,KAAA,CAAM,KAAA,EAAO,CAAC,CAAA;AACnE,EAAA,MAAM,OAAO,IAAA,CAAK,MAAA;AAClB,EAAA,MAAM,QAAqB,EAAC;AAC5B,EAAA,IAAI,OAAA,GAAU,CAAA;AAEd,EAAA,KAAA,MAAW,SAAS,UAAA,EAAY;AAC9B,IAAA,KAAA,IAAS,GAAA,GAAM,CAAA,EAAG,GAAA,GAAM,IAAA,EAAM,GAAA,EAAA,EAAO;AACnC,MAAA,MAAM,IAAA,GAAO,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA,IAAK,EAAA;AACjC,MAAA,KAAA,IAAS,GAAA,GAAM,CAAA,EAAG,GAAA,GAAM,IAAA,CAAK,QAAQ,GAAA,EAAA,EAAO;AAC1C,QAAA,MAAM,EAAA,GAAK,KAAK,GAAG,CAAA;AACnB,QAAA,IAAI,EAAA,KAAO,QAAA,IAAO,EAAA,KAAO,QAAA,EAAK;AAC5B,UAAA,KAAA,CAAM,KAAK,EAAE,EAAA,EAAI,KAAK,OAAA,GAAU,GAAA,EAAK,KAAK,CAAA;AAAA,QAC5C;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAA,IAAW,KAAA,CAAM,KAAA;AAAA,EACnB;AAEA,EAAA,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,IAAA,EAAK;AAC7B;AAhDA,IAAA,YAAA,GAAA,KAAA,CAAA;AAAA,EAAA,sBAAA,GAAA;AAAA,EAAA;AAAA,CAAA,CAAA;;;ACAA,IACa,YAAA;AADb,IAAA,kBAAA,GAAA,KAAA,CAAA;AAAA,EAAA,kCAAA,GAAA;AACO,IAAM,YAAA,GAAuB,CAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,EAAA;AAAA,CAAA,CAA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","file":"index.js","sourcesContent":["import type { FigletFont } from \"./figlet\"\n\nexport interface AsciiCell {\n ch: \"█\" | \"░\"\n col: number\n row: number\n}\n\nexport interface AsciiTextLayout {\n cells: AsciiCell[]\n cols: number\n rows: number\n}\n\nexport function composeAsciiText(font: FigletFont, text: string): AsciiTextLayout {\n const charBlocks: Array<{ lines: string[]; width: number }> = []\n\n for (const ch of text) {\n const code = ch.charCodeAt(0)\n const glyph = font.chars.get(code) ?? font.chars.get(32)\n if (!glyph) continue\n\n const width = Math.max(...glyph.map((line) => line.length))\n charBlocks.push({\n lines: glyph.map((line) => line.padEnd(width)),\n width,\n })\n }\n\n const cols = charBlocks.reduce((sum, block) => sum + block.width, 0)\n const rows = font.height\n const cells: AsciiCell[] = []\n let offsetX = 0\n\n for (const block of charBlocks) {\n for (let row = 0; row < rows; row++) {\n const line = block.lines[row] ?? \"\"\n for (let col = 0; col < line.length; col++) {\n const ch = line[col]\n if (ch === \"█\" || ch === \"░\") {\n cells.push({ ch, col: offsetX + col, row })\n }\n }\n }\n offsetX += block.width\n }\n\n return { cells, cols, rows }\n}\n\nexport function getAsciiAccentColumns(\n font: FigletFont,\n text: string,\n accent: string,\n): Set<number> {\n if (!accent) return new Set<number>()\n\n const columns = new Set<number>()\n const accentRanges: Array<{ start: number; end: number }> = []\n let searchFrom = 0\n while (true) {\n const idx = text.indexOf(accent, searchFrom)\n if (idx === -1) break\n accentRanges.push({ start: idx, end: idx + accent.length })\n searchFrom = idx + 1\n }\n if (accentRanges.length === 0) return columns\n\n let offsetX = 0\n let charIndex = 0\n\n for (const ch of text) {\n const code = ch.charCodeAt(0)\n const glyph = font.chars.get(code) ?? font.chars.get(32)\n if (!glyph) { charIndex++; continue }\n\n const width = Math.max(...glyph.map((line) => line.length))\n if (accentRanges.some((r) => charIndex >= r.start && charIndex < r.end)) {\n for (let col = 0; col < width; col++) columns.add(offsetX + col)\n }\n offsetX += width\n charIndex++\n }\n\n return columns\n}\n","// @generated from dosrebel.flf. Do not edit by hand.\nexport const dosrebelFont: string = \"flf2a$ 11 8 35 -1 15\\nRebel by Valerie Mates (popcorn@cyberspace.org), based on a font by Ron Bliss\\n(who sometimes goes by the name \\\"rebel\\\" because his initials are REB).\\nNOTE: THIS FONT ONLY WORKS IN MS-DOS.\\nMay 27, 1994\\n\\nExplanation of first line:\\nflf2 - \\\"magic number\\\" for file identification\\na - should always be `a', for now\\n$ - the \\\"hardblank\\\" -- prints as a blank, but can't be smushed\\n11 - height of a character\\n8 - height of a character, not including descenders\\n35 - max line length (excluding comment lines) + a fudge factor\\n-1 - default smushmode for this font (like \\\"-m 15\\\" on command line)\\n15 - number of comment lines\\n\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@@\\n ███@\\n░███@\\n░███@\\n░███@\\n░███@\\n░░░ @\\n ███@\\n░░░ @\\n @\\n @\\n @@\\n ██ ██@\\n░██░██@\\n░░ ░░ @\\n @\\n @\\n @\\n @\\n @\\n @\\n @\\n @@\\n ███ ███ @\\n ████████████@\\n░░░███░░███░ @\\n ████████████@\\n░░░███░░███░ @\\n ░░░ ░░░ @\\n @\\n @\\n @\\n @\\n @@\\n ███ @\\n ██████ @\\n ███░░░ @\\n ░░█████ @\\n ░░░░███ @\\n ██████ @\\n ░░░███ @\\n ░░░ @\\n @\\n @\\n @@\\n ███ ███@\\n ░░░ ███░ @\\n ███░ @\\n ███░ @\\n ███░ @\\n ███░ @\\n ███░ ███ @\\n░░░ ░░░ @\\n @\\n @\\n @@\\n ██████ @\\n ███░░███ @\\n ░░██████ @\\n ██████ @\\n░███░░███ @\\n░███ ░░███ @\\n░░█████░███@\\n ░░░░░ ░░░ @\\n @\\n @\\n @@\\n ██@\\n ███@\\n░░░ @\\n @\\n @\\n @\\n @\\n @\\n @\\n @\\n @@\\n ███@\\n ███ @\\n ███ @\\n░███ @\\n░███ @\\n░░███ @\\n ░░███@\\n ░░░ @\\n @\\n @\\n @@\\n ███ @\\n░░███ @\\n ░░███@\\n ░███@\\n ░███@\\n ███ @\\n ██░ @\\n░░░ @\\n @\\n @\\n @@\\n ███ @\\n ███ ░███ ███@\\n░░░█████████░ @\\n ░░░█████░ @\\n █████████ @\\n ███░░███░░███@\\n░░░ ░███ ░░░ @\\n ░░░ @\\n @\\n @\\n @@\\n @\\n ███ @\\n ░███ @\\n ███████████@\\n░░░░░███░░░ @\\n ░███ @\\n ░░░ @\\n @\\n @\\n @\\n @@\\n @\\n @\\n @\\n @\\n @\\n @\\n ██@\\n ██ @\\n░░ @\\n @\\n @@\\n @\\n @\\n @\\n ██████████@\\n░░░░░░░░░░ @\\n @\\n @\\n @\\n @\\n @\\n @@\\n @\\n @\\n @\\n @\\n @\\n @\\n ██@\\n░░ @\\n @\\n @\\n @@\\n ███@\\n ███░ @\\n ███░ @\\n ███░ @\\n ███░ @\\n ███░ @\\n ███░ @\\n░░░ @\\n @\\n @\\n @@\\n █████ @\\n ███░░░███ @\\n ███ ░░███@\\n░███ ░███@\\n░███ ░███@\\n░░███ ███ @\\n ░░░█████░ @\\n ░░░░░░ @\\n @\\n @\\n @@\\n ████ @\\n░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n █████@\\n░░░░░ @\\n @\\n @\\n @@\\n ████████ @\\n ███░░░░███@\\n░░░ ░███@\\n ███████ @\\n ███░░░░ @\\n ███ █@\\n░██████████@\\n░░░░░░░░░░ @\\n @\\n @\\n @@\\n ████████ @\\n ███░░░░███@\\n░░░ ░███@\\n ██████░ @\\n ░░░░░░███@\\n ███ ░███@\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n █████ █████ @\\n░░███ ░░███ @\\n ░███ ░███ █@\\n ░███████████@\\n ░░░░░░░███░█@\\n ░███░ @\\n █████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n ██████████@\\n░███░░░░░░█@\\n░███ ░ @\\n░█████████ @\\n░░░░░░░░███@\\n ███ ░███@\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n ████████ @\\n ███░░░░███@\\n░███ ░░░ @\\n░█████████ @\\n░███░░░░███@\\n░███ ░███@\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n ██████████@\\n░███░░░░███@\\n░░░ ███ @\\n ███ @\\n ███ @\\n ███ @\\n ███ @\\n ░░░ @\\n @\\n @\\n @@\\n ████████ @\\n ███░░░░███ @\\n░███ ░███ @\\n░░████████ @\\n ███░░░░███ @\\n░███ ░███ @\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n ████████ @\\n ███░░░░███@\\n░███ ░███@\\n░░█████████@\\n ░░░░░░░███@\\n ███ ░███@\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ██@\\n░░ @\\n @\\n @\\n ██@\\n░░ @\\n @\\n @\\n @@\\n @\\n @\\n @\\n @\\n ██@\\n ░░ @\\n ██@\\n ██ @\\n░░ @\\n @\\n @@\\n ███@\\n ███░ @\\n ███░ @\\n ███░ @\\n░░░███ @\\n ░░░███ @\\n ░░░███@\\n ░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████████@\\n░░░░░░░░░ @\\n █████████@\\n░░░░░░░░░ @\\n @\\n @\\n @\\n @\\n @@\\n ███ @\\n░░░███ @\\n ░░░███ @\\n ░░░███@\\n ███░ @\\n ███░ @\\n ███░ @\\n░░░ @\\n @\\n @\\n @@\\n ███████ @\\n ███░░░███@\\n░░░ ░███@\\n ███████ @\\n ░███░░░ @\\n ░░░ @\\n ███ @\\n ░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░░ @\\n░███ ██████ @\\n░███░███░███@\\n░███░███░███@\\n░███░░░ ░███@\\n░░█████████ @\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░███ @\\n ░███ ░███ @\\n ░███████████ @\\n ░███░░░░░███ @\\n ░███ ░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ███████████ @\\n░░███░░░░░███@\\n ░███ ░███@\\n ░██████████ @\\n ░███░░░░░███@\\n ░███ ░███@\\n ███████████ @\\n░░░░░░░░░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░███@\\n ███ ░░░ @\\n░███ @\\n░███ @\\n░░███ ███@\\n ░░█████████ @\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n ██████████ @\\n░░███░░░░███ @\\n ░███ ░░███@\\n ░███ ░███@\\n ░███ ░███@\\n ░███ ███ @\\n ██████████ @\\n░░░░░░░░░░ @\\n @\\n @\\n @@\\n ██████████@\\n░░███░░░░░█@\\n ░███ █ ░ @\\n ░██████ @\\n ░███░░█ @\\n ░███ ░ █@\\n ██████████@\\n░░░░░░░░░░ @\\n @\\n @\\n @@\\n ███████████@\\n░░███░░░░░░█@\\n ░███ █ ░ @\\n ░███████ @\\n ░███░░░█ @\\n ░███ ░ @\\n █████ @\\n░░░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░███@\\n ███ ░░░ @\\n░███ @\\n░███ █████@\\n░░███ ░░███ @\\n ░░█████████ @\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░███████████ @\\n ░███░░░░░███ @\\n ░███ ░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n █████@\\n░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n █████@\\n░░░░░ @\\n @\\n @\\n @@\\n █████@\\n ░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ███ ░███ @\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n █████ ████@\\n░░███ ███░ @\\n ░███ ███ @\\n ░███████ @\\n ░███░░███ @\\n ░███ ░░███ @\\n █████ ░░████@\\n░░░░░ ░░░░ @\\n @\\n @\\n @@\\n █████ @\\n░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ░███ █@\\n ███████████@\\n░░░░░░░░░░░ @\\n @\\n @\\n @@\\n ██████ ██████@\\n░░██████ ██████ @\\n ░███░█████░███ @\\n ░███░░███ ░███ @\\n ░███ ░░░ ░███ @\\n ░███ ░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ██████ █████@\\n░░██████ ░░███ @\\n ░███░███ ░███ @\\n ░███░░███░███ @\\n ░███ ░░██████ @\\n ░███ ░░█████ @\\n █████ ░░█████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ███████ @\\n ███░░░░░███ @\\n ███ ░░███@\\n░███ ░███@\\n░███ ░███@\\n░░███ ███ @\\n ░░░███████░ @\\n ░░░░░░░ @\\n @\\n @\\n @@\\n ███████████ @\\n░░███░░░░░███@\\n ░███ ░███@\\n ░██████████ @\\n ░███░░░░░░ @\\n ░███ @\\n █████ @\\n░░░░░ @\\n @\\n @\\n @@\\n ██████ @\\n ███░░░░███ @\\n ███ ░░███@\\n░███ ░███@\\n░███ ██░███@\\n░░███ ░░████ @\\n ░░░██████░██@\\n ░░░░░░ ░░ @\\n @\\n @\\n @@\\n ███████████ @\\n░░███░░░░░███ @\\n ░███ ░███ @\\n ░██████████ @\\n ░███░░░░░███ @\\n ░███ ░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░███@\\n░███ ░░░ @\\n░░█████████ @\\n ░░░░░░░░███@\\n ███ ░███@\\n░░█████████ @\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n ███████████@\\n░█░░░███░░░█@\\n░ ░███ ░ @\\n ░███ @\\n ░███ @\\n ░███ @\\n █████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░███ ███ @\\n ░░░█████░ @\\n ░░███ @\\n ░░░ @\\n @\\n @\\n @@\\n █████ ███ █████@\\n░░███ ░███ ░░███ @\\n ░███ ░███ ░███ @\\n ░███ ░███ ░███ @\\n ░░███ █████ ███ @\\n ░░░█████░█████░ @\\n ░░███ ░░███ @\\n ░░░ ░░░ @\\n @\\n @\\n @@\\n █████ █████@\\n░░███ ░░███ @\\n ░░███ ███ @\\n ░░█████ @\\n ███░███ @\\n ███ ░░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n █████ █████@\\n░░███ ░░███ @\\n ░░███ ███ @\\n ░░█████ @\\n ░░███ @\\n ░███ @\\n █████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n ███████████@\\n░█░░░░░░███ @\\n░ ███░ @\\n ███ @\\n ███ @\\n ████ █@\\n ███████████@\\n░░░░░░░░░░░ @\\n @\\n @\\n @@\\n █████@\\n░███░ @\\n░███ @\\n░███ @\\n░███ @\\n░███ @\\n░█████@\\n░░░░░ @\\n @\\n @\\n @@\\n ███ @\\n░░███ @\\n ░░███ @\\n ░░███ @\\n ░░███ @\\n ░░███ @\\n ░░███@\\n ░░░ @\\n @\\n @\\n @@\\n █████@\\n░░░███@\\n ░███@\\n ░███@\\n ░███@\\n ░███@\\n █████@\\n░░░░░ @\\n @\\n @\\n @@\\n ██ @\\n ████ @\\n ██░░██@\\n░░ ░░ @\\n @\\n @\\n @\\n @\\n @\\n @\\n @@\\n @\\n @\\n @\\n @\\n @\\n @\\n █████████@\\n░░░░░░░░░ @\\n @\\n @\\n @@\\n ██ @\\n░███@\\n░░░ @\\n @\\n @\\n @\\n @\\n @\\n @\\n @\\n @@\\n @\\n @\\n ██████ @\\n ░░░░░███ @\\n ███████ @\\n ███░░███ @\\n░░████████@\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n █████ @\\n░░███ @\\n ░███████ @\\n ░███░░███@\\n ░███ ░███@\\n ░███ ░███@\\n ████████ @\\n░░░░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ██████ @\\n ███░░███@\\n░███ ░░░ @\\n░███ ███@\\n░░██████ @\\n ░░░░░░ @\\n @\\n @\\n @@\\n █████@\\n ░░███ @\\n ███████ @\\n ███░░███ @\\n░███ ░███ @\\n░███ ░███ @\\n░░████████@\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ██████ @\\n ███░░███@\\n░███████ @\\n░███░░░ @\\n░░██████ @\\n ░░░░░░ @\\n @\\n @\\n @@\\n ██████ @\\n ███░░███@\\n ░███ ░░░ @\\n ███████ @\\n░░░███░ @\\n ░███ @\\n █████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ███████@\\n ███░░███@\\n░███ ░███@\\n░███ ░███@\\n░░███████@\\n ░░░░░███@\\n ███ ░███@\\n░░██████ @\\n ░░░░░░ @@\\n █████ @\\n░░███ @\\n ░███████ @\\n ░███░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ████ █████@\\n░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ███ @\\n ░░░ @\\n ████ @\\n░░███ @\\n ░███ @\\n ░███ @\\n █████@\\n░░░░░ @\\n @\\n @\\n @@\\n ███ @\\n ░░░ @\\n █████@\\n ░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ███ ░███ @\\n░░██████ @\\n ░░░░░░ @@\\n █████ @\\n░░███ @\\n ░███ █████@\\n ░███░░███ @\\n ░██████░ @\\n ░███░░███ @\\n ████ █████@\\n░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ████ @\\n░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n █████@\\n░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████████████ @\\n░░███░░███░░███ @\\n ░███ ░███ ░███ @\\n ░███ ░███ ░███ @\\n █████░███ █████@\\n░░░░░ ░░░ ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ████████ @\\n░░███░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ████ █████@\\n░░░░ ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ██████ @\\n ███░░███@\\n░███ ░███@\\n░███ ░███@\\n░░██████ @\\n ░░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ████████ @\\n░░███░░███@\\n ░███ ░███@\\n ░███ ░███@\\n ░███████ @\\n ░███░░░ @\\n ░███ @\\n █████ @\\n░░░░░ @@\\n @\\n @\\n ████████@\\n ███░░███ @\\n░███ ░███ @\\n░███ ░███ @\\n░░███████ @\\n ░░░░░███ @\\n ░███ @\\n █████@\\n ░░░░░ @@\\n @\\n @\\n ████████ @\\n░░███░░███@\\n ░███ ░░░ @\\n ░███ @\\n █████ @\\n░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ @\\n ███░░ @\\n░░█████ @\\n ░░░░███@\\n ██████ @\\n░░░░░░ @\\n @\\n @\\n @@\\n █████ @\\n ░░███ @\\n ███████ @\\n░░░███░ @\\n ░███ @\\n ░███ ███@\\n ░░█████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ ████@\\n░░███ ░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░████████@\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░░███ ███ @\\n ░░█████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ ███ █████@\\n░░███ ░███░░███ @\\n ░███ ░███ ░███ @\\n ░░███████████ @\\n ░░████░████ @\\n ░░░░ ░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ █████@\\n░░███ ░░███ @\\n ░░░█████░ @\\n ███░░░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ ████@\\n░░███ ░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░███████ @\\n ░░░░░███ @\\n ███ ░███ @\\n ░░██████ @\\n ░░░░░░ @@\\n @\\n @\\n █████████@\\n ░█░░░░███ @\\n ░ ███░ @\\n ███░ █@\\n █████████@\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n ███@\\n ██░ @\\n ██ @\\n ███ @\\n░░░██ @\\n ░░██ @\\n ░░███@\\n ░░░ @\\n @\\n @\\n @@\\n ███@\\n░███@\\n░███@\\n░███@\\n░███@\\n░███@\\n░███@\\n░░░ @\\n @\\n @\\n @@\\n ███ @\\n░░░██ @\\n ░░██ @\\n ░░███@\\n ██░ @\\n ██ @\\n ███ @\\n░░░ @\\n @\\n @\\n @@\\n @\\n ███ ███@\\n ███░███░ @\\n░░░ ░░░ @\\n @\\n @\\n @\\n @\\n @\\n @\\n @@\\n ███ ███ @\\n ░░░ ░░░ @\\n ███████ @\\n ███░░░███ @\\n ░█████████ @\\n ░███░░░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ███ ███ @\\n░░░ ░░░ @\\n ███████ @\\n ███░░░███@\\n░███ ░███@\\n░███ ░███@\\n░░███████ @\\n ░░░░░░░ @\\n @\\n @\\n @@\\n ███ ███ @\\n ░░░ ░░░ @\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░███████ @\\n ░░░░░░░ @\\n @\\n @\\n @@\\n ███ ███ @\\n░░░ ░░░ @\\n ██████ @\\n ░░░░░███ @\\n ███████ @\\n ███░░███ @\\n░░████████@\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n ███ ███ @\\n░░░ ░░░ @\\n ███████ @\\n ███░░░███@\\n░███ ░███@\\n░███ ░███@\\n░░███████ @\\n ░░░░░░░ @\\n @\\n @\\n @@\\n ███ ███ @\\n ░░░ ░░░ @\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░█████████@\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░███@\\n ░███ ░███@\\n ░██████████ @\\n ░███░░░░░███@\\n ░███ ░███@\\n ████ ██████ @\\n░░░░ ░░░░░░ @\\n @\\n @\\n @@\\n\"\n\n","import { dosrebelFont } from \"./fonts/dosrebel-data\"\n\nexport { dosrebelFont }\n\nexport const asciiFonts = {\n dosrebel: dosrebelFont,\n} as const\n\nexport type AsciiFontName = keyof typeof asciiFonts\n\nexport function getAsciiFont(name: AsciiFontName): string {\n return asciiFonts[name]\n}\n","export interface FigletFont {\n height: number\n baseline: number\n hardblank: string\n chars: Map<number, string[]>\n}\n\nexport function parseFigletFont(raw: string): FigletFont {\n const lines = raw.split(\"\\n\")\n\n if (lines[0]?.charCodeAt(0) === 0xfeff) {\n lines[0] = lines[0].slice(1)\n }\n\n const header = lines[0]\n if (!header?.startsWith(\"flf2a\")) {\n throw new Error(\"Invalid FIGlet font: missing flf2a header\")\n }\n\n const hardblank = header[5] ?? \"$\"\n const parts = header.slice(6).trim().split(/\\s+/)\n const height = Number.parseInt(parts[0] ?? \"\", 10)\n const baseline = Number.parseInt(parts[1] ?? \"\", 10)\n const commentLines = Number.parseInt(parts[4] ?? \"\", 10)\n\n if (!Number.isFinite(height) || height <= 0) {\n throw new Error(\"Invalid FIGlet font: missing character height\")\n }\n\n const dataStart = 1 + (Number.isFinite(commentLines) ? commentLines : 0)\n const chars = new Map<number, string[]>()\n let lineIndex = dataStart\n let ascii = 32\n\n while (lineIndex + height <= lines.length && ascii <= 126) {\n const charLines: string[] = []\n for (let row = 0; row < height; row++) {\n const line = (lines[lineIndex + row] ?? \"\")\n .replace(/@+$/, \"\")\n .replaceAll(hardblank, \" \")\n charLines.push(line)\n }\n\n chars.set(ascii, charLines)\n lineIndex += height\n ascii++\n }\n\n return { height, baseline, hardblank, chars }\n}\n","import { composeAsciiText } from \"./ascii/compose\"\nimport { dosrebelFont } from \"./ascii/fonts\"\nimport { parseFigletFont } from \"./ascii/figlet\"\n\nlet renderCache = new Map<string, string[]>()\n\nexport async function renderDosRebel(text: string): Promise<string[]> {\n const cached = renderCache.get(text)\n if (cached) return cached\n\n const font = parseFigletFont(dosrebelFont)\n const layout = composeAsciiText(font, text)\n const output = Array.from({ length: layout.rows }, () => \"\")\n const cellByPosition = new Map(layout.cells.map((cell) => [`${cell.row}:${cell.col}`, cell.ch]))\n\n for (let row = 0; row < layout.rows; row++) {\n let line = \"\"\n for (let col = 0; col < layout.cols; col++) {\n line += cellByPosition.get(`${row}:${col}`) ?? \" \"\n }\n output[row] = line.replace(/\\s+$/g, \"\")\n }\n\n renderCache.set(text, output)\n return output\n}\n","const RESET = \"\\x1b[0m\"\nconst DEFAULT_HEX = \"#22D3EE\"\nconst WHITE_HEX = \"#ffffff\"\nconst shownBannerKeys = new Set<string>()\n\nexport type BannerSegment = {\n text: string\n colorHex?: string\n}\n\ntype BannerOptions = {\n segments: BannerSegment[]\n compactSegments?: BannerSegment[]\n rowColors?: string[]\n rowShadeColor?: string\n}\n\ntype LegacyBannerOptions = {\n baseText: string\n suffix?: string\n colorHex?: string\n baseColorHex?: string\n}\n\ntype DevPlugin = {\n name: string\n apply: \"serve\"\n configureServer: (server: unknown) => void\n}\n\n\nexport function hexToAnsi24(hex: string) {\n const normalized = hex.trim().replace(/^#/, \"\")\n if (!/^[0-9a-fA-F]{6}$/.test(normalized)) {\n return null\n }\n const r = parseInt(normalized.slice(0, 2), 16)\n const g = parseInt(normalized.slice(2, 4), 16)\n const b = parseInt(normalized.slice(4, 6), 16)\n return `\\x1b[38;2;${r};${g};${b}m`\n}\n\nfunction visibleLen(value: string) {\n return value.length\n}\n\nfunction normalizeSegments(\n input: string | BannerOptions | LegacyBannerOptions\n): { segments: BannerSegment[]; compactSegments?: BannerSegment[]; rowColors?: string[]; rowShadeColor?: string } {\n if (typeof input === \"string\") {\n return { segments: [{ text: input, colorHex: WHITE_HEX }] }\n }\n\n if (\"segments\" in input) {\n const normalize = (segments: BannerSegment[]) =>\n segments\n .filter((segment) => segment.text.trim().length > 0)\n .map((segment) => ({\n text: segment.text,\n colorHex: segment.colorHex ?? WHITE_HEX,\n }))\n const segments = normalize(input.segments)\n const compactSegments =\n input.compactSegments && input.compactSegments.length > 0\n ? normalize(input.compactSegments)\n : undefined\n return { segments, compactSegments, rowColors: input.rowColors, rowShadeColor: input.rowShadeColor }\n }\n\n const suffix = input.suffix ?? \"\"\n if (!suffix) {\n return {\n segments: [{ text: input.baseText, colorHex: input.colorHex ?? DEFAULT_HEX }],\n }\n }\n\n return {\n segments: [\n { text: input.baseText, colorHex: input.baseColorHex ?? WHITE_HEX },\n { text: suffix, colorHex: input.colorHex ?? DEFAULT_HEX },\n ],\n }\n}\n\nasync function renderSegmentedFiglet(segments: BannerSegment[]) {\n const { renderDosRebel } = await import(\"./dos-rebel-font\")\n const cumulativeTexts: string[] = []\n let textSoFar = \"\"\n for (const segment of segments) {\n textSoFar += segment.text\n cumulativeTexts.push(textSoFar)\n }\n\n const renderedByBoundary = await Promise.all(\n cumulativeTexts.map((text) => renderDosRebel(text))\n )\n const lines = renderedByBoundary[renderedByBoundary.length - 1] ?? []\n const boundaryLines = renderedByBoundary.slice(0, -1)\n const ansiBySegment = segments.map(\n (segment) => hexToAnsi24(segment.colorHex ?? WHITE_HEX) ?? \"\\x1b[97m\"\n )\n const widestLine = lines.reduce((max, line) => Math.max(max, visibleLen(line)), 0)\n\n return { lines, boundaryLines, ansiBySegment, widestLine }\n}\n\nfunction printRowColoredFiglet(lines: string[], rowColors: string[], rowShadeColor?: string) {\n for (let i = 0; i < lines.length; i++) {\n const hex = rowColors[i % rowColors.length] ?? WHITE_HEX\n const fgAnsi = hexToAnsi24(hex) ?? \"\\x1b[97m\"\n const shadeAnsi = rowShadeColor ? (hexToAnsi24(rowShadeColor) ?? fgAnsi) : fgAnsi\n const line = lines[i] ?? \"\"\n let out = \"\"\n for (const char of line) {\n if (char === \" \") {\n out += `${RESET} `\n } else if (char === \"░\") {\n out += `${shadeAnsi}${char}`\n } else {\n out += `${fgAnsi}${char}`\n }\n }\n process.stdout.write(`${out}${RESET}\\n`)\n }\n}\n\nfunction printColoredFiglet(\n lines: string[],\n boundaryLines: string[][],\n ansiBySegment: string[]\n) {\n for (let i = 0; i < lines.length; i++) {\n const full = lines[i] ?? \"\"\n let cursor = 0\n let out = \"\"\n\n for (let segmentIndex = 0; segmentIndex < ansiBySegment.length; segmentIndex += 1) {\n const boundaryLine =\n segmentIndex < boundaryLines.length ? boundaryLines[segmentIndex]?.[i] ?? \"\" : full\n const end = Math.min(boundaryLine.length, full.length)\n const chunk = full.slice(cursor, end)\n out += `${ansiBySegment[segmentIndex]}${chunk}`\n cursor = end\n }\n\n process.stdout.write(`${out}${RESET}\\n`)\n }\n}\n\nexport async function printBanner(input: string | BannerSegment[] | BannerOptions) {\n const normalized = Array.isArray(input)\n ? { segments: input, compactSegments: undefined, rowColors: undefined }\n : normalizeSegments(input)\n const segments = normalized.segments\n const compactSegments = normalized.compactSegments\n const rowColors = normalized.rowColors\n const rowShadeColor = normalized.rowShadeColor\n if (!segments.length) return\n\n process.stdout.write(`${RESET}\\n`)\n const terminalColumns = process.stdout.columns ?? 0\n const primary = await renderSegmentedFiglet(segments)\n\n if (terminalColumns === 0 || primary.widestLine <= terminalColumns) {\n if (rowColors && rowColors.length > 0) {\n printRowColoredFiglet(primary.lines, rowColors, rowShadeColor)\n } else {\n printColoredFiglet(primary.lines, primary.boundaryLines, primary.ansiBySegment)\n }\n return\n }\n\n if (compactSegments && compactSegments.length > 0) {\n const compactFiglet = await renderSegmentedFiglet(compactSegments)\n if (compactFiglet.widestLine <= terminalColumns) {\n printColoredFiglet(\n compactFiglet.lines,\n compactFiglet.boundaryLines,\n compactFiglet.ansiBySegment\n )\n return\n }\n }\n\n let plain = \"\"\n for (let i = 0; i < segments.length; i++) {\n const text = segments[i]?.text ?? \"\"\n if (!text) continue\n plain += `${primary.ansiBySegment[i]}${text}`\n }\n process.stdout.write(`${plain}${RESET}\\n`)\n}\n\nexport function createTsupBannerHook(\n project: string | BannerOptions | LegacyBannerOptions\n): () => Promise<void> {\n let shown = false\n const normalized = normalizeSegments(project)\n const bannerKey = JSON.stringify(normalized)\n return async () => {\n if (shown) return\n if (shownBannerKeys.has(bannerKey)) return\n shown = true\n shownBannerKeys.add(bannerKey)\n await printBanner(normalized)\n }\n}\n\nexport function createDevBannerPlugin(\n project: string | BannerOptions | LegacyBannerOptions\n): DevPlugin {\n let shown = false\n const { segments, compactSegments, rowColors, rowShadeColor } = normalizeSegments(project)\n const bannerText = segments.map((segment) => segment.text).join(\"\")\n return {\n name: `olwiba-dev-banner-${bannerText.toLowerCase()}`,\n apply: \"serve\",\n configureServer(_server: unknown) {\n if (shown) return\n shown = true\n void printBanner({ segments, compactSegments, rowColors, rowShadeColor })\n },\n }\n}\n","import { createServer } from \"node:net\"\n\n/**\n * Probe for the first free port from `start` up. Vite's own auto-increment\n * doesn't kick in reliably under the TanStack Start plugin, so dev servers\n * resolve the port themselves before passing it to `server.port`.\n */\n/** True when `port` can be bound right now. */\nasync function isFree(port: number): Promise<boolean> {\n return new Promise<boolean>((resolve) => {\n const probe = createServer()\n .once(\"error\", () => resolve(false))\n .once(\"listening\", () => probe.close(() => resolve(true)))\n probe.listen(port)\n })\n}\n\nexport async function findFreePort(start: number, attempts = 20): Promise<number> {\n for (let port = start; port < start + attempts; port++) {\n if (await isFree(port)) return port\n }\n throw new Error(`No free port found in range ${start}-${start + attempts - 1}`)\n}\n\n/**\n * Resolve the dev server port, or fail.\n *\n * Deliberately does **not** fall back to the next free port. Silently moving to\n * 3001 looks like it worked and then breaks something unrelated several minutes\n * later: `BETTER_AUTH_TRUSTED_ORIGINS` pins an origin, so the app boots fine and\n * every sign-in fails with \"Invalid origin\" — a message that points at auth\n * config rather than at the port that actually moved.\n *\n * Running a second app at the same time is still supported, but has to be said\n * out loud: `PORT=3001 bun run dev`.\n */\nexport async function resolveDevPort(preferred: number): Promise<number> {\n if (await isFree(preferred)) return preferred\n\n throw new Error(\n `Port ${preferred} is already in use.\\n\\n` +\n ` Free it, or start this app on another port explicitly:\\n` +\n ` PORT=${preferred + 1} bun run dev\\n\\n` +\n ` If you pick another port, add its origin to BETTER_AUTH_TRUSTED_ORIGINS\\n` +\n ` or sign-in will fail with \"Invalid origin\".`,\n )\n}\n","import {\n createDevBannerPlugin,\n createTsupBannerHook,\n type BannerSegment,\n} from \"./dev-banner\"\n\nexport type ProjectBrandAccent = {\n hex: string\n lightOklch?: string\n darkOklch?: string\n}\n\nexport type ProjectBannerSegment = {\n text: string\n accent?: boolean\n colorHex?: string\n}\n\nexport type ProjectConfig = {\n id: string\n label: string\n brandAccent: ProjectBrandAccent\n banner: {\n segments: readonly ProjectBannerSegment[]\n compactSegments?: readonly ProjectBannerSegment[]\n }\n}\n\nfunction resolveProjectBannerSegments(\n segments: readonly ProjectBannerSegment[],\n accentHex: string\n): BannerSegment[] {\n return segments.map((segment) => ({\n text: segment.text,\n colorHex: segment.accent ? accentHex : segment.colorHex,\n }))\n}\n\nfunction getProjectBanner(project: ProjectConfig) {\n return {\n segments: resolveProjectBannerSegments(project.banner.segments, project.brandAccent.hex),\n compactSegments: project.banner.compactSegments\n ? resolveProjectBannerSegments(project.banner.compactSegments, project.brandAccent.hex)\n : undefined,\n }\n}\n\nexport function createProjectDevBannerPlugin(project: ProjectConfig) {\n return createDevBannerPlugin(getProjectBanner(project))\n}\n\nexport function createProjectTsupBannerHook(project: ProjectConfig) {\n return createTsupBannerHook(getProjectBanner(project))\n}\n"]}
1
+ {"version":3,"sources":["../src/ascii/compose.ts","../src/ascii/fonts/dosrebel-data.ts","../src/ascii/fonts.ts","../src/ascii/figlet.ts","../src/dos-rebel-font.ts","../src/dev-banner.ts","../src/find-free-port.ts","../src/project-brand.ts"],"names":["segments","renderDosRebel"],"mappings":"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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,EAAA;AAAA,CAAA,CAA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","file":"index.js","sourcesContent":["import type { FigletFont } from \"./figlet\"\n\nexport interface AsciiCell {\n ch: \"█\" | \"░\"\n col: number\n row: number\n}\n\nexport interface AsciiTextLayout {\n cells: AsciiCell[]\n cols: number\n rows: number\n}\n\nexport function composeAsciiText(font: FigletFont, text: string): AsciiTextLayout {\n const charBlocks: Array<{ lines: string[]; width: number }> = []\n\n for (const ch of text) {\n const code = ch.charCodeAt(0)\n const glyph = font.chars.get(code) ?? font.chars.get(32)\n if (!glyph) continue\n\n const width = Math.max(...glyph.map((line) => line.length))\n charBlocks.push({\n lines: glyph.map((line) => line.padEnd(width)),\n width,\n })\n }\n\n const cols = charBlocks.reduce((sum, block) => sum + block.width, 0)\n const rows = font.height\n const cells: AsciiCell[] = []\n let offsetX = 0\n\n for (const block of charBlocks) {\n for (let row = 0; row < rows; row++) {\n const line = block.lines[row] ?? \"\"\n for (let col = 0; col < line.length; col++) {\n const ch = line[col]\n if (ch === \"█\" || ch === \"░\") {\n cells.push({ ch, col: offsetX + col, row })\n }\n }\n }\n offsetX += block.width\n }\n\n return { cells, cols, rows }\n}\n\nexport function getAsciiAccentColumns(\n font: FigletFont,\n text: string,\n accent: string,\n): Set<number> {\n if (!accent) return new Set<number>()\n\n const columns = new Set<number>()\n const accentRanges: Array<{ start: number; end: number }> = []\n let searchFrom = 0\n while (true) {\n const idx = text.indexOf(accent, searchFrom)\n if (idx === -1) break\n accentRanges.push({ start: idx, end: idx + accent.length })\n searchFrom = idx + 1\n }\n if (accentRanges.length === 0) return columns\n\n let offsetX = 0\n let charIndex = 0\n\n for (const ch of text) {\n const code = ch.charCodeAt(0)\n const glyph = font.chars.get(code) ?? font.chars.get(32)\n if (!glyph) { charIndex++; continue }\n\n const width = Math.max(...glyph.map((line) => line.length))\n if (accentRanges.some((r) => charIndex >= r.start && charIndex < r.end)) {\n for (let col = 0; col < width; col++) columns.add(offsetX + col)\n }\n offsetX += width\n charIndex++\n }\n\n return columns\n}\n","// @generated from dosrebel.flf. Do not edit by hand.\nexport const dosrebelFont: string = \"flf2a$ 11 8 35 -1 15\\nRebel by Valerie Mates (popcorn@cyberspace.org), based on a font by Ron Bliss\\n(who sometimes goes by the name \\\"rebel\\\" because his initials are REB).\\nNOTE: THIS FONT ONLY WORKS IN MS-DOS.\\nMay 27, 1994\\n\\nExplanation of first line:\\nflf2 - \\\"magic number\\\" for file identification\\na - should always be `a', for now\\n$ - the \\\"hardblank\\\" -- prints as a blank, but can't be smushed\\n11 - height of a character\\n8 - height of a character, not including descenders\\n35 - max line length (excluding comment lines) + a fudge factor\\n-1 - default smushmode for this font (like \\\"-m 15\\\" on command line)\\n15 - number of comment lines\\n\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@\\n$$$@@\\n ███@\\n░███@\\n░███@\\n░███@\\n░███@\\n░░░ @\\n ███@\\n░░░ @\\n @\\n @\\n @@\\n ██ ██@\\n░██░██@\\n░░ ░░ @\\n @\\n @\\n @\\n @\\n @\\n @\\n @\\n @@\\n ███ ███ @\\n ████████████@\\n░░░███░░███░ @\\n ████████████@\\n░░░███░░███░ @\\n ░░░ ░░░ @\\n @\\n @\\n @\\n @\\n @@\\n ███ @\\n ██████ @\\n ███░░░ @\\n ░░█████ @\\n ░░░░███ @\\n ██████ @\\n ░░░███ @\\n ░░░ @\\n @\\n @\\n @@\\n ███ ███@\\n ░░░ ███░ @\\n ███░ @\\n ███░ @\\n ███░ @\\n ███░ @\\n ███░ ███ @\\n░░░ ░░░ @\\n @\\n @\\n @@\\n ██████ @\\n ███░░███ @\\n ░░██████ @\\n ██████ @\\n░███░░███ @\\n░███ ░░███ @\\n░░█████░███@\\n ░░░░░ ░░░ @\\n @\\n @\\n @@\\n ██@\\n ███@\\n░░░ @\\n @\\n @\\n @\\n @\\n @\\n @\\n @\\n @@\\n ███@\\n ███ @\\n ███ @\\n░███ @\\n░███ @\\n░░███ @\\n ░░███@\\n ░░░ @\\n @\\n @\\n @@\\n ███ @\\n░░███ @\\n ░░███@\\n ░███@\\n ░███@\\n ███ @\\n ██░ @\\n░░░ @\\n @\\n @\\n @@\\n ███ @\\n ███ ░███ ███@\\n░░░█████████░ @\\n ░░░█████░ @\\n █████████ @\\n ███░░███░░███@\\n░░░ ░███ ░░░ @\\n ░░░ @\\n @\\n @\\n @@\\n @\\n ███ @\\n ░███ @\\n ███████████@\\n░░░░░███░░░ @\\n ░███ @\\n ░░░ @\\n @\\n @\\n @\\n @@\\n @\\n @\\n @\\n @\\n @\\n @\\n ██@\\n ██ @\\n░░ @\\n @\\n @@\\n @\\n @\\n @\\n ██████████@\\n░░░░░░░░░░ @\\n @\\n @\\n @\\n @\\n @\\n @@\\n @\\n @\\n @\\n @\\n @\\n @\\n ██@\\n░░ @\\n @\\n @\\n @@\\n ███@\\n ███░ @\\n ███░ @\\n ███░ @\\n ███░ @\\n ███░ @\\n ███░ @\\n░░░ @\\n @\\n @\\n @@\\n █████ @\\n ███░░░███ @\\n ███ ░░███@\\n░███ ░███@\\n░███ ░███@\\n░░███ ███ @\\n ░░░█████░ @\\n ░░░░░░ @\\n @\\n @\\n @@\\n ████ @\\n░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n █████@\\n░░░░░ @\\n @\\n @\\n @@\\n ████████ @\\n ███░░░░███@\\n░░░ ░███@\\n ███████ @\\n ███░░░░ @\\n ███ █@\\n░██████████@\\n░░░░░░░░░░ @\\n @\\n @\\n @@\\n ████████ @\\n ███░░░░███@\\n░░░ ░███@\\n ██████░ @\\n ░░░░░░███@\\n ███ ░███@\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n █████ █████ @\\n░░███ ░░███ @\\n ░███ ░███ █@\\n ░███████████@\\n ░░░░░░░███░█@\\n ░███░ @\\n █████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n ██████████@\\n░███░░░░░░█@\\n░███ ░ @\\n░█████████ @\\n░░░░░░░░███@\\n ███ ░███@\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n ████████ @\\n ███░░░░███@\\n░███ ░░░ @\\n░█████████ @\\n░███░░░░███@\\n░███ ░███@\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n ██████████@\\n░███░░░░███@\\n░░░ ███ @\\n ███ @\\n ███ @\\n ███ @\\n ███ @\\n ░░░ @\\n @\\n @\\n @@\\n ████████ @\\n ███░░░░███ @\\n░███ ░███ @\\n░░████████ @\\n ███░░░░███ @\\n░███ ░███ @\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n ████████ @\\n ███░░░░███@\\n░███ ░███@\\n░░█████████@\\n ░░░░░░░███@\\n ███ ░███@\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ██@\\n░░ @\\n @\\n @\\n ██@\\n░░ @\\n @\\n @\\n @@\\n @\\n @\\n @\\n @\\n ██@\\n ░░ @\\n ██@\\n ██ @\\n░░ @\\n @\\n @@\\n ███@\\n ███░ @\\n ███░ @\\n ███░ @\\n░░░███ @\\n ░░░███ @\\n ░░░███@\\n ░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████████@\\n░░░░░░░░░ @\\n █████████@\\n░░░░░░░░░ @\\n @\\n @\\n @\\n @\\n @@\\n ███ @\\n░░░███ @\\n ░░░███ @\\n ░░░███@\\n ███░ @\\n ███░ @\\n ███░ @\\n░░░ @\\n @\\n @\\n @@\\n ███████ @\\n ███░░░███@\\n░░░ ░███@\\n ███████ @\\n ░███░░░ @\\n ░░░ @\\n ███ @\\n ░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░░ @\\n░███ ██████ @\\n░███░███░███@\\n░███░███░███@\\n░███░░░ ░███@\\n░░█████████ @\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░███ @\\n ░███ ░███ @\\n ░███████████ @\\n ░███░░░░░███ @\\n ░███ ░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ███████████ @\\n░░███░░░░░███@\\n ░███ ░███@\\n ░██████████ @\\n ░███░░░░░███@\\n ░███ ░███@\\n ███████████ @\\n░░░░░░░░░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░███@\\n ███ ░░░ @\\n░███ @\\n░███ @\\n░░███ ███@\\n ░░█████████ @\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n ██████████ @\\n░░███░░░░███ @\\n ░███ ░░███@\\n ░███ ░███@\\n ░███ ░███@\\n ░███ ███ @\\n ██████████ @\\n░░░░░░░░░░ @\\n @\\n @\\n @@\\n ██████████@\\n░░███░░░░░█@\\n ░███ █ ░ @\\n ░██████ @\\n ░███░░█ @\\n ░███ ░ █@\\n ██████████@\\n░░░░░░░░░░ @\\n @\\n @\\n @@\\n ███████████@\\n░░███░░░░░░█@\\n ░███ █ ░ @\\n ░███████ @\\n ░███░░░█ @\\n ░███ ░ @\\n █████ @\\n░░░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░███@\\n ███ ░░░ @\\n░███ @\\n░███ █████@\\n░░███ ░░███ @\\n ░░█████████ @\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░███████████ @\\n ░███░░░░░███ @\\n ░███ ░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n █████@\\n░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n █████@\\n░░░░░ @\\n @\\n @\\n @@\\n █████@\\n ░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ███ ░███ @\\n░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n █████ ████@\\n░░███ ███░ @\\n ░███ ███ @\\n ░███████ @\\n ░███░░███ @\\n ░███ ░░███ @\\n █████ ░░████@\\n░░░░░ ░░░░ @\\n @\\n @\\n @@\\n █████ @\\n░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ░███ █@\\n ███████████@\\n░░░░░░░░░░░ @\\n @\\n @\\n @@\\n ██████ ██████@\\n░░██████ ██████ @\\n ░███░█████░███ @\\n ░███░░███ ░███ @\\n ░███ ░░░ ░███ @\\n ░███ ░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ██████ █████@\\n░░██████ ░░███ @\\n ░███░███ ░███ @\\n ░███░░███░███ @\\n ░███ ░░██████ @\\n ░███ ░░█████ @\\n █████ ░░█████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ███████ @\\n ███░░░░░███ @\\n ███ ░░███@\\n░███ ░███@\\n░███ ░███@\\n░░███ ███ @\\n ░░░███████░ @\\n ░░░░░░░ @\\n @\\n @\\n @@\\n ███████████ @\\n░░███░░░░░███@\\n ░███ ░███@\\n ░██████████ @\\n ░███░░░░░░ @\\n ░███ @\\n █████ @\\n░░░░░ @\\n @\\n @\\n @@\\n ██████ @\\n ███░░░░███ @\\n ███ ░░███@\\n░███ ░███@\\n░███ ██░███@\\n░░███ ░░████ @\\n ░░░██████░██@\\n ░░░░░░ ░░ @\\n @\\n @\\n @@\\n ███████████ @\\n░░███░░░░░███ @\\n ░███ ░███ @\\n ░██████████ @\\n ░███░░░░░███ @\\n ░███ ░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░███@\\n░███ ░░░ @\\n░░█████████ @\\n ░░░░░░░░███@\\n ███ ░███@\\n░░█████████ @\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n ███████████@\\n░█░░░███░░░█@\\n░ ░███ ░ @\\n ░███ @\\n ░███ @\\n ░███ @\\n █████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░████████ @\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░███ ███ @\\n ░░░█████░ @\\n ░░███ @\\n ░░░ @\\n @\\n @\\n @@\\n █████ ███ █████@\\n░░███ ░███ ░░███ @\\n ░███ ░███ ░███ @\\n ░███ ░███ ░███ @\\n ░░███ █████ ███ @\\n ░░░█████░█████░ @\\n ░░███ ░░███ @\\n ░░░ ░░░ @\\n @\\n @\\n @@\\n █████ █████@\\n░░███ ░░███ @\\n ░░███ ███ @\\n ░░█████ @\\n ███░███ @\\n ███ ░░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n █████ █████@\\n░░███ ░░███ @\\n ░░███ ███ @\\n ░░█████ @\\n ░░███ @\\n ░███ @\\n █████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n ███████████@\\n░█░░░░░░███ @\\n░ ███░ @\\n ███ @\\n ███ @\\n ████ █@\\n ███████████@\\n░░░░░░░░░░░ @\\n @\\n @\\n @@\\n █████@\\n░███░ @\\n░███ @\\n░███ @\\n░███ @\\n░███ @\\n░█████@\\n░░░░░ @\\n @\\n @\\n @@\\n ███ @\\n░░███ @\\n ░░███ @\\n ░░███ @\\n ░░███ @\\n ░░███ @\\n ░░███@\\n ░░░ @\\n @\\n @\\n @@\\n █████@\\n░░░███@\\n ░███@\\n ░███@\\n ░███@\\n ░███@\\n █████@\\n░░░░░ @\\n @\\n @\\n @@\\n ██ @\\n ████ @\\n ██░░██@\\n░░ ░░ @\\n @\\n @\\n @\\n @\\n @\\n @\\n @@\\n @\\n @\\n @\\n @\\n @\\n @\\n █████████@\\n░░░░░░░░░ @\\n @\\n @\\n @@\\n ██ @\\n░███@\\n░░░ @\\n @\\n @\\n @\\n @\\n @\\n @\\n @\\n @@\\n @\\n @\\n ██████ @\\n ░░░░░███ @\\n ███████ @\\n ███░░███ @\\n░░████████@\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n █████ @\\n░░███ @\\n ░███████ @\\n ░███░░███@\\n ░███ ░███@\\n ░███ ░███@\\n ████████ @\\n░░░░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ██████ @\\n ███░░███@\\n░███ ░░░ @\\n░███ ███@\\n░░██████ @\\n ░░░░░░ @\\n @\\n @\\n @@\\n █████@\\n ░░███ @\\n ███████ @\\n ███░░███ @\\n░███ ░███ @\\n░███ ░███ @\\n░░████████@\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ██████ @\\n ███░░███@\\n░███████ @\\n░███░░░ @\\n░░██████ @\\n ░░░░░░ @\\n @\\n @\\n @@\\n ██████ @\\n ███░░███@\\n ░███ ░░░ @\\n ███████ @\\n░░░███░ @\\n ░███ @\\n █████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ███████@\\n ███░░███@\\n░███ ░███@\\n░███ ░███@\\n░░███████@\\n ░░░░░███@\\n ███ ░███@\\n░░██████ @\\n ░░░░░░ @@\\n █████ @\\n░░███ @\\n ░███████ @\\n ░███░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ████ █████@\\n░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ███ @\\n ░░░ @\\n ████ @\\n░░███ @\\n ░███ @\\n ░███ @\\n █████@\\n░░░░░ @\\n @\\n @\\n @@\\n ███ @\\n ░░░ @\\n █████@\\n ░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ███ ░███ @\\n░░██████ @\\n ░░░░░░ @@\\n █████ @\\n░░███ @\\n ░███ █████@\\n ░███░░███ @\\n ░██████░ @\\n ░███░░███ @\\n ████ █████@\\n░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ████ @\\n░░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n ░███ @\\n █████@\\n░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████████████ @\\n░░███░░███░░███ @\\n ░███ ░███ ░███ @\\n ░███ ░███ ░███ @\\n █████░███ █████@\\n░░░░░ ░░░ ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ████████ @\\n░░███░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ████ █████@\\n░░░░ ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ██████ @\\n ███░░███@\\n░███ ░███@\\n░███ ░███@\\n░░██████ @\\n ░░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n ████████ @\\n░░███░░███@\\n ░███ ░███@\\n ░███ ░███@\\n ░███████ @\\n ░███░░░ @\\n ░███ @\\n █████ @\\n░░░░░ @@\\n @\\n @\\n ████████@\\n ███░░███ @\\n░███ ░███ @\\n░███ ░███ @\\n░░███████ @\\n ░░░░░███ @\\n ░███ @\\n █████@\\n ░░░░░ @@\\n @\\n @\\n ████████ @\\n░░███░░███@\\n ░███ ░░░ @\\n ░███ @\\n █████ @\\n░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ @\\n ███░░ @\\n░░█████ @\\n ░░░░███@\\n ██████ @\\n░░░░░░ @\\n @\\n @\\n @@\\n █████ @\\n ░░███ @\\n ███████ @\\n░░░███░ @\\n ░███ @\\n ░███ ███@\\n ░░█████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ ████@\\n░░███ ░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░████████@\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░░███ ███ @\\n ░░█████ @\\n ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ ███ █████@\\n░░███ ░███░░███ @\\n ░███ ░███ ░███ @\\n ░░███████████ @\\n ░░████░████ @\\n ░░░░ ░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ █████@\\n░░███ ░░███ @\\n ░░░█████░ @\\n ███░░░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n @\\n @\\n █████ ████@\\n░░███ ░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░███████ @\\n ░░░░░███ @\\n ███ ░███ @\\n ░░██████ @\\n ░░░░░░ @@\\n @\\n @\\n █████████@\\n ░█░░░░███ @\\n ░ ███░ @\\n ███░ █@\\n █████████@\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n ███@\\n ██░ @\\n ██ @\\n ███ @\\n░░░██ @\\n ░░██ @\\n ░░███@\\n ░░░ @\\n @\\n @\\n @@\\n ███@\\n░███@\\n░███@\\n░███@\\n░███@\\n░███@\\n░███@\\n░░░ @\\n @\\n @\\n @@\\n ███ @\\n░░░██ @\\n ░░██ @\\n ░░███@\\n ██░ @\\n ██ @\\n ███ @\\n░░░ @\\n @\\n @\\n @@\\n @\\n ███ ███@\\n ███░███░ @\\n░░░ ░░░ @\\n @\\n @\\n @\\n @\\n @\\n @\\n @@\\n ███ ███ @\\n ░░░ ░░░ @\\n ███████ @\\n ███░░░███ @\\n ░█████████ @\\n ░███░░░███ @\\n █████ █████@\\n░░░░░ ░░░░░ @\\n @\\n @\\n @@\\n ███ ███ @\\n░░░ ░░░ @\\n ███████ @\\n ███░░░███@\\n░███ ░███@\\n░███ ░███@\\n░░███████ @\\n ░░░░░░░ @\\n @\\n @\\n @@\\n ███ ███ @\\n ░░░ ░░░ @\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░███████ @\\n ░░░░░░░ @\\n @\\n @\\n @@\\n ███ ███ @\\n░░░ ░░░ @\\n ██████ @\\n ░░░░░███ @\\n ███████ @\\n ███░░███ @\\n░░████████@\\n ░░░░░░░░ @\\n @\\n @\\n @@\\n ███ ███ @\\n░░░ ░░░ @\\n ███████ @\\n ███░░░███@\\n░███ ░███@\\n░███ ░███@\\n░░███████ @\\n ░░░░░░░ @\\n @\\n @\\n @@\\n ███ ███ @\\n ░░░ ░░░ @\\n █████ █████@\\n░░███ ░░███ @\\n ░███ ░███ @\\n ░███ ░███ @\\n ░░█████████@\\n ░░░░░░░░░ @\\n @\\n @\\n @@\\n █████████ @\\n ███░░░░░███@\\n ░███ ░███@\\n ░██████████ @\\n ░███░░░░░███@\\n ░███ ░███@\\n ████ ██████ @\\n░░░░ ░░░░░░ @\\n @\\n @\\n @@\\n\"\n\n","import { dosrebelFont } from \"./fonts/dosrebel-data\"\n\nexport { dosrebelFont }\n\nexport const asciiFonts = {\n dosrebel: dosrebelFont,\n} as const\n\nexport type AsciiFontName = keyof typeof asciiFonts\n\nexport function getAsciiFont(name: AsciiFontName): string {\n return asciiFonts[name]\n}\n","export interface FigletFont {\n height: number\n baseline: number\n hardblank: string\n chars: Map<number, string[]>\n}\n\nexport function parseFigletFont(raw: string): FigletFont {\n const lines = raw.split(\"\\n\")\n\n if (lines[0]?.charCodeAt(0) === 0xfeff) {\n lines[0] = lines[0].slice(1)\n }\n\n const header = lines[0]\n if (!header?.startsWith(\"flf2a\")) {\n throw new Error(\"Invalid FIGlet font: missing flf2a header\")\n }\n\n const hardblank = header[5] ?? \"$\"\n const parts = header.slice(6).trim().split(/\\s+/)\n const height = Number.parseInt(parts[0] ?? \"\", 10)\n const baseline = Number.parseInt(parts[1] ?? \"\", 10)\n const commentLines = Number.parseInt(parts[4] ?? \"\", 10)\n\n if (!Number.isFinite(height) || height <= 0) {\n throw new Error(\"Invalid FIGlet font: missing character height\")\n }\n\n const dataStart = 1 + (Number.isFinite(commentLines) ? commentLines : 0)\n const chars = new Map<number, string[]>()\n let lineIndex = dataStart\n let ascii = 32\n\n while (lineIndex + height <= lines.length && ascii <= 126) {\n const charLines: string[] = []\n for (let row = 0; row < height; row++) {\n const line = (lines[lineIndex + row] ?? \"\")\n .replace(/@+$/, \"\")\n .replaceAll(hardblank, \" \")\n charLines.push(line)\n }\n\n chars.set(ascii, charLines)\n lineIndex += height\n ascii++\n }\n\n return { height, baseline, hardblank, chars }\n}\n","import { composeAsciiText } from \"./ascii/compose\"\nimport { dosrebelFont } from \"./ascii/fonts\"\nimport { parseFigletFont } from \"./ascii/figlet\"\n\nlet renderCache = new Map<string, string[]>()\n\nexport async function renderDosRebel(text: string): Promise<string[]> {\n const cached = renderCache.get(text)\n if (cached) return cached\n\n const font = parseFigletFont(dosrebelFont)\n const layout = composeAsciiText(font, text)\n const output = Array.from({ length: layout.rows }, () => \"\")\n const cellByPosition = new Map(layout.cells.map((cell) => [`${cell.row}:${cell.col}`, cell.ch]))\n\n for (let row = 0; row < layout.rows; row++) {\n let line = \"\"\n for (let col = 0; col < layout.cols; col++) {\n line += cellByPosition.get(`${row}:${col}`) ?? \" \"\n }\n output[row] = line.replace(/\\s+$/g, \"\")\n }\n\n renderCache.set(text, output)\n return output\n}\n","const RESET = \"\\x1b[0m\"\nconst DEFAULT_HEX = \"#22D3EE\"\nconst WHITE_HEX = \"#ffffff\"\nconst shownBannerKeys = new Set<string>()\n\nexport type BannerSegment = {\n text: string\n colorHex?: string\n}\n\ntype BannerOptions = {\n segments: BannerSegment[]\n compactSegments?: BannerSegment[]\n rowColors?: string[]\n rowShadeColor?: string\n}\n\ntype LegacyBannerOptions = {\n baseText: string\n suffix?: string\n colorHex?: string\n baseColorHex?: string\n}\n\ntype DevPlugin = {\n name: string\n apply: \"serve\"\n configureServer: (server: unknown) => void\n}\n\n\nexport function hexToAnsi24(hex: string) {\n const normalized = hex.trim().replace(/^#/, \"\")\n if (!/^[0-9a-fA-F]{6}$/.test(normalized)) {\n return null\n }\n const r = parseInt(normalized.slice(0, 2), 16)\n const g = parseInt(normalized.slice(2, 4), 16)\n const b = parseInt(normalized.slice(4, 6), 16)\n return `\\x1b[38;2;${r};${g};${b}m`\n}\n\nfunction visibleLen(value: string) {\n return value.length\n}\n\nfunction normalizeSegments(\n input: string | BannerOptions | LegacyBannerOptions\n): { segments: BannerSegment[]; compactSegments?: BannerSegment[]; rowColors?: string[]; rowShadeColor?: string } {\n if (typeof input === \"string\") {\n return { segments: [{ text: input, colorHex: WHITE_HEX }] }\n }\n\n if (\"segments\" in input) {\n const normalize = (segments: BannerSegment[]) =>\n segments\n .filter((segment) => segment.text.trim().length > 0)\n .map((segment) => ({\n text: segment.text,\n colorHex: segment.colorHex ?? WHITE_HEX,\n }))\n const segments = normalize(input.segments)\n const compactSegments =\n input.compactSegments && input.compactSegments.length > 0\n ? normalize(input.compactSegments)\n : undefined\n return { segments, compactSegments, rowColors: input.rowColors, rowShadeColor: input.rowShadeColor }\n }\n\n const suffix = input.suffix ?? \"\"\n if (!suffix) {\n return {\n segments: [{ text: input.baseText, colorHex: input.colorHex ?? DEFAULT_HEX }],\n }\n }\n\n return {\n segments: [\n { text: input.baseText, colorHex: input.baseColorHex ?? WHITE_HEX },\n { text: suffix, colorHex: input.colorHex ?? DEFAULT_HEX },\n ],\n }\n}\n\nasync function renderSegmentedFiglet(segments: BannerSegment[]) {\n const { renderDosRebel } = await import(\"./dos-rebel-font\")\n const cumulativeTexts: string[] = []\n let textSoFar = \"\"\n for (const segment of segments) {\n textSoFar += segment.text\n cumulativeTexts.push(textSoFar)\n }\n\n const renderedByBoundary = await Promise.all(\n cumulativeTexts.map((text) => renderDosRebel(text))\n )\n const lines = renderedByBoundary[renderedByBoundary.length - 1] ?? []\n const boundaryLines = renderedByBoundary.slice(0, -1)\n const ansiBySegment = segments.map(\n (segment) => hexToAnsi24(segment.colorHex ?? WHITE_HEX) ?? \"\\x1b[97m\"\n )\n const widestLine = lines.reduce((max, line) => Math.max(max, visibleLen(line)), 0)\n\n return { lines, boundaryLines, ansiBySegment, widestLine }\n}\n\nfunction printRowColoredFiglet(lines: string[], rowColors: string[], rowShadeColor?: string) {\n for (let i = 0; i < lines.length; i++) {\n const hex = rowColors[i % rowColors.length] ?? WHITE_HEX\n const fgAnsi = hexToAnsi24(hex) ?? \"\\x1b[97m\"\n const shadeAnsi = rowShadeColor ? (hexToAnsi24(rowShadeColor) ?? fgAnsi) : fgAnsi\n const line = lines[i] ?? \"\"\n let out = \"\"\n for (const char of line) {\n if (char === \" \") {\n out += `${RESET} `\n } else if (char === \"░\") {\n out += `${shadeAnsi}${char}`\n } else {\n out += `${fgAnsi}${char}`\n }\n }\n process.stdout.write(`${out}${RESET}\\n`)\n }\n}\n\nfunction printColoredFiglet(\n lines: string[],\n boundaryLines: string[][],\n ansiBySegment: string[]\n) {\n for (let i = 0; i < lines.length; i++) {\n const full = lines[i] ?? \"\"\n let cursor = 0\n let out = \"\"\n\n for (let segmentIndex = 0; segmentIndex < ansiBySegment.length; segmentIndex += 1) {\n const boundaryLine =\n segmentIndex < boundaryLines.length ? boundaryLines[segmentIndex]?.[i] ?? \"\" : full\n const end = Math.min(boundaryLine.length, full.length)\n const chunk = full.slice(cursor, end)\n out += `${ansiBySegment[segmentIndex]}${chunk}`\n cursor = end\n }\n\n process.stdout.write(`${out}${RESET}\\n`)\n }\n}\n\nexport async function printBanner(input: string | BannerSegment[] | BannerOptions) {\n const normalized = Array.isArray(input)\n ? { segments: input, compactSegments: undefined, rowColors: undefined }\n : normalizeSegments(input)\n const segments = normalized.segments\n const compactSegments = normalized.compactSegments\n const rowColors = normalized.rowColors\n const rowShadeColor = normalized.rowShadeColor\n if (!segments.length) return\n\n process.stdout.write(`${RESET}\\n`)\n const terminalColumns = process.stdout.columns ?? 0\n const primary = await renderSegmentedFiglet(segments)\n\n if (terminalColumns === 0 || primary.widestLine <= terminalColumns) {\n if (rowColors && rowColors.length > 0) {\n printRowColoredFiglet(primary.lines, rowColors, rowShadeColor)\n } else {\n printColoredFiglet(primary.lines, primary.boundaryLines, primary.ansiBySegment)\n }\n return\n }\n\n if (compactSegments && compactSegments.length > 0) {\n const compactFiglet = await renderSegmentedFiglet(compactSegments)\n if (compactFiglet.widestLine <= terminalColumns) {\n printColoredFiglet(\n compactFiglet.lines,\n compactFiglet.boundaryLines,\n compactFiglet.ansiBySegment\n )\n return\n }\n }\n\n let plain = \"\"\n for (let i = 0; i < segments.length; i++) {\n const text = segments[i]?.text ?? \"\"\n if (!text) continue\n plain += `${primary.ansiBySegment[i]}${text}`\n }\n process.stdout.write(`${plain}${RESET}\\n`)\n}\n\nexport function createTsupBannerHook(\n project: string | BannerOptions | LegacyBannerOptions\n): () => Promise<void> {\n let shown = false\n const normalized = normalizeSegments(project)\n const bannerKey = JSON.stringify(normalized)\n return async () => {\n if (shown) return\n if (shownBannerKeys.has(bannerKey)) return\n shown = true\n shownBannerKeys.add(bannerKey)\n await printBanner(normalized)\n }\n}\n\nexport function createDevBannerPlugin(\n project: string | BannerOptions | LegacyBannerOptions\n): DevPlugin {\n let shown = false\n const { segments, compactSegments, rowColors, rowShadeColor } = normalizeSegments(project)\n const bannerText = segments.map((segment) => segment.text).join(\"\")\n return {\n name: `olwiba-dev-banner-${bannerText.toLowerCase()}`,\n apply: \"serve\",\n configureServer(_server: unknown) {\n if (shown) return\n shown = true\n void printBanner({ segments, compactSegments, rowColors, rowShadeColor })\n },\n }\n}\n","import { createServer } from \"node:net\"\n\n/**\n * Probe for the first free port from `start` up. Vite's own auto-increment\n * doesn't kick in reliably under the TanStack Start plugin, so dev servers\n * resolve the port themselves before passing it to `server.port`.\n */\n/** True when `port` can be bound right now. */\nasync function isFree(port: number): Promise<boolean> {\n return new Promise<boolean>((resolve) => {\n const probe = createServer()\n .once(\"error\", () => resolve(false))\n .once(\"listening\", () => probe.close(() => resolve(true)))\n probe.listen(port)\n })\n}\n\nexport async function findFreePort(start: number, attempts = 20): Promise<number> {\n for (let port = start; port < start + attempts; port++) {\n if (await isFree(port)) return port\n }\n throw new Error(`No free port found in range ${start}-${start + attempts - 1}`)\n}\n\n/**\n * Resolve the dev server port for a preferred base port, falling back to the\n * next free one and saying so loudly.\n *\n * Falling back is the right default — a second app should start rather than\n * refuse — but the move used to be near-silent, and the port is not the thing\n * that breaks. What breaks is anything holding an absolute localhost URL:\n * sign-in fails \"Invalid origin\" if the origin is pinned, and magic links point\n * at the port you are no longer on.\n *\n * So callers are expected to do two things, and the log says so:\n * - trust localhost on any port in dev (`http://localhost:*`)\n * - derive `BETTER_AUTH_URL` from the port this returns, not from `.env`\n */\nexport async function resolveDevPort(preferred: number, attempts = 20): Promise<number> {\n const port = await findFreePort(preferred, attempts)\n if (port !== preferred) {\n console.warn(\n `\\n ⚠ Port ${preferred} is in use — this dev server is on ${port} instead.\\n` +\n ` Absolute URLs built from .env still say ${preferred}. Anything that\\n` +\n ` emails you a link (magic link, email verification) will point at the\\n` +\n ` wrong port unless BETTER_AUTH_URL is derived from ${port}.\\n`,\n )\n }\n return port\n}\n","import {\n createDevBannerPlugin,\n createTsupBannerHook,\n type BannerSegment,\n} from \"./dev-banner\"\n\nexport type ProjectBrandAccent = {\n hex: string\n lightOklch?: string\n darkOklch?: string\n}\n\nexport type ProjectBannerSegment = {\n text: string\n accent?: boolean\n colorHex?: string\n}\n\nexport type ProjectConfig = {\n id: string\n label: string\n brandAccent: ProjectBrandAccent\n banner: {\n segments: readonly ProjectBannerSegment[]\n compactSegments?: readonly ProjectBannerSegment[]\n }\n}\n\nfunction resolveProjectBannerSegments(\n segments: readonly ProjectBannerSegment[],\n accentHex: string\n): BannerSegment[] {\n return segments.map((segment) => ({\n text: segment.text,\n colorHex: segment.accent ? accentHex : segment.colorHex,\n }))\n}\n\nfunction getProjectBanner(project: ProjectConfig) {\n return {\n segments: resolveProjectBannerSegments(project.banner.segments, project.brandAccent.hex),\n compactSegments: project.banner.compactSegments\n ? resolveProjectBannerSegments(project.banner.compactSegments, project.brandAccent.hex)\n : undefined,\n }\n}\n\nexport function createProjectDevBannerPlugin(project: ProjectConfig) {\n return createDevBannerPlugin(getProjectBanner(project))\n}\n\nexport function createProjectTsupBannerHook(project: ProjectConfig) {\n return createTsupBannerHook(getProjectBanner(project))\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olwiba/dx",
3
- "version": "0.0.21",
3
+ "version": "0.0.22",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "sideEffects": false,