@quitscope/discord-welcomecard 0.1.0 → 0.2.0

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.cjs CHANGED
@@ -30,8 +30,8 @@ var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${_
30
30
  var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
31
31
 
32
32
  // src/constants.ts
33
- var CARD_WIDTH = 1024;
34
- var CARD_HEIGHT = 384;
33
+ var CARD_WIDTH = 840;
34
+ var CARD_HEIGHT = 420;
35
35
  var GIF_FRAMES = 30;
36
36
  var GIF_DELAY_MS = 50;
37
37
  var GIF_SCALE = 0.5;
@@ -62,29 +62,58 @@ var DEFAULT_FONT_FAMILY = "WelcomeCard";
62
62
  // src/presets/centered.ts
63
63
  var EDGE_PAD = 24;
64
64
  var TOP_BASELINE = 36;
65
+ function isHexBackground(background) {
66
+ return typeof background === "string" && /^#[0-9a-fA-F]{3,8}$/.test(background);
67
+ }
68
+ function resolveBackgroundColor(background, fallback) {
69
+ return isHexBackground(background) ? background : fallback;
70
+ }
65
71
  function resolvePosition(position, width, height) {
66
72
  const pos = position === void 0 || position === "corner" ? "bottom-right" : position;
67
- const [v, h] = pos === "center" ? ["center", "center"] : pos.split("-");
68
- return {
69
- x: h === "left" ? EDGE_PAD : h === "center" ? width / 2 : width - EDGE_PAD,
70
- y: v === "top" ? TOP_BASELINE : v === "center" ? height / 2 : height - EDGE_PAD,
71
- align: h
72
- };
73
+ const x = { left: EDGE_PAD, center: width / 2, right: width - EDGE_PAD };
74
+ const y = { top: TOP_BASELINE, center: height / 2, bottom: height - EDGE_PAD };
75
+ switch (pos) {
76
+ case "top-left":
77
+ return { x: x.left, y: y.top, align: "left" };
78
+ case "top-center":
79
+ return { x: x.center, y: y.top, align: "center" };
80
+ case "top-right":
81
+ return { x: x.right, y: y.top, align: "right" };
82
+ case "center-left":
83
+ return { x: x.left, y: y.center, align: "left" };
84
+ case "center":
85
+ return { x: x.center, y: y.center, align: "center" };
86
+ case "center-right":
87
+ return { x: x.right, y: y.center, align: "right" };
88
+ case "bottom-left":
89
+ return { x: x.left, y: y.bottom, align: "left" };
90
+ case "bottom-center":
91
+ return { x: x.center, y: y.bottom, align: "center" };
92
+ case "bottom-right":
93
+ return { x: x.right, y: y.bottom, align: "right" };
94
+ default: {
95
+ const _exhausted = pos;
96
+ throw new Error(`Unhandled memberCountPosition: "${_exhausted}"`);
97
+ }
98
+ }
73
99
  }
74
100
  function centeredLayout(opts) {
75
101
  const width = CARD_WIDTH;
76
102
  const height = CARD_HEIGHT;
77
103
  const accent = opts.theme === "dark" ? "#89b4fa" : "#1e66f5";
78
- const bgColor = typeof opts.background === "string" && opts.background.startsWith("#") ? opts.background : opts.theme === "dark" ? "#1e1e2e" : "#eff1f5";
104
+ const bgColor = resolveBackgroundColor(
105
+ opts.background,
106
+ opts.theme === "dark" ? "#1e1e2e" : "#eff1f5"
107
+ );
79
108
  const textColor = opts.font.color ?? (opts.theme === "dark" ? "#ffffff" : "#11111b");
80
109
  const family = opts.font.family ?? DEFAULT_FONT_FAMILY;
81
- const avatarSize = 120;
82
- const avatarY = 50;
110
+ const avatarSize = 170;
111
+ const avatarY = 56;
83
112
  return {
84
113
  width,
85
114
  height,
86
115
  backgroundColor: bgColor,
87
- background: typeof opts.background === "string" && opts.background.startsWith("#") ? void 0 : opts.background,
116
+ background: isHexBackground(opts.background) ? void 0 : opts.background,
88
117
  avatar: {
89
118
  x: width / 2 - avatarSize / 2,
90
119
  y: avatarY,
@@ -95,8 +124,8 @@ function centeredLayout(opts) {
95
124
  username: {
96
125
  text: opts.username ?? "",
97
126
  x: width / 2,
98
- y: avatarY + avatarSize + 60,
99
- size: opts.font.size ?? 44,
127
+ y: avatarY + avatarSize + 66,
128
+ size: opts.font.size ?? 56,
100
129
  color: textColor,
101
130
  family,
102
131
  align: "center"
@@ -104,8 +133,8 @@ function centeredLayout(opts) {
104
133
  subtitle: opts.subtitle ? {
105
134
  text: opts.subtitle,
106
135
  x: width / 2,
107
- y: avatarY + avatarSize + 105,
108
- size: 24,
136
+ y: avatarY + avatarSize + 122,
137
+ size: opts.font.subtitleSize ?? Math.round((opts.font.size ?? 56) * 0.61),
109
138
  color: textColor,
110
139
  family,
111
140
  align: "center"
@@ -114,7 +143,7 @@ function centeredLayout(opts) {
114
143
  text: `MEMBER #${opts.memberCount}`,
115
144
  // centered preset: everything centered by default, count included
116
145
  ...resolvePosition(opts.memberCountPosition ?? "bottom-center", width, height),
117
- size: 16,
146
+ size: 20,
118
147
  color: textColor,
119
148
  family
120
149
  } : void 0
@@ -126,7 +155,7 @@ function neonLayout(opts) {
126
155
  const base = centeredLayout(opts);
127
156
  return {
128
157
  ...base,
129
- backgroundColor: opts.background?.startsWith("#") ? opts.background : "#0b0b1a",
158
+ backgroundColor: resolveBackgroundColor(opts.background, "#0b0b1a"),
130
159
  avatar: { ...base.avatar, ringColor: "#00ffd5" },
131
160
  username: { ...base.username, color: opts.font.color ?? "#00ffd5" }
132
161
  };
@@ -137,7 +166,7 @@ function minimalLayout(opts) {
137
166
  const base = centeredLayout(opts);
138
167
  return {
139
168
  ...base,
140
- backgroundColor: opts.background?.startsWith("#") ? opts.background : "#ffffff",
169
+ backgroundColor: resolveBackgroundColor(opts.background, "#ffffff"),
141
170
  avatar: { ...base.avatar, ringColor: "#222222" },
142
171
  username: { ...base.username, color: opts.font.color ?? "#111111" },
143
172
  subtitle: base.subtitle ? { ...base.subtitle, color: "#555555" } : void 0
@@ -151,10 +180,13 @@ function heroLayout(opts) {
151
180
  const textX = avatarX + base.avatar.size + 40;
152
181
  return {
153
182
  ...base,
154
- backgroundColor: opts.background?.startsWith("#") ? opts.background : "#101830",
183
+ backgroundColor: resolveBackgroundColor(
184
+ opts.background,
185
+ opts.theme === "dark" ? "#1b1f2a" : "#e8ecf4"
186
+ ),
155
187
  avatar: { ...base.avatar, x: avatarX, y: base.height / 2 - base.avatar.size / 2 },
156
- username: { ...base.username, x: textX, y: base.height / 2 - 6, align: "left" },
157
- subtitle: base.subtitle ? { ...base.subtitle, x: textX, y: base.height / 2 + 30, align: "left" } : void 0,
188
+ username: { ...base.username, x: textX, y: base.height / 2 - 12, align: "left" },
189
+ subtitle: base.subtitle ? { ...base.subtitle, x: textX, y: base.height / 2 + 42, align: "left" } : void 0,
158
190
  memberCount: base.memberCount ? (
159
191
  // hero is asymmetric — default the count to the corner, not bottom-center
160
192
  {
@@ -197,21 +229,34 @@ function layout(opts) {
197
229
 
198
230
  // src/assets/loadImage.ts
199
231
  var import_canvas2 = require("@napi-rs/canvas");
232
+ var MAX_CACHE = 256;
233
+ function boundedSet(map, key, value) {
234
+ if (map.size >= MAX_CACHE) {
235
+ map.delete(map.keys().next().value);
236
+ }
237
+ map.set(key, value);
238
+ }
239
+ var cache = /* @__PURE__ */ new Map();
240
+ var solidCache = /* @__PURE__ */ new Map();
200
241
  async function solidImage(color, w, h) {
242
+ const key = `${color}:${w}x${h}`;
243
+ const hit = solidCache.get(key);
244
+ if (hit) return hit;
201
245
  const canvas = (0, import_canvas2.createCanvas)(w, h);
202
246
  const ctx = canvas.getContext("2d");
203
247
  ctx.fillStyle = color;
204
248
  ctx.fillRect(0, 0, w, h);
205
- return (0, import_canvas2.loadImage)(canvas.toBuffer("image/png"));
249
+ const img = await (0, import_canvas2.loadImage)(canvas.toBuffer("image/png"));
250
+ boundedSet(solidCache, key, img);
251
+ return img;
206
252
  }
207
- var cache = /* @__PURE__ */ new Map();
208
253
  async function loadImageOrFallback(source, fallbackColor, w = 256, h = 256) {
209
254
  if (source === void 0) return solidImage(fallbackColor, w, h);
210
255
  const hit = cache.get(source);
211
256
  if (hit) return hit;
212
257
  try {
213
258
  const img = await (0, import_canvas2.loadImage)(source);
214
- cache.set(source, img);
259
+ boundedSet(cache, source, img);
215
260
  return img;
216
261
  } catch {
217
262
  return solidImage(fallbackColor, w, h);
@@ -668,6 +713,12 @@ async function renderGIF(opts) {
668
713
  const enc = GIFEncoder();
669
714
  const frames = opts.animations.length === 0 ? 1 : GIF_FRAMES;
670
715
  let palette;
716
+ if (frames > 1) {
717
+ const paletteState = frameStateFor(opts.animations, 0.5);
718
+ await drawFrame(ctx, l, paletteState);
719
+ outCtx.drawImage(canvas, 0, 0, gw, gh);
720
+ palette = quantize(outCtx.getImageData(0, 0, gw, gh).data, 256);
721
+ }
671
722
  for (let i = 0; i < frames; i++) {
672
723
  const progress = frames === 1 ? 0 : i / frames;
673
724
  const state = frameStateFor(opts.animations, progress);
@@ -684,7 +735,7 @@ async function renderGIF(opts) {
684
735
 
685
736
  // src/WelcomeCard.ts
686
737
  var WelcomeCard = class {
687
- opts = { ...DEFAULT_OPTIONS, font: {}, animations: [] };
738
+ opts = { ...DEFAULT_OPTIONS };
688
739
  setPreset(preset) {
689
740
  if (!PRESETS[preset]) {
690
741
  throw new WelcomeCardError(
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.15_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js","../src/constants.ts","../src/assets/fonts/register.ts","../src/presets/centered.ts","../src/presets/neon.ts","../src/presets/minimal.ts","../src/presets/hero.ts","../src/presets/index.ts","../src/errors.ts","../src/render/toPNG.ts","../src/render/layout.ts","../src/assets/loadImage.ts","../src/render/drawFrame.ts","../src/render/toGIF.ts","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/constants.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/stream.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/lzwEncode.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/rgb-packing.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/pnnquant2.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/color.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/palettize.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/index.js","../src/animate/text.ts","../src/animate/avatar.ts","../src/animate/background.ts","../src/animate/index.ts","../src/WelcomeCard.ts"],"sourcesContent":["export { WelcomeCard } from './WelcomeCard.js';\nexport { WelcomeCardError } from './errors.js';\nexport type {\n CardOptions,\n Theme,\n PresetName,\n AnimationType,\n OutputFormat,\n FontOptions,\n MemberCountPosition,\n} from './types.js';\n","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","import type { CardOptions } from './types.js';\n\nexport const CARD_WIDTH = 1024;\nexport const CARD_HEIGHT = 384; // ~16:6 banner\n\nexport const GIF_FRAMES = 30;\nexport const GIF_DELAY_MS = 50; // ~20fps\nexport const GIF_SCALE = 0.5; // GIFs render at half size to stay under Discord upload limits\n\nexport const DEFAULT_OPTIONS: CardOptions = {\n preset: 'centered',\n theme: 'dark',\n font: {},\n animations: [],\n};\n","import { GlobalFonts } from '@napi-rs/canvas';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport { existsSync } from 'node:fs';\n\nconst here = dirname(fileURLToPath(import.meta.url));\n\n// dev/tests run from src/assets/fonts; the published build runs from dist\n// with the font copied next to it (tsup publicDir).\nconst candidates = [\n join(here, 'Poppins-Bold.ttf'),\n join(here, 'assets', 'fonts', 'Poppins-Bold.ttf'),\n join(here, '..', 'src', 'assets', 'fonts', 'Poppins-Bold.ttf'),\n];\n\nconst fontPath = candidates.find(existsSync);\nif (fontPath) {\n GlobalFonts.registerFromPath(fontPath, 'WelcomeCard');\n}\n\nexport const DEFAULT_FONT_FAMILY = 'WelcomeCard';\n","import { CARD_WIDTH, CARD_HEIGHT } from '../constants.js';\nimport type { CardOptions, MemberCountPosition } from '../types.js';\nimport { DEFAULT_FONT_FAMILY } from '../assets/fonts/register.js';\n\nconst EDGE_PAD = 24;\nconst TOP_BASELINE = 36; // baseline y for top-anchored text\n\nexport function resolvePosition(\n position: MemberCountPosition | undefined,\n width: number,\n height: number,\n): { x: number; y: number; align: 'left' | 'center' | 'right' } {\n const pos = position === undefined || position === 'corner' ? 'bottom-right' : position;\n const [v, h] = pos === 'center' ? ['center', 'center'] : pos.split('-');\n return {\n x: h === 'left' ? EDGE_PAD : h === 'center' ? width / 2 : width - EDGE_PAD,\n y: v === 'top' ? TOP_BASELINE : v === 'center' ? height / 2 : height - EDGE_PAD,\n align: h as 'left' | 'center' | 'right',\n };\n}\n\nexport interface TextBox {\n text: string;\n x: number;\n y: number;\n size: number;\n color: string;\n family: string;\n align: 'left' | 'center' | 'right';\n}\n\nexport interface LayoutResult {\n width: number;\n height: number;\n backgroundColor: string;\n background?: string | Buffer;\n avatar: { x: number; y: number; size: number; ringColor: string; source?: string | Buffer };\n username: TextBox;\n subtitle?: TextBox;\n memberCount?: TextBox;\n}\n\nexport function centeredLayout(opts: CardOptions): LayoutResult {\n const width = CARD_WIDTH;\n const height = CARD_HEIGHT;\n const accent = opts.theme === 'dark' ? '#89b4fa' : '#1e66f5';\n const bgColor =\n typeof opts.background === 'string' && opts.background.startsWith('#')\n ? opts.background\n : opts.theme === 'dark'\n ? '#1e1e2e'\n : '#eff1f5';\n const textColor = opts.font.color ?? (opts.theme === 'dark' ? '#ffffff' : '#11111b');\n const family = opts.font.family ?? DEFAULT_FONT_FAMILY;\n\n const avatarSize = 120;\n const avatarY = 50;\n\n return {\n width,\n height,\n backgroundColor: bgColor,\n background:\n typeof opts.background === 'string' && opts.background.startsWith('#')\n ? undefined\n : opts.background,\n avatar: {\n x: width / 2 - avatarSize / 2,\n y: avatarY,\n size: avatarSize,\n ringColor: accent,\n source: opts.avatar,\n },\n username: {\n text: opts.username ?? '',\n x: width / 2,\n y: avatarY + avatarSize + 60,\n size: opts.font.size ?? 44,\n color: textColor,\n family,\n align: 'center',\n },\n subtitle: opts.subtitle\n ? {\n text: opts.subtitle,\n x: width / 2,\n y: avatarY + avatarSize + 105,\n size: 24,\n color: textColor,\n family,\n align: 'center',\n }\n : undefined,\n memberCount:\n opts.memberCount !== undefined\n ? {\n text: `MEMBER #${opts.memberCount}`,\n // centered preset: everything centered by default, count included\n ...resolvePosition(opts.memberCountPosition ?? 'bottom-center', width, height),\n size: 16,\n color: textColor,\n family,\n }\n : undefined,\n };\n}\n","import { centeredLayout } from './centered.js';\nimport type { CardOptions } from '../types.js';\nimport type { LayoutResult } from './centered.js';\n\nexport function neonLayout(opts: CardOptions): LayoutResult {\n const base = centeredLayout(opts);\n return {\n ...base,\n backgroundColor: opts.background?.startsWith('#') ? opts.background : '#0b0b1a',\n avatar: { ...base.avatar, ringColor: '#00ffd5' },\n username: { ...base.username, color: opts.font.color ?? '#00ffd5' },\n };\n}\n","import { centeredLayout } from './centered.js';\nimport type { CardOptions } from '../types.js';\nimport type { LayoutResult } from './centered.js';\n\nexport function minimalLayout(opts: CardOptions): LayoutResult {\n const base = centeredLayout(opts);\n return {\n ...base,\n backgroundColor: opts.background?.startsWith('#') ? opts.background : '#ffffff',\n avatar: { ...base.avatar, ringColor: '#222222' },\n username: { ...base.username, color: opts.font.color ?? '#111111' },\n subtitle: base.subtitle ? { ...base.subtitle, color: '#555555' } : undefined,\n };\n}\n","import { centeredLayout, resolvePosition } from './centered.js';\nimport type { CardOptions } from '../types.js';\nimport type { LayoutResult } from './centered.js';\n\n// Hero: avatar shifted left, text left-aligned beside it.\nexport function heroLayout(opts: CardOptions): LayoutResult {\n const base = centeredLayout(opts);\n const avatarX = 60;\n const textX = avatarX + base.avatar.size + 40;\n return {\n ...base,\n backgroundColor: opts.background?.startsWith('#') ? opts.background : '#101830',\n avatar: { ...base.avatar, x: avatarX, y: base.height / 2 - base.avatar.size / 2 },\n username: { ...base.username, x: textX, y: base.height / 2 - 6, align: 'left' },\n subtitle: base.subtitle\n ? { ...base.subtitle, x: textX, y: base.height / 2 + 30, align: 'left' }\n : undefined,\n memberCount: base.memberCount\n ? // hero is asymmetric — default the count to the corner, not bottom-center\n {\n ...base.memberCount,\n ...resolvePosition(opts.memberCountPosition ?? 'bottom-right', base.width, base.height),\n }\n : undefined,\n };\n}\n","import type { CardOptions, PresetName } from '../types.js';\nimport { centeredLayout, type LayoutResult } from './centered.js';\nimport { neonLayout } from './neon.js';\nimport { minimalLayout } from './minimal.js';\nimport { heroLayout } from './hero.js';\n\nexport type { LayoutResult, TextBox } from './centered.js';\nexport type LayoutFn = (opts: CardOptions) => LayoutResult;\n\nexport const PRESETS: Record<PresetName, LayoutFn> = {\n centered: centeredLayout,\n neon: neonLayout,\n minimal: minimalLayout,\n hero: heroLayout,\n};\n","export class WelcomeCardError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WelcomeCardError';\n }\n}\n","import { createCanvas } from '@napi-rs/canvas';\nimport '../assets/fonts/register.js';\nimport type { CardOptions } from '../types.js';\nimport { layout } from './layout.js';\nimport { drawFrame, STATIC_FRAME } from './drawFrame.js';\n\nexport async function renderPNG(opts: CardOptions): Promise<Buffer> {\n const l = layout(opts);\n const canvas = createCanvas(l.width, l.height);\n const ctx = canvas.getContext('2d');\n await drawFrame(ctx, l, STATIC_FRAME);\n return canvas.toBuffer('image/png');\n}\n","import type { CardOptions } from '../types.js';\nimport { PRESETS, type LayoutResult } from '../presets/index.js';\nimport { WelcomeCardError } from '../errors.js';\n\nexport function layout(opts: CardOptions): LayoutResult {\n const fn = PRESETS[opts.preset];\n if (!fn) {\n throw new WelcomeCardError(\n `Unknown preset \"${opts.preset}\". Allowed: ${Object.keys(PRESETS).join(', ')}`,\n );\n }\n return fn(opts);\n}\n","import { loadImage, createCanvas, type Image } from '@napi-rs/canvas';\n\nasync function solidImage(color: string, w: number, h: number): Promise<Image> {\n const canvas = createCanvas(w, h);\n const ctx = canvas.getContext('2d');\n ctx.fillStyle = color;\n ctx.fillRect(0, 0, w, h);\n return loadImage(canvas.toBuffer('image/png'));\n}\n\n// Cache so GIF rendering (N frames) fetches each URL/Buffer only once.\nconst cache = new Map<string | Buffer, Image>();\n\nexport async function loadImageOrFallback(\n source: string | Buffer | undefined,\n fallbackColor: string,\n w = 256,\n h = 256,\n): Promise<Image> {\n if (source === undefined) return solidImage(fallbackColor, w, h);\n const hit = cache.get(source);\n if (hit) return hit;\n try {\n const img = await loadImage(source);\n cache.set(source, img);\n return img;\n } catch {\n return solidImage(fallbackColor, w, h);\n }\n}\n","import type { SKRSContext2D } from '@napi-rs/canvas';\nimport type { LayoutResult, TextBox } from '../presets/index.js';\nimport { loadImageOrFallback } from '../assets/loadImage.js';\n\nexport interface FrameState {\n textAlpha: number; // 0..1 reveal for text\n avatarGlow: number; // 0..1 glow intensity\n backgroundShift: number; // 0..1 gradient phase\n}\n\nexport const STATIC_FRAME: FrameState = { textAlpha: 1, avatarGlow: 1, backgroundShift: 0 };\n\nfunction drawText(ctx: SKRSContext2D, box: TextBox, alpha: number) {\n ctx.save();\n ctx.globalAlpha = alpha;\n ctx.fillStyle = box.color;\n ctx.textAlign = box.align;\n ctx.textBaseline = 'alphabetic';\n ctx.font = `${box.size}px ${box.family}`;\n ctx.fillText(box.text, box.x, box.y);\n ctx.restore();\n}\n\nexport async function drawFrame(\n ctx: SKRSContext2D,\n l: LayoutResult,\n state: FrameState,\n): Promise<void> {\n // background\n ctx.fillStyle = l.backgroundColor;\n ctx.fillRect(0, 0, l.width, l.height);\n if (l.background !== undefined) {\n const bg = await loadImageOrFallback(l.background, l.backgroundColor, l.width, l.height);\n ctx.drawImage(bg, 0, 0, l.width, l.height);\n }\n if (state.backgroundShift > 0) {\n // diagonal sheen sliding across the card; phase 0..1 loops with the GIF\n const x = (state.backgroundShift * 2 - 1) * l.width * 2;\n const g = ctx.createLinearGradient(x, 0, x + l.width, l.height);\n g.addColorStop(0, 'rgba(255,255,255,0)');\n g.addColorStop(0.5, 'rgba(255,255,255,0.10)');\n g.addColorStop(1, 'rgba(255,255,255,0)');\n ctx.fillStyle = g;\n ctx.fillRect(0, 0, l.width, l.height);\n }\n\n // avatar (circular) with glow ring\n const { x, y, size, ringColor } = l.avatar;\n const cx = x + size / 2;\n const cy = y + size / 2;\n ctx.save();\n ctx.shadowColor = ringColor;\n ctx.shadowBlur = 10 + state.avatarGlow * 25;\n ctx.lineWidth = 6;\n ctx.strokeStyle = ringColor;\n ctx.beginPath();\n ctx.arc(cx, cy, size / 2 + 3, 0, Math.PI * 2);\n ctx.stroke();\n ctx.restore();\n\n const avatarImg = await loadImageOrFallback(l.avatar.source, ringColor, size, size);\n ctx.save();\n ctx.beginPath();\n ctx.arc(cx, cy, size / 2, 0, Math.PI * 2);\n ctx.clip();\n ctx.drawImage(avatarImg, x, y, size, size);\n ctx.restore();\n\n // text\n drawText(ctx, l.username, state.textAlpha);\n if (l.subtitle) drawText(ctx, l.subtitle, state.textAlpha);\n if (l.memberCount) drawText(ctx, l.memberCount, state.textAlpha);\n}\n","import { createCanvas } from '@napi-rs/canvas';\nimport * as gifencMod from 'gifenc';\n// gifenc ships dual CJS/ESM with inconsistent interop — named exports may live on the\n// namespace (vite/bundlers) or behind .default (node CJS-ESM interop). Pick whichever has them.\ntype Gifenc = typeof import('gifenc');\nconst { GIFEncoder, quantize, applyPalette } =\n 'GIFEncoder' in gifencMod ? (gifencMod as Gifenc) : (gifencMod as { default: Gifenc }).default;\nimport '../assets/fonts/register.js';\nimport type { CardOptions } from '../types.js';\nimport { GIF_FRAMES, GIF_DELAY_MS, GIF_SCALE } from '../constants.js';\nimport { layout } from './layout.js';\nimport { drawFrame } from './drawFrame.js';\nimport { frameStateFor } from '../animate/index.js';\n\nexport async function renderGIF(opts: CardOptions): Promise<Buffer> {\n const l = layout(opts);\n // draw at full size, encode at half size: smaller files, under Discord limits\n const canvas = createCanvas(l.width, l.height);\n const ctx = canvas.getContext('2d');\n const gw = Math.round(l.width * GIF_SCALE);\n const gh = Math.round(l.height * GIF_SCALE);\n const out = createCanvas(gw, gh);\n const outCtx = out.getContext('2d');\n const enc = GIFEncoder();\n\n const frames = opts.animations.length === 0 ? 1 : GIF_FRAMES;\n // one shared palette for all frames: stable colors (no flicker), faster encode\n let palette: number[][] | undefined;\n for (let i = 0; i < frames; i++) {\n const progress = frames === 1 ? 0 : i / frames;\n const state = frameStateFor(opts.animations, progress);\n await drawFrame(ctx, l, state);\n outCtx.drawImage(canvas, 0, 0, gw, gh);\n const { data } = outCtx.getImageData(0, 0, gw, gh);\n palette ??= quantize(data, 256);\n const index = applyPalette(data, palette);\n enc.writeFrame(index, gw, gh, { palette, delay: GIF_DELAY_MS });\n }\n enc.finish();\n return Buffer.from(enc.bytes());\n}\n","export default {\n signature: \"GIF\",\n version: \"89a\",\n trailer: 0x3B,\n extensionIntroducer: 0x21,\n applicationExtensionLabel: 0xFF,\n graphicControlExtensionLabel: 0xF9,\n imageSeparator: 0x2C,\n // Header\n signatureSize: 3,\n versionSize: 3,\n globalColorTableFlagMask: 0b10000000,\n colorResolutionMask: 0b01110000,\n sortFlagMask: 0b00001000,\n globalColorTableSizeMask: 0b00000111,\n // Application extension\n applicationIdentifierSize: 8,\n applicationAuthCodeSize: 3,\n // Graphic control extension\n disposalMethodMask: 0b00011100,\n userInputFlagMask: 0b00000010,\n transparentColorFlagMask: 0b00000001,\n // Image descriptor\n localColorTableFlagMask: 0b10000000,\n interlaceFlagMask: 0b01000000,\n idSortFlagMask: 0b00100000,\n localColorTableSizeMask: 0b00000111\n}\n","export default function createStream(initialCapacity = 256) {\n let cursor = 0;\n let contents = new Uint8Array(initialCapacity);\n\n return {\n get buffer() {\n return contents.buffer;\n },\n reset() {\n cursor = 0;\n },\n bytesView() {\n return contents.subarray(0, cursor);\n },\n bytes() {\n return contents.slice(0, cursor);\n },\n writeByte(byte) {\n expand(cursor + 1);\n contents[cursor] = byte;\n cursor++;\n },\n writeBytes(data, offset = 0, byteLength = data.length) {\n expand(cursor + byteLength);\n for (let i = 0; i < byteLength; i++) {\n contents[cursor++] = data[i + offset];\n }\n },\n writeBytesView(data, offset = 0, byteLength = data.byteLength) {\n expand(cursor + byteLength);\n contents.set(data.subarray(offset, offset + byteLength), cursor);\n cursor += byteLength;\n },\n };\n\n function expand(newCapacity) {\n var prevCapacity = contents.length;\n if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough.\n // Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity.\n // For small filesizes (<1MB), perform size*2 geometric increase, but for large sizes, do a much more conservative size*1.125 increase to\n // avoid overshooting the allocation cap by a very large margin.\n var CAPACITY_DOUBLING_MAX = 1024 * 1024;\n newCapacity = Math.max(\n newCapacity,\n (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) >>>\n 0\n );\n if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.\n const oldContents = contents;\n contents = new Uint8Array(newCapacity); // Allocate new storage.\n if (cursor > 0) contents.set(oldContents.subarray(0, cursor), 0);\n }\n}\n","/*\n LZWEncoder.js\n Authors\n Kevin Weiner (original Java version - kweiner@fmsware.com)\n Thibault Imbert (AS3 version - bytearray.org)\n Johan Nordberg (JS version - code@johan-nordberg.com)\n Acknowledgements\n GIFCOMPR.C - GIF Image compression routines\n Lempel-Ziv compression based on 'compress'. GIF modifications by\n David Rowley (mgardi@watdcsu.waterloo.edu)\n GIF Image compression - modified 'compress'\n Based on: compress.c - File compression ala IEEE Computer, June 1984.\n By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)\n Jim McKie (decvax!mcvax!jim)\n Steve Davies (decvax!vax135!petsd!peora!srd)\n Ken Turkowski (decvax!decwrl!turtlevax!ken)\n James A. Woods (decvax!ihnp4!ames!jaw)\n Joe Orost (decvax!vax135!petsd!joe)\n Matt DesLauriers (@mattdesl - V8/JS optimizations)\n Mathieu Henri (@p01 - JS optimization)\n*/\n\nimport createStream from \"./stream.js\";\n\nconst EOF = -1;\nconst BITS = 12;\nconst DEFAULT_HSIZE = 5003; // 80% occupancy\nconst MASKS = [\n 0x0000,\n 0x0001,\n 0x0003,\n 0x0007,\n 0x000f,\n 0x001f,\n 0x003f,\n 0x007f,\n 0x00ff,\n 0x01ff,\n 0x03ff,\n 0x07ff,\n 0x0fff,\n 0x1fff,\n 0x3fff,\n 0x7fff,\n 0xffff,\n];\n\nfunction lzwEncode(\n width,\n height,\n pixels,\n colorDepth,\n outStream = createStream(512),\n accum = new Uint8Array(256),\n htab = new Int32Array(DEFAULT_HSIZE),\n codetab = new Int32Array(DEFAULT_HSIZE)\n) {\n const hsize = htab.length;\n const initCodeSize = Math.max(2, colorDepth);\n\n accum.fill(0);\n codetab.fill(0);\n htab.fill(-1);\n\n let cur_accum = 0;\n let cur_bits = 0;\n\n // Algorithm: use open addressing double hashing (no chaining) on the\n // prefix code / next character combination. We do a variant of Knuth's\n // algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime\n // secondary probe. Here, the modular division first probe is gives way\n // to a faster exclusive-or manipulation. Also do block compression with\n // an adaptive reset, whereby the code table is cleared when the compression\n // ratio decreases, but after the table fills. The variable-length output\n // codes are re-sized at this point, and a special CLEAR code is generated\n // for the decompressor. Late addition: construct the table according to\n // file size for noticeable speed improvement on small files. Please direct\n // questions about this implementation to ames!jaw.\n\n // compress and write the pixel data\n const init_bits = initCodeSize + 1;\n\n // Set up the globals: g_init_bits - initial number of bits\n const g_init_bits = init_bits;\n\n // Set up the necessary values\n\n // block compression parameters -- after all codes are used up,\n // and compression rate changes, start over.\n let clear_flg = false;\n let n_bits = g_init_bits;\n let maxcode = (1 << n_bits) - 1;\n\n const ClearCode = 1 << (init_bits - 1);\n const EOFCode = ClearCode + 1;\n let free_ent = ClearCode + 2;\n let a_count = 0; // clear packet\n\n let ent = pixels[0];\n\n let hshift = 0;\n for (let fcode = hsize; fcode < 65536; fcode *= 2) {\n ++hshift;\n }\n hshift = 8 - hshift; // set hash code range bound\n\n outStream.writeByte(initCodeSize); // write \"initial code size\" byte\n\n output(ClearCode);\n\n const length = pixels.length;\n for (let idx = 1; idx < length; idx++) {\n next_block: {\n const c = pixels[idx];\n const fcode = (c << BITS) + ent;\n let i = (c << hshift) ^ ent; // xor hashing\n if (htab[i] === fcode) {\n ent = codetab[i];\n break next_block;\n }\n\n const disp = i === 0 ? 1 : hsize - i; // secondary hash (after G. Knott)\n while (htab[i] >= 0) {\n // non-empty slot\n i -= disp;\n if (i < 0) i += hsize;\n if (htab[i] === fcode) {\n ent = codetab[i];\n break next_block;\n }\n }\n output(ent);\n ent = c;\n if (free_ent < 1 << BITS) {\n codetab[i] = free_ent++; // code -> hashtable\n htab[i] = fcode;\n } else {\n // Clear out the hash table\n // table clear for block compress\n htab.fill(-1);\n free_ent = ClearCode + 2;\n clear_flg = true;\n output(ClearCode);\n }\n }\n }\n\n // Put out the final code.\n output(ent);\n output(EOFCode);\n\n outStream.writeByte(0); // write block terminator\n return outStream.bytesView();\n\n function output(code) {\n cur_accum &= MASKS[cur_bits];\n\n if (cur_bits > 0) cur_accum |= code << cur_bits;\n else cur_accum = code;\n\n cur_bits += n_bits;\n\n while (cur_bits >= 8) {\n // Add a character to the end of the current packet, and if it is 254\n // characters, flush the packet to disk.\n accum[a_count++] = cur_accum & 0xff;\n if (a_count >= 254) {\n outStream.writeByte(a_count);\n outStream.writeBytesView(accum, 0, a_count);\n a_count = 0;\n }\n cur_accum >>= 8;\n cur_bits -= 8;\n }\n\n // If the next entry is going to be too big for the code size,\n // then increase it, if possible.\n if (free_ent > maxcode || clear_flg) {\n if (clear_flg) {\n n_bits = g_init_bits;\n maxcode = (1 << n_bits) - 1;\n clear_flg = false;\n } else {\n ++n_bits;\n maxcode = n_bits === BITS ? (1 << n_bits) : (1 << n_bits) - 1;\n }\n }\n\n if (code == EOFCode) {\n // At EOF, write the rest of the buffer.\n while (cur_bits > 0) {\n // Add a character to the end of the current packet, and if it is 254\n // characters, flush the packet to disk.\n accum[a_count++] = cur_accum & 0xff;\n if (a_count >= 254) {\n outStream.writeByte(a_count);\n outStream.writeBytesView(accum, 0, a_count);\n a_count = 0;\n }\n cur_accum >>= 8;\n cur_bits -= 8;\n }\n // Flush the packet to disk, and reset the accumulator\n if (a_count > 0) {\n outStream.writeByte(a_count);\n outStream.writeBytesView(accum, 0, a_count);\n a_count = 0;\n }\n }\n }\n}\n\nexport default lzwEncode;\n","export function uint32_to_rgba(color) {\n var a = (color >> 24) & 0xff;\n var b = (color >> 16) & 0xff;\n var g = (color >> 8) & 0xff;\n var r = color & 0xff;\n return [r, g, b, a];\n}\n\nexport function rgba_to_uint32(r, g, b, a) {\n return (a << 24) | (b << 16) | (g << 8) | r;\n}\n\nexport function rgb888_to_rgb565(r, g, b) {\n return ((r << 8) & 0xf800) | ((g << 2) & 0x03e0) | (b >> 3);\n}\n\nexport function rgba8888_to_rgba4444(r, g, b, a) {\n return (r >> 4) | (g & 0xf0) | ((b & 0xf0) << 4) | ((a & 0xf0) << 8);\n}\n\nexport function rgb888_to_rgb444(r, g, b) {\n return ((r >> 4) << 8) | (g & 0xf0) | (b >> 4);\n}\n\n// Alternative 565 ?\n// return ((r & 0xf8) << 8) + ((g & 0xfc) << 3) + (b >> 3);\n\n// Alternative 4444 ?\n// ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | (g & 0xf0) | (b >> 4);\n","// Modified from:\n// https://github.com/mcychan/PnnQuant.js/blob/master/src/pnnquant.js\n\n/* Fast pairwise nearest neighbor based algorithm for multilevel thresholding\nCopyright (C) 2004-2019 Mark Tyler and Dmitry Groshev\nCopyright (c) 2018-2021 Miller Cy Chan\n* error measure; time used is proportional to number of bins squared - WJ */\n\nimport {\n rgb888_to_rgb565,\n rgb888_to_rgb444,\n rgba8888_to_rgba4444,\n} from \"./rgb-packing.js\";\n\nfunction clamp(value, min, max) {\n return value < min ? min : value > max ? max : value;\n}\n\nfunction sqr(value) {\n return value * value;\n}\n\nfunction find_nn(bins, idx, hasAlpha) {\n var nn = 0;\n var err = 1e100;\n\n const bin1 = bins[idx];\n const n1 = bin1.cnt;\n const wa = bin1.ac;\n const wr = bin1.rc;\n const wg = bin1.gc;\n const wb = bin1.bc;\n for (var i = bin1.fw; i != 0; i = bins[i].fw) {\n const bin = bins[i];\n const n2 = bin.cnt;\n const nerr2 = (n1 * n2) / (n1 + n2);\n if (nerr2 >= err) continue;\n\n var nerr = 0;\n if (hasAlpha) {\n nerr += nerr2 * sqr(bin.ac - wa);\n if (nerr >= err) continue;\n }\n\n nerr += nerr2 * sqr(bin.rc - wr);\n if (nerr >= err) continue;\n\n nerr += nerr2 * sqr(bin.gc - wg);\n if (nerr >= err) continue;\n\n nerr += nerr2 * sqr(bin.bc - wb);\n if (nerr >= err) continue;\n err = nerr;\n nn = i;\n }\n bin1.err = err;\n bin1.nn = nn;\n}\n\nfunction create_bin() {\n return {\n ac: 0,\n rc: 0,\n gc: 0,\n bc: 0,\n cnt: 0,\n nn: 0,\n fw: 0,\n bk: 0,\n tm: 0,\n mtm: 0,\n err: 0,\n };\n}\n\nfunction bin_add_rgb(bin, r, g, b) {\n bin.rc += r;\n bin.gc += g;\n bin.bc += b;\n bin.cnt++;\n}\n\nfunction create_bin_list(data, format) {\n const bincount = format === \"rgb444\" ? 4096 : 65536;\n const bins = new Array(bincount);\n const size = data.length;\n\n /* Build histogram */\n // Note: Instead of introducing branching/conditions\n // within a very hot per-pixel iteration, we just duplicate the code\n // for each new condition\n if (format === \"rgba4444\") {\n for (let i = 0; i < size; ++i) {\n const color = data[i];\n const a = (color >> 24) & 0xff;\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n\n // reduce to rgb4444 16-bit uint\n const index = rgba8888_to_rgba4444(r, g, b, a);\n let bin = index in bins ? bins[index] : (bins[index] = create_bin());\n bin.rc += r;\n bin.gc += g;\n bin.bc += b;\n bin.ac += a;\n bin.cnt++;\n }\n }\n \n else if (format === \"rgb444\") {\n for (let i = 0; i < size; ++i) {\n const color = data[i];\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n\n // reduce to rgb444 12-bit uint\n const index = rgb888_to_rgb444(r, g, b);\n let bin = index in bins ? bins[index] : (bins[index] = create_bin());\n bin.rc += r;\n bin.gc += g;\n bin.bc += b;\n bin.cnt++;\n }\n } else {\n for (let i = 0; i < size; ++i) {\n const color = data[i];\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n\n // reduce to rgb565 16-bit uint\n const index = rgb888_to_rgb565(r, g, b);\n let bin = index in bins ? bins[index] : (bins[index] = create_bin());\n bin.rc += r;\n bin.gc += g;\n bin.bc += b;\n bin.cnt++;\n }\n }\n return bins;\n}\n\nexport default function quantize(rgba, maxColors, opts = {}) {\n const {\n format = \"rgb565\",\n clearAlpha = true,\n clearAlphaColor = 0x00,\n clearAlphaThreshold = 0,\n oneBitAlpha = false,\n } = opts;\n\n if (!rgba || !rgba.buffer) {\n throw new Error('quantize() expected RGBA Uint8Array data');\n }\n if (!(rgba instanceof Uint8Array) && !(rgba instanceof Uint8ClampedArray)) {\n throw new Error('quantize() expected RGBA Uint8Array data');\n }\n \n const data = new Uint32Array(rgba.buffer);\n\n let useSqrt = opts.useSqrt !== false;\n\n // format can be:\n // rgb565 (default)\n // rgb444\n // rgba4444\n\n const hasAlpha = format === \"rgba4444\";\n const bins = create_bin_list(data, format);\n const bincount = bins.length;\n const bincountMinusOne = bincount - 1;\n const heap = new Uint32Array(bincount + 1);\n\n /* Cluster nonempty bins at one end of array */\n var maxbins = 0;\n for (var i = 0; i < bincount; ++i) {\n const bin = bins[i];\n if (bin != null) {\n var d = 1.0 / bin.cnt;\n if (hasAlpha) bin.ac *= d;\n bin.rc *= d;\n bin.gc *= d;\n bin.bc *= d;\n bins[maxbins++] = bin;\n }\n }\n\n if (sqr(maxColors) / maxbins < 0.022) {\n useSqrt = false;\n }\n\n var i = 0;\n for (; i < maxbins - 1; ++i) {\n bins[i].fw = i + 1;\n bins[i + 1].bk = i;\n if (useSqrt) bins[i].cnt = Math.sqrt(bins[i].cnt);\n }\n if (useSqrt) bins[i].cnt = Math.sqrt(bins[i].cnt);\n\n var h, l, l2;\n /* Initialize nearest neighbors and build heap of them */\n for (i = 0; i < maxbins; ++i) {\n find_nn(bins, i, false);\n /* Push slot on heap */\n var err = bins[i].err;\n for (l = ++heap[0]; l > 1; l = l2) {\n l2 = l >> 1;\n if (bins[(h = heap[l2])].err <= err) break;\n heap[l] = h;\n }\n heap[l] = i;\n }\n\n /* Merge bins which increase error the least */\n var extbins = maxbins - maxColors;\n for (i = 0; i < extbins; ) {\n var tb;\n /* Use heap to find which bins to merge */\n for (;;) {\n var b1 = heap[1];\n tb = bins[b1]; /* One with least error */\n /* Is stored error up to date? */\n if (tb.tm >= tb.mtm && bins[tb.nn].mtm <= tb.tm) break;\n if (tb.mtm == bincountMinusOne)\n /* Deleted node */ b1 = heap[1] = heap[heap[0]--];\n /* Too old error value */ else {\n find_nn(bins, b1, false);\n tb.tm = i;\n }\n /* Push slot down */\n var err = bins[b1].err;\n for (l = 1; (l2 = l + l) <= heap[0]; l = l2) {\n if (l2 < heap[0] && bins[heap[l2]].err > bins[heap[l2 + 1]].err) l2++;\n if (err <= bins[(h = heap[l2])].err) break;\n heap[l] = h;\n }\n heap[l] = b1;\n }\n\n /* Do a merge */\n var nb = bins[tb.nn];\n var n1 = tb.cnt;\n var n2 = nb.cnt;\n var d = 1.0 / (n1 + n2);\n if (hasAlpha) tb.ac = d * (n1 * tb.ac + n2 * nb.ac);\n tb.rc = d * (n1 * tb.rc + n2 * nb.rc);\n tb.gc = d * (n1 * tb.gc + n2 * nb.gc);\n tb.bc = d * (n1 * tb.bc + n2 * nb.bc);\n tb.cnt += nb.cnt;\n tb.mtm = ++i;\n\n /* Unchain deleted bin */\n bins[nb.bk].fw = nb.fw;\n bins[nb.fw].bk = nb.bk;\n nb.mtm = bincountMinusOne;\n }\n\n // let palette = new Uint32Array(maxColors);\n let palette = [];\n\n /* Fill palette */\n var k = 0;\n for (i = 0; ; ++k) {\n let r = clamp(Math.round(bins[i].rc), 0, 0xff);\n let g = clamp(Math.round(bins[i].gc), 0, 0xff);\n let b = clamp(Math.round(bins[i].bc), 0, 0xff);\n\n let a = 0xff;\n if (hasAlpha) {\n a = clamp(Math.round(bins[i].ac), 0, 0xff);\n if (oneBitAlpha) {\n const threshold = typeof oneBitAlpha === \"number\" ? oneBitAlpha : 127;\n a = a <= threshold ? 0x00 : 0xff;\n }\n if (clearAlpha && a <= clearAlphaThreshold) {\n r = g = b = clearAlphaColor;\n a = 0x00;\n }\n }\n\n const color = hasAlpha ? [r, g, b, a] : [r, g, b];\n const exists = existsInPalette(palette, color);\n if (!exists) palette.push(color);\n if ((i = bins[i].fw) == 0) break;\n }\n\n return palette;\n}\n\nfunction existsInPalette(palette, color) {\n for (let i = 0; i < palette.length; i++) {\n const p = palette[i];\n let matchesRGB =\n p[0] === color[0] && p[1] === color[1] && p[2] === color[2];\n let matchesAlpha =\n p.length >= 4 && color.length >= 4 ? p[3] === color[3] : true;\n if (matchesRGB && matchesAlpha) return true;\n }\n return false;\n}\n\n// TODO: Further 'clean' palette by merging nearly-identical colors?\n","function rgb2y(r, g, b) {\n return r * 0.29889531 + g * 0.58662247 + b * 0.11448223;\n}\nfunction rgb2i(r, g, b) {\n return r * 0.59597799 - g * 0.2741761 - b * 0.32180189;\n}\nfunction rgb2q(r, g, b) {\n return r * 0.21147017 - g * 0.52261711 + b * 0.31114694;\n}\n\nexport function colorDifferenceYIQSquared(yiqA, yiqB) {\n const y = yiqA[0] - yiqB[0];\n const i = yiqA[1] - yiqB[1];\n const q = yiqA[2] - yiqB[2];\n const a = alpha(yiqA) - alpha(yiqB);\n return y * y * 0.5053 + i * i * 0.299 + q * q * 0.1957 + a * a;\n}\n\nfunction alpha(array) {\n return array[3] != null ? array[3] : 0xff;\n}\n\nexport function colorDifferenceYIQ(yiqA, yiqB) {\n return Math.sqrt(colorDifferenceYIQSquared(yiqA, yiqB));\n}\n\nexport function colorDifferenceRGBToYIQSquared(rgb1, rgb2) {\n const [r1, g1, b1] = rgb1;\n const [r2, g2, b2] = rgb2;\n const y = rgb2y(r1, g1, b1) - rgb2y(r2, g2, b2),\n i = rgb2i(r1, g1, b1) - rgb2i(r2, g2, b2),\n q = rgb2q(r1, g1, b1) - rgb2q(r2, g2, b2);\n const a = alpha(rgb1) - alpha(rgb2);\n return y * y * 0.5053 + i * i * 0.299 + q * q * 0.1957 + a * a;\n}\n\nexport function colorDifferenceRGBToYIQ(rgb1, rgb2) {\n return Math.sqrt(colorDifferenceRGBToYIQSquared(rgb1, rgb2));\n}\n\nexport function euclideanDistanceSquared(a, b) {\n var sum = 0;\n var n;\n for (n = 0; n < a.length; n++) {\n const dx = a[n] - b[n];\n sum += dx * dx;\n }\n return sum;\n}\n\nexport function euclideanDistance(a, b) {\n return Math.sqrt(euclideanDistanceSquared(a, b));\n}\n","import {\n rgb888_to_rgb444,\n rgb888_to_rgb565,\n rgba8888_to_rgba4444,\n} from \"./rgb-packing.js\";\n\nimport { euclideanDistanceSquared } from \"./color.js\";\n\nfunction roundStep(byte, step) {\n return step > 1 ? Math.round(byte / step) * step : byte;\n}\n\nexport function prequantize(\n rgba,\n { roundRGB = 5, roundAlpha = 10, oneBitAlpha = null } = {}\n) {\n const data = new Uint32Array(rgba.buffer);\n for (let i = 0; i < data.length; i++) {\n const color = data[i];\n let a = (color >> 24) & 0xff;\n let b = (color >> 16) & 0xff;\n let g = (color >> 8) & 0xff;\n let r = color & 0xff;\n\n a = roundStep(a, roundAlpha);\n if (oneBitAlpha) {\n const threshold = typeof oneBitAlpha === \"number\" ? oneBitAlpha : 127;\n a = a <= threshold ? 0x00 : 0xff;\n }\n r = roundStep(r, roundRGB);\n g = roundStep(g, roundRGB);\n b = roundStep(b, roundRGB);\n\n data[i] = (a << 24) | (b << 16) | (g << 8) | (r << 0);\n }\n}\n\nexport function applyPalette(rgba, palette, format = \"rgb565\") {\n if (!rgba || !rgba.buffer) {\n throw new Error('quantize() expected RGBA Uint8Array data');\n }\n if (!(rgba instanceof Uint8Array) && !(rgba instanceof Uint8ClampedArray)) {\n throw new Error('quantize() expected RGBA Uint8Array data');\n }\n if (palette.length > 256) {\n throw new Error('applyPalette() only works with 256 colors or less');\n }\n\n const data = new Uint32Array(rgba.buffer);\n const length = data.length;\n const bincount = format === \"rgb444\" ? 4096 : 65536;\n const index = new Uint8Array(length);\n const cache = new Array(bincount);\n const hasAlpha = format === \"rgba4444\";\n\n // Some duplicate code below due to very hot code path\n // Introducing branching/conditions shows some significant impact\n if (format === \"rgba4444\") {\n for (let i = 0; i < length; i++) {\n const color = data[i];\n const a = (color >> 24) & 0xff;\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n const key = rgba8888_to_rgba4444(r, g, b, a);\n const idx = key in cache ? cache[key] : (cache[key] = nearestColorIndexRGBA(r, g, b, a, palette));\n index[i] = idx;\n }\n } else {\n const rgb888_to_key = format === \"rgb444\" ? rgb888_to_rgb444 : rgb888_to_rgb565;\n for (let i = 0; i < length; i++) {\n const color = data[i];\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n const key = rgb888_to_key(r, g, b);\n const idx = key in cache ? cache[key] : (cache[key] = nearestColorIndexRGB(r, g, b, palette));\n index[i] = idx;\n }\n }\n\n return index;\n}\n\nfunction nearestColorIndexRGBA(r, g, b, a, palette) {\n let k = 0;\n let mindist = 1e100;\n for (let i = 0; i < palette.length; i++) {\n const px2 = palette[i];\n const a2 = px2[3];\n let curdist = sqr(a2 - a);\n if (curdist > mindist) continue;\n const r2 = px2[0];\n curdist += sqr(r2 - r);\n if (curdist > mindist) continue;\n const g2 = px2[1];\n curdist += sqr(g2 - g);\n if (curdist > mindist) continue;\n const b2 = px2[2];\n curdist += sqr(b2 - b);\n if (curdist > mindist) continue;\n mindist = curdist;\n k = i;\n }\n return k;\n}\n\nfunction nearestColorIndexRGB(r, g, b, palette) {\n let k = 0;\n let mindist = 1e100;\n for (let i = 0; i < palette.length; i++) {\n const px2 = palette[i];\n const r2 = px2[0];\n let curdist = sqr(r2 - r);\n if (curdist > mindist) continue;\n const g2 = px2[1];\n curdist += sqr(g2 - g);\n if (curdist > mindist) continue;\n const b2 = px2[2];\n curdist += sqr(b2 - b);\n if (curdist > mindist) continue;\n mindist = curdist;\n k = i;\n }\n return k;\n}\n\nexport function snapColorsToPalette(palette, knownColors, threshold = 5) {\n if (!palette.length || !knownColors.length) return;\n\n const paletteRGB = palette.map((p) => p.slice(0, 3));\n const thresholdSq = threshold * threshold;\n const dim = palette[0].length;\n for (let i = 0; i < knownColors.length; i++) {\n let color = knownColors[i];\n if (color.length < dim) {\n // palette is RGBA, known is RGB\n color = [color[0], color[1], color[2], 0xff];\n } else if (color.length > dim) {\n // palette is RGB, known is RGBA\n color = color.slice(0, 3);\n } else {\n // make sure we always copy known colors\n color = color.slice();\n }\n const r = nearestColorIndexWithDistance(\n paletteRGB,\n color.slice(0, 3),\n euclideanDistanceSquared\n );\n const idx = r[0];\n const distanceSq = r[1];\n if (distanceSq > 0 && distanceSq <= thresholdSq) {\n palette[idx] = color;\n }\n }\n}\n\nfunction sqr(a) {\n return a * a;\n}\n\nexport function nearestColorIndex(\n colors,\n pixel,\n distanceFn = euclideanDistanceSquared\n) {\n let minDist = Infinity;\n let minDistIndex = -1;\n for (let j = 0; j < colors.length; j++) {\n const paletteColor = colors[j];\n const dist = distanceFn(pixel, paletteColor);\n if (dist < minDist) {\n minDist = dist;\n minDistIndex = j;\n }\n }\n return minDistIndex;\n}\n\nexport function nearestColorIndexWithDistance(\n colors,\n pixel,\n distanceFn = euclideanDistanceSquared\n) {\n let minDist = Infinity;\n let minDistIndex = -1;\n for (let j = 0; j < colors.length; j++) {\n const paletteColor = colors[j];\n const dist = distanceFn(pixel, paletteColor);\n if (dist < minDist) {\n minDist = dist;\n minDistIndex = j;\n }\n }\n return [minDistIndex, minDist];\n}\n\nexport function nearestColor(\n colors,\n pixel,\n distanceFn = euclideanDistanceSquared\n) {\n return colors[nearestColorIndex(colors, pixel, distanceFn)];\n}\n","import constants from \"./constants.js\";\nimport lzwEncode from \"./lzwEncode.js\";\nimport createStream from \"./stream.js\";\nimport quantize from \"./pnnquant2.js\";\n\nimport {\n prequantize,\n applyPalette,\n nearestColorIndex,\n nearestColor,\n nearestColorIndexWithDistance,\n snapColorsToPalette,\n} from \"./palettize.js\";\n\nfunction GIFEncoder(opt = {}) {\n const { initialCapacity = 4096, auto = true } = opt;\n\n // Stream all encoded data into this buffer\n const stream = createStream(initialCapacity);\n\n // Shared array data across all frames\n const HSIZE = 5003; // 80% occupancy\n const accum = new Uint8Array(256);\n const htab = new Int32Array(HSIZE);\n const codetab = new Int32Array(HSIZE);\n\n let hasInit = false;\n\n return {\n reset() {\n stream.reset();\n hasInit = false;\n },\n finish() {\n stream.writeByte(constants.trailer);\n },\n bytes() {\n return stream.bytes();\n },\n bytesView() {\n return stream.bytesView();\n },\n get buffer() {\n return stream.buffer;\n },\n get stream() {\n return stream;\n },\n writeHeader,\n writeFrame(index, width, height, opts = {}) {\n const {\n transparent = false,\n transparentIndex = 0x00,\n delay = 0,\n palette = null,\n repeat = 0, // -1=once, 0=forever, >0=count\n colorDepth = 8,\n dispose = -1,\n } = opts;\n\n let first = false;\n if (auto) {\n // In 'auto' mode, the first time we write a frame\n // we will write LSD/GCT/EXT\n if (!hasInit) {\n // have not yet init, we can consider this our first frame\n first = true;\n // in 'auto' mode, we also encode a header on first frame\n // this is different than manual mode where you must encode\n // header yoursef (or perhaps not write header altogether)\n writeHeader();\n hasInit = true;\n }\n } else {\n // in manual mode, the first frame is determined by the options only\n first = Boolean(opts.first);\n }\n\n width = Math.max(0, Math.floor(width));\n height = Math.max(0, Math.floor(height));\n\n // Write pre-frame details such as repeat count and global palette\n if (first) {\n if (!palette) {\n throw new Error(\"First frame must include a { palette } option\");\n }\n encodeLogicalScreenDescriptor(\n stream,\n width,\n height,\n palette,\n colorDepth\n );\n encodeColorTable(stream, palette);\n if (repeat >= 0) {\n encodeNetscapeExt(stream, repeat);\n }\n }\n\n const delayTime = Math.round(delay / 10);\n encodeGraphicControlExt(\n stream,\n dispose,\n delayTime,\n transparent,\n transparentIndex\n );\n\n const useLocalColorTable = Boolean(palette) && !first;\n encodeImageDescriptor(\n stream,\n width,\n height,\n useLocalColorTable ? palette : null\n );\n if (useLocalColorTable) encodeColorTable(stream, palette);\n encodePixels(\n stream,\n index,\n width,\n height,\n colorDepth,\n accum,\n htab,\n codetab\n );\n },\n };\n\n function writeHeader() {\n writeUTFBytes(stream, \"GIF89a\");\n }\n}\n\nfunction encodeGraphicControlExt(\n stream,\n dispose,\n delay,\n transparent,\n transparentIndex\n) {\n stream.writeByte(0x21); // extension introducer\n stream.writeByte(0xf9); // GCE label\n stream.writeByte(4); // data block size\n\n if (transparentIndex < 0) {\n transparentIndex = 0x00;\n transparent = false;\n }\n\n var transp, disp;\n if (!transparent) {\n transp = 0;\n disp = 0; // dispose = no action\n } else {\n transp = 1;\n disp = 2; // force clear if using transparent color\n }\n\n if (dispose >= 0) {\n disp = dispose & 7; // user override\n }\n\n disp <<= 2;\n\n const userInput = 0;\n\n // packed fields\n stream.writeByte(\n 0 | // 1:3 reserved\n disp | // 4:6 disposal\n userInput | // 7 user input - 0 = none\n transp // 8 transparency flag\n );\n\n writeUInt16(stream, delay); // delay x 1/100 sec\n stream.writeByte(transparentIndex || 0x00); // transparent color index\n stream.writeByte(0); // block terminator\n}\n\nfunction encodeLogicalScreenDescriptor(\n stream,\n width,\n height,\n palette,\n colorDepth = 8\n) {\n const globalColorTableFlag = 1;\n const sortFlag = 0;\n const globalColorTableSize = colorTableSize(palette.length) - 1;\n const fields =\n (globalColorTableFlag << 7) |\n ((colorDepth - 1) << 4) |\n (sortFlag << 3) |\n globalColorTableSize;\n const backgroundColorIndex = 0;\n const pixelAspectRatio = 0;\n writeUInt16(stream, width);\n writeUInt16(stream, height);\n stream.writeBytes([fields, backgroundColorIndex, pixelAspectRatio]);\n}\n\nfunction encodeNetscapeExt(stream, repeat) {\n stream.writeByte(0x21); // extension introducer\n stream.writeByte(0xff); // app extension label\n stream.writeByte(11); // block size\n writeUTFBytes(stream, \"NETSCAPE2.0\"); // app id + auth code\n stream.writeByte(3); // sub-block size\n stream.writeByte(1); // loop sub-block id\n writeUInt16(stream, repeat); // loop count (extra iterations, 0=repeat forever)\n stream.writeByte(0); // block terminator\n}\n\nfunction encodeColorTable(stream, palette) {\n const colorTableLength = 1 << colorTableSize(palette.length);\n for (let i = 0; i < colorTableLength; i++) {\n let color = [0, 0, 0];\n if (i < palette.length) {\n color = palette[i];\n }\n stream.writeByte(color[0]);\n stream.writeByte(color[1]);\n stream.writeByte(color[2]);\n }\n}\n\nfunction encodeImageDescriptor(stream, width, height, localPalette) {\n stream.writeByte(0x2c); // image separator\n\n writeUInt16(stream, 0); // x position\n writeUInt16(stream, 0); // y position\n writeUInt16(stream, width); // image size\n writeUInt16(stream, height);\n\n if (localPalette) {\n const interlace = 0;\n const sorted = 0;\n const palSize = colorTableSize(localPalette.length) - 1;\n // local palette\n stream.writeByte(\n 0x80 | // 1 local color table 1=yes\n interlace | // 2 interlace - 0=no\n sorted | // 3 sorted - 0=no\n 0 | // 4-5 reserved\n palSize // 6-8 size of color table\n );\n } else {\n // global palette\n stream.writeByte(0);\n }\n}\n\nfunction encodePixels(\n stream,\n index,\n width,\n height,\n colorDepth = 8,\n accum,\n htab,\n codetab\n) {\n lzwEncode(width, height, index, colorDepth, stream, accum, htab, codetab);\n}\n\n// Utilities\n\nfunction writeUInt16(stream, short) {\n stream.writeByte(short & 0xff);\n stream.writeByte((short >> 8) & 0xff);\n}\n\nfunction writeUTFBytes(stream, text) {\n for (var i = 0; i < text.length; i++) {\n stream.writeByte(text.charCodeAt(i));\n }\n}\n\nfunction colorTableSize(length) {\n return Math.max(Math.ceil(Math.log2(length)), 1);\n}\n\nexport {\n GIFEncoder,\n quantize,\n prequantize,\n applyPalette,\n nearestColorIndex,\n nearestColor,\n nearestColorIndexWithDistance,\n snapColorsToPalette,\n};\n\nexport default GIFEncoder;\n","// Ease-out reveal: alpha goes 0 -> 1 over first 70% of timeline.\nexport function textAlpha(progress: number): number {\n const p = Math.min(progress / 0.7, 1);\n return 1 - Math.pow(1 - p, 3);\n}\n","// Pulsing glow 0..1 using a sine wave over the loop.\nexport function avatarGlow(progress: number): number {\n return (Math.sin(progress * Math.PI * 2) + 1) / 2;\n}\n","// Phase 0..1 used by drawFrame to shift the background sheen.\nexport function backgroundShift(progress: number): number {\n return progress;\n}\n","import type { AnimationType } from '../types.js';\nimport type { FrameState } from '../render/drawFrame.js';\nimport { textAlpha } from './text.js';\nimport { avatarGlow } from './avatar.js';\nimport { backgroundShift } from './background.js';\n\nexport function frameStateFor(animations: AnimationType[], progress: number): FrameState {\n return {\n textAlpha: animations.includes('text') ? textAlpha(progress) : 1,\n avatarGlow: animations.includes('avatar') ? avatarGlow(progress) : 1,\n backgroundShift: animations.includes('background') ? backgroundShift(progress) : 0,\n };\n}\n","import type {\n AnimationType,\n CardOptions,\n FontOptions,\n MemberCountPosition,\n PresetName,\n Theme,\n} from './types.js';\nimport { DEFAULT_OPTIONS } from './constants.js';\nimport { PRESETS } from './presets/index.js';\nimport { WelcomeCardError } from './errors.js';\nimport { renderPNG } from './render/toPNG.js';\nimport { renderGIF } from './render/toGIF.js';\n\nexport class WelcomeCard {\n private opts: CardOptions = { ...DEFAULT_OPTIONS, font: {}, animations: [] };\n\n setPreset(preset: PresetName): this {\n if (!PRESETS[preset]) {\n throw new WelcomeCardError(\n `Unknown preset \"${preset}\". Allowed: ${Object.keys(PRESETS).join(', ')}`,\n );\n }\n this.opts.preset = preset;\n return this;\n }\n\n setUsername(username: string): this {\n this.opts.username = username;\n return this;\n }\n\n setAvatar(avatar: string | Buffer): this {\n this.opts.avatar = avatar;\n return this;\n }\n\n setSubtitle(subtitle: string): this {\n this.opts.subtitle = subtitle;\n return this;\n }\n\n setMemberCount(count: number): this {\n this.opts.memberCount = count;\n return this;\n }\n\n setMemberCountPosition(position: MemberCountPosition): this {\n this.opts.memberCountPosition = position;\n return this;\n }\n\n setBackground(background: string): this {\n this.opts.background = background;\n return this;\n }\n\n setTheme(theme: Theme): this {\n this.opts.theme = theme;\n return this;\n }\n\n setFont(font: FontOptions): this {\n this.opts.font = { ...this.opts.font, ...font };\n return this;\n }\n\n setAnimations(animations: AnimationType[]): this {\n this.opts.animations = animations;\n return this;\n }\n\n private validate(): void {\n if (!this.opts.username) {\n throw new WelcomeCardError('username is required — call .setUsername() before rendering.');\n }\n }\n\n async toPNG(): Promise<Buffer> {\n this.validate();\n return renderPNG(this.opts);\n }\n\n async toGIF(): Promise<Buffer> {\n this.validate();\n if (this.opts.animations.length === 0) {\n console.warn('[welcomecard] toGIF() called with no animations — output will be static.');\n }\n return renderGIF(this.opts);\n }\n}\n"],"mappings":"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","names":["import_canvas","import_canvas","x","import_canvas"]}
1
+ {"version":3,"sources":["../src/index.ts","../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.15_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js","../src/constants.ts","../src/assets/fonts/register.ts","../src/presets/centered.ts","../src/presets/neon.ts","../src/presets/minimal.ts","../src/presets/hero.ts","../src/presets/index.ts","../src/errors.ts","../src/render/toPNG.ts","../src/render/layout.ts","../src/assets/loadImage.ts","../src/render/drawFrame.ts","../src/render/toGIF.ts","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/constants.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/stream.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/lzwEncode.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/rgb-packing.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/pnnquant2.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/color.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/palettize.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/index.js","../src/animate/text.ts","../src/animate/avatar.ts","../src/animate/background.ts","../src/animate/index.ts","../src/WelcomeCard.ts"],"sourcesContent":["export { WelcomeCard } from './WelcomeCard.js';\nexport { WelcomeCardError } from './errors.js';\nexport type {\n CardOptions,\n Theme,\n PresetName,\n AnimationType,\n OutputFormat,\n FontOptions,\n MemberCountPosition,\n} from './types.js';\n","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","import type { CardOptions } from './types.js';\n\nexport const CARD_WIDTH = 840;\nexport const CARD_HEIGHT = 420; // 2:1 banner\n\nexport const GIF_FRAMES = 30;\nexport const GIF_DELAY_MS = 50; // ~20fps\nexport const GIF_SCALE = 0.5; // GIFs render at half size to stay under Discord upload limits\n\nexport const DEFAULT_OPTIONS: CardOptions = {\n preset: 'centered',\n theme: 'dark',\n font: {},\n animations: [],\n};\n","import { GlobalFonts } from '@napi-rs/canvas';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport { existsSync } from 'node:fs';\n\nconst here = dirname(fileURLToPath(import.meta.url));\n\n// dev/tests run from src/assets/fonts; the published build runs from dist\n// with the font copied next to it (tsup publicDir).\nconst candidates = [\n join(here, 'Poppins-Bold.ttf'),\n join(here, 'assets', 'fonts', 'Poppins-Bold.ttf'),\n join(here, '..', 'src', 'assets', 'fonts', 'Poppins-Bold.ttf'),\n];\n\nconst fontPath = candidates.find(existsSync);\nif (fontPath) {\n GlobalFonts.registerFromPath(fontPath, 'WelcomeCard');\n}\n\nexport const DEFAULT_FONT_FAMILY = 'WelcomeCard';\n","import { CARD_WIDTH, CARD_HEIGHT } from '../constants.js';\nimport type { CardOptions, MemberCountPosition } from '../types.js';\nimport { DEFAULT_FONT_FAMILY } from '../assets/fonts/register.js';\n\nconst EDGE_PAD = 24;\nconst TOP_BASELINE = 36; // baseline y for top-anchored text\n\nexport function isHexBackground(background: string | undefined): background is string {\n return typeof background === 'string' && /^#[0-9a-fA-F]{3,8}$/.test(background);\n}\n\nexport function resolveBackgroundColor(background: string | undefined, fallback: string): string {\n return isHexBackground(background) ? background : fallback;\n}\n\nexport function resolvePosition(\n position: MemberCountPosition | undefined,\n width: number,\n height: number,\n): { x: number; y: number; align: 'left' | 'center' | 'right' } {\n const pos = position === undefined || position === 'corner' ? 'bottom-right' : position;\n const x = { left: EDGE_PAD, center: width / 2, right: width - EDGE_PAD } as const;\n const y = { top: TOP_BASELINE, center: height / 2, bottom: height - EDGE_PAD } as const;\n switch (pos) {\n case 'top-left': return { x: x.left, y: y.top, align: 'left' };\n case 'top-center': return { x: x.center, y: y.top, align: 'center' };\n case 'top-right': return { x: x.right, y: y.top, align: 'right' };\n case 'center-left': return { x: x.left, y: y.center, align: 'left' };\n case 'center': return { x: x.center, y: y.center, align: 'center' };\n case 'center-right': return { x: x.right, y: y.center, align: 'right' };\n case 'bottom-left': return { x: x.left, y: y.bottom, align: 'left' };\n case 'bottom-center': return { x: x.center, y: y.bottom, align: 'center' };\n case 'bottom-right': return { x: x.right, y: y.bottom, align: 'right' };\n default: {\n const _exhausted: never = pos;\n throw new Error(`Unhandled memberCountPosition: \"${_exhausted as string}\"`);\n }\n }\n}\n\nexport interface TextBox {\n text: string;\n x: number;\n y: number;\n size: number;\n color: string;\n family: string;\n align: 'left' | 'center' | 'right';\n}\n\nexport interface LayoutResult {\n width: number;\n height: number;\n backgroundColor: string;\n background?: string;\n avatar: { x: number; y: number; size: number; ringColor: string; source?: string | Buffer };\n username: TextBox;\n subtitle?: TextBox;\n memberCount?: TextBox;\n}\n\nexport function centeredLayout(opts: CardOptions): LayoutResult {\n const width = CARD_WIDTH;\n const height = CARD_HEIGHT;\n const accent = opts.theme === 'dark' ? '#89b4fa' : '#1e66f5';\n const bgColor = resolveBackgroundColor(\n opts.background,\n opts.theme === 'dark' ? '#1e1e2e' : '#eff1f5',\n );\n const textColor = opts.font.color ?? (opts.theme === 'dark' ? '#ffffff' : '#11111b');\n const family = opts.font.family ?? DEFAULT_FONT_FAMILY;\n\n const avatarSize = 170;\n const avatarY = 56;\n\n return {\n width,\n height,\n backgroundColor: bgColor,\n background: isHexBackground(opts.background) ? undefined : opts.background,\n avatar: {\n x: width / 2 - avatarSize / 2,\n y: avatarY,\n size: avatarSize,\n ringColor: accent,\n source: opts.avatar,\n },\n username: {\n text: opts.username ?? '',\n x: width / 2,\n y: avatarY + avatarSize + 66,\n size: opts.font.size ?? 56,\n color: textColor,\n family,\n align: 'center',\n },\n subtitle: opts.subtitle\n ? {\n text: opts.subtitle,\n x: width / 2,\n y: avatarY + avatarSize + 122,\n size: opts.font.subtitleSize ?? Math.round((opts.font.size ?? 56) * 0.61),\n color: textColor,\n family,\n align: 'center',\n }\n : undefined,\n memberCount:\n opts.memberCount !== undefined\n ? {\n text: `MEMBER #${opts.memberCount}`,\n // centered preset: everything centered by default, count included\n ...resolvePosition(opts.memberCountPosition ?? 'bottom-center', width, height),\n size: 20,\n color: textColor,\n family,\n }\n : undefined,\n };\n}\n","import { centeredLayout, resolveBackgroundColor } from './centered.js';\nimport type { CardOptions } from '../types.js';\nimport type { LayoutResult } from './centered.js';\n\nexport function neonLayout(opts: CardOptions): LayoutResult {\n const base = centeredLayout(opts);\n return {\n ...base,\n backgroundColor: resolveBackgroundColor(opts.background, '#0b0b1a'),\n avatar: { ...base.avatar, ringColor: '#00ffd5' },\n username: { ...base.username, color: opts.font.color ?? '#00ffd5' },\n };\n}\n","import { centeredLayout, resolveBackgroundColor } from './centered.js';\nimport type { CardOptions } from '../types.js';\nimport type { LayoutResult } from './centered.js';\n\nexport function minimalLayout(opts: CardOptions): LayoutResult {\n const base = centeredLayout(opts);\n return {\n ...base,\n backgroundColor: resolveBackgroundColor(opts.background, '#ffffff'),\n avatar: { ...base.avatar, ringColor: '#222222' },\n username: { ...base.username, color: opts.font.color ?? '#111111' },\n subtitle: base.subtitle ? { ...base.subtitle, color: '#555555' } : undefined,\n };\n}\n","import { centeredLayout, resolvePosition, resolveBackgroundColor } from './centered.js';\nimport type { CardOptions } from '../types.js';\nimport type { LayoutResult } from './centered.js';\n\n// Hero: avatar shifted left, text left-aligned beside it.\nexport function heroLayout(opts: CardOptions): LayoutResult {\n const base = centeredLayout(opts);\n const avatarX = 60;\n const textX = avatarX + base.avatar.size + 40;\n return {\n ...base,\n backgroundColor: resolveBackgroundColor(\n opts.background,\n opts.theme === 'dark' ? '#1b1f2a' : '#e8ecf4',\n ),\n avatar: { ...base.avatar, x: avatarX, y: base.height / 2 - base.avatar.size / 2 },\n username: { ...base.username, x: textX, y: base.height / 2 - 12, align: 'left' },\n subtitle: base.subtitle\n ? { ...base.subtitle, x: textX, y: base.height / 2 + 42, align: 'left' }\n : undefined,\n memberCount: base.memberCount\n ? // hero is asymmetric — default the count to the corner, not bottom-center\n {\n ...base.memberCount,\n ...resolvePosition(opts.memberCountPosition ?? 'bottom-right', base.width, base.height),\n }\n : undefined,\n };\n}\n","import type { CardOptions, PresetName } from '../types.js';\nimport { centeredLayout, type LayoutResult } from './centered.js';\nimport { neonLayout } from './neon.js';\nimport { minimalLayout } from './minimal.js';\nimport { heroLayout } from './hero.js';\n\nexport type { LayoutResult, TextBox } from './centered.js';\nexport type LayoutFn = (opts: CardOptions) => LayoutResult;\n\nexport const PRESETS: Record<PresetName, LayoutFn> = {\n centered: centeredLayout,\n neon: neonLayout,\n minimal: minimalLayout,\n hero: heroLayout,\n};\n","export class WelcomeCardError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WelcomeCardError';\n }\n}\n","import { createCanvas } from '@napi-rs/canvas';\nimport '../assets/fonts/register.js';\nimport type { CardOptions } from '../types.js';\nimport { layout } from './layout.js';\nimport { drawFrame, STATIC_FRAME } from './drawFrame.js';\n\nexport async function renderPNG(opts: CardOptions): Promise<Buffer> {\n const l = layout(opts);\n const canvas = createCanvas(l.width, l.height);\n const ctx = canvas.getContext('2d');\n await drawFrame(ctx, l, STATIC_FRAME);\n return canvas.toBuffer('image/png');\n}\n","import type { CardOptions } from '../types.js';\nimport { PRESETS, type LayoutResult } from '../presets/index.js';\nimport { WelcomeCardError } from '../errors.js';\n\nexport function layout(opts: CardOptions): LayoutResult {\n const fn = PRESETS[opts.preset];\n if (!fn) {\n throw new WelcomeCardError(\n `Unknown preset \"${opts.preset}\". Allowed: ${Object.keys(PRESETS).join(', ')}`,\n );\n }\n return fn(opts);\n}\n","import { loadImage, createCanvas, type Image } from '@napi-rs/canvas';\n\nconst MAX_CACHE = 256;\n\nfunction boundedSet<K>(map: Map<K, Image>, key: K, value: Image): void {\n if (map.size >= MAX_CACHE) {\n map.delete(map.keys().next().value!);\n }\n map.set(key, value);\n}\n\n// Cache so GIF rendering (N frames) fetches each URL/Buffer only once.\nconst cache = new Map<string | Buffer, Image>();\nconst solidCache = new Map<string, Image>();\n\nasync function solidImage(color: string, w: number, h: number): Promise<Image> {\n const key = `${color}:${w}x${h}`;\n const hit = solidCache.get(key);\n if (hit) return hit;\n const canvas = createCanvas(w, h);\n const ctx = canvas.getContext('2d');\n ctx.fillStyle = color;\n ctx.fillRect(0, 0, w, h);\n const img = await loadImage(canvas.toBuffer('image/png'));\n boundedSet(solidCache, key, img);\n return img;\n}\n\nexport async function loadImageOrFallback(\n source: string | Buffer | undefined,\n fallbackColor: string,\n w = 256,\n h = 256,\n): Promise<Image> {\n if (source === undefined) return solidImage(fallbackColor, w, h);\n const hit = cache.get(source);\n if (hit) return hit;\n try {\n const img = await loadImage(source);\n boundedSet(cache, source, img);\n return img;\n } catch {\n return solidImage(fallbackColor, w, h);\n }\n}\n","import type { SKRSContext2D } from '@napi-rs/canvas';\nimport type { LayoutResult, TextBox } from '../presets/index.js';\nimport { loadImageOrFallback } from '../assets/loadImage.js';\n\nexport interface FrameState {\n textAlpha: number; // 0..1 reveal for text\n avatarGlow: number; // 0..1 glow intensity\n backgroundShift: number; // 0..1 gradient phase\n}\n\nexport const STATIC_FRAME: FrameState = { textAlpha: 1, avatarGlow: 1, backgroundShift: 0 };\n\nfunction drawText(ctx: SKRSContext2D, box: TextBox, alpha: number) {\n ctx.save();\n ctx.globalAlpha = alpha;\n ctx.fillStyle = box.color;\n ctx.textAlign = box.align;\n ctx.textBaseline = 'alphabetic';\n ctx.font = `${box.size}px ${box.family}`;\n ctx.fillText(box.text, box.x, box.y);\n ctx.restore();\n}\n\nexport async function drawFrame(\n ctx: SKRSContext2D,\n l: LayoutResult,\n state: FrameState,\n): Promise<void> {\n // background\n ctx.fillStyle = l.backgroundColor;\n ctx.fillRect(0, 0, l.width, l.height);\n if (l.background !== undefined) {\n const bg = await loadImageOrFallback(l.background, l.backgroundColor, l.width, l.height);\n ctx.drawImage(bg, 0, 0, l.width, l.height);\n }\n if (state.backgroundShift > 0) {\n // diagonal sheen sliding across the card; phase 0..1 loops with the GIF\n const x = (state.backgroundShift * 2 - 1) * l.width * 2;\n const g = ctx.createLinearGradient(x, 0, x + l.width, l.height);\n g.addColorStop(0, 'rgba(255,255,255,0)');\n g.addColorStop(0.5, 'rgba(255,255,255,0.10)');\n g.addColorStop(1, 'rgba(255,255,255,0)');\n ctx.fillStyle = g;\n ctx.fillRect(0, 0, l.width, l.height);\n }\n\n // avatar (circular) with glow ring\n const { x, y, size, ringColor } = l.avatar;\n const cx = x + size / 2;\n const cy = y + size / 2;\n ctx.save();\n ctx.shadowColor = ringColor;\n ctx.shadowBlur = 10 + state.avatarGlow * 25;\n ctx.lineWidth = 6;\n ctx.strokeStyle = ringColor;\n ctx.beginPath();\n ctx.arc(cx, cy, size / 2 + 3, 0, Math.PI * 2);\n ctx.stroke();\n ctx.restore();\n\n const avatarImg = await loadImageOrFallback(l.avatar.source, ringColor, size, size);\n ctx.save();\n ctx.beginPath();\n ctx.arc(cx, cy, size / 2, 0, Math.PI * 2);\n ctx.clip();\n ctx.drawImage(avatarImg, x, y, size, size);\n ctx.restore();\n\n // text\n drawText(ctx, l.username, state.textAlpha);\n if (l.subtitle) drawText(ctx, l.subtitle, state.textAlpha);\n if (l.memberCount) drawText(ctx, l.memberCount, state.textAlpha);\n}\n","import { createCanvas } from '@napi-rs/canvas';\nimport * as gifencMod from 'gifenc';\n// gifenc ships dual CJS/ESM with inconsistent interop — named exports may live on the\n// namespace (vite/bundlers) or behind .default (node CJS-ESM interop). Pick whichever has them.\ntype Gifenc = typeof import('gifenc');\nconst { GIFEncoder, quantize, applyPalette } =\n 'GIFEncoder' in gifencMod ? (gifencMod as Gifenc) : (gifencMod as { default: Gifenc }).default;\nimport '../assets/fonts/register.js';\nimport type { CardOptions } from '../types.js';\nimport { GIF_FRAMES, GIF_DELAY_MS, GIF_SCALE } from '../constants.js';\nimport { layout } from './layout.js';\nimport { drawFrame } from './drawFrame.js';\nimport { frameStateFor } from '../animate/index.js';\n\nexport async function renderGIF(opts: CardOptions): Promise<Buffer> {\n const l = layout(opts);\n // draw at full size, encode at half size: smaller files, under Discord limits\n const canvas = createCanvas(l.width, l.height);\n const ctx = canvas.getContext('2d');\n const gw = Math.round(l.width * GIF_SCALE);\n const gh = Math.round(l.height * GIF_SCALE);\n const out = createCanvas(gw, gh);\n const outCtx = out.getContext('2d');\n const enc = GIFEncoder();\n\n const frames = opts.animations.length === 0 ? 1 : GIF_FRAMES;\n\n // For animated GIFs, build palette from progress=0.5: sheen peaks there so\n // highlight colours absent from frame 0 are represented. For static (1 frame),\n // skip the pre-render and derive the palette from the single rendered frame.\n let palette: ReturnType<typeof quantize> | undefined;\n if (frames > 1) {\n const paletteState = frameStateFor(opts.animations, 0.5);\n await drawFrame(ctx, l, paletteState);\n outCtx.drawImage(canvas, 0, 0, gw, gh);\n palette = quantize(outCtx.getImageData(0, 0, gw, gh).data, 256);\n }\n\n for (let i = 0; i < frames; i++) {\n const progress = frames === 1 ? 0 : i / frames;\n const state = frameStateFor(opts.animations, progress);\n await drawFrame(ctx, l, state);\n outCtx.drawImage(canvas, 0, 0, gw, gh);\n const { data } = outCtx.getImageData(0, 0, gw, gh);\n palette ??= quantize(data, 256);\n const index = applyPalette(data, palette);\n enc.writeFrame(index, gw, gh, { palette, delay: GIF_DELAY_MS });\n }\n enc.finish();\n return Buffer.from(enc.bytes());\n}\n","export default {\n signature: \"GIF\",\n version: \"89a\",\n trailer: 0x3B,\n extensionIntroducer: 0x21,\n applicationExtensionLabel: 0xFF,\n graphicControlExtensionLabel: 0xF9,\n imageSeparator: 0x2C,\n // Header\n signatureSize: 3,\n versionSize: 3,\n globalColorTableFlagMask: 0b10000000,\n colorResolutionMask: 0b01110000,\n sortFlagMask: 0b00001000,\n globalColorTableSizeMask: 0b00000111,\n // Application extension\n applicationIdentifierSize: 8,\n applicationAuthCodeSize: 3,\n // Graphic control extension\n disposalMethodMask: 0b00011100,\n userInputFlagMask: 0b00000010,\n transparentColorFlagMask: 0b00000001,\n // Image descriptor\n localColorTableFlagMask: 0b10000000,\n interlaceFlagMask: 0b01000000,\n idSortFlagMask: 0b00100000,\n localColorTableSizeMask: 0b00000111\n}\n","export default function createStream(initialCapacity = 256) {\n let cursor = 0;\n let contents = new Uint8Array(initialCapacity);\n\n return {\n get buffer() {\n return contents.buffer;\n },\n reset() {\n cursor = 0;\n },\n bytesView() {\n return contents.subarray(0, cursor);\n },\n bytes() {\n return contents.slice(0, cursor);\n },\n writeByte(byte) {\n expand(cursor + 1);\n contents[cursor] = byte;\n cursor++;\n },\n writeBytes(data, offset = 0, byteLength = data.length) {\n expand(cursor + byteLength);\n for (let i = 0; i < byteLength; i++) {\n contents[cursor++] = data[i + offset];\n }\n },\n writeBytesView(data, offset = 0, byteLength = data.byteLength) {\n expand(cursor + byteLength);\n contents.set(data.subarray(offset, offset + byteLength), cursor);\n cursor += byteLength;\n },\n };\n\n function expand(newCapacity) {\n var prevCapacity = contents.length;\n if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough.\n // Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity.\n // For small filesizes (<1MB), perform size*2 geometric increase, but for large sizes, do a much more conservative size*1.125 increase to\n // avoid overshooting the allocation cap by a very large margin.\n var CAPACITY_DOUBLING_MAX = 1024 * 1024;\n newCapacity = Math.max(\n newCapacity,\n (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) >>>\n 0\n );\n if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.\n const oldContents = contents;\n contents = new Uint8Array(newCapacity); // Allocate new storage.\n if (cursor > 0) contents.set(oldContents.subarray(0, cursor), 0);\n }\n}\n","/*\n LZWEncoder.js\n Authors\n Kevin Weiner (original Java version - kweiner@fmsware.com)\n Thibault Imbert (AS3 version - bytearray.org)\n Johan Nordberg (JS version - code@johan-nordberg.com)\n Acknowledgements\n GIFCOMPR.C - GIF Image compression routines\n Lempel-Ziv compression based on 'compress'. GIF modifications by\n David Rowley (mgardi@watdcsu.waterloo.edu)\n GIF Image compression - modified 'compress'\n Based on: compress.c - File compression ala IEEE Computer, June 1984.\n By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)\n Jim McKie (decvax!mcvax!jim)\n Steve Davies (decvax!vax135!petsd!peora!srd)\n Ken Turkowski (decvax!decwrl!turtlevax!ken)\n James A. Woods (decvax!ihnp4!ames!jaw)\n Joe Orost (decvax!vax135!petsd!joe)\n Matt DesLauriers (@mattdesl - V8/JS optimizations)\n Mathieu Henri (@p01 - JS optimization)\n*/\n\nimport createStream from \"./stream.js\";\n\nconst EOF = -1;\nconst BITS = 12;\nconst DEFAULT_HSIZE = 5003; // 80% occupancy\nconst MASKS = [\n 0x0000,\n 0x0001,\n 0x0003,\n 0x0007,\n 0x000f,\n 0x001f,\n 0x003f,\n 0x007f,\n 0x00ff,\n 0x01ff,\n 0x03ff,\n 0x07ff,\n 0x0fff,\n 0x1fff,\n 0x3fff,\n 0x7fff,\n 0xffff,\n];\n\nfunction lzwEncode(\n width,\n height,\n pixels,\n colorDepth,\n outStream = createStream(512),\n accum = new Uint8Array(256),\n htab = new Int32Array(DEFAULT_HSIZE),\n codetab = new Int32Array(DEFAULT_HSIZE)\n) {\n const hsize = htab.length;\n const initCodeSize = Math.max(2, colorDepth);\n\n accum.fill(0);\n codetab.fill(0);\n htab.fill(-1);\n\n let cur_accum = 0;\n let cur_bits = 0;\n\n // Algorithm: use open addressing double hashing (no chaining) on the\n // prefix code / next character combination. We do a variant of Knuth's\n // algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime\n // secondary probe. Here, the modular division first probe is gives way\n // to a faster exclusive-or manipulation. Also do block compression with\n // an adaptive reset, whereby the code table is cleared when the compression\n // ratio decreases, but after the table fills. The variable-length output\n // codes are re-sized at this point, and a special CLEAR code is generated\n // for the decompressor. Late addition: construct the table according to\n // file size for noticeable speed improvement on small files. Please direct\n // questions about this implementation to ames!jaw.\n\n // compress and write the pixel data\n const init_bits = initCodeSize + 1;\n\n // Set up the globals: g_init_bits - initial number of bits\n const g_init_bits = init_bits;\n\n // Set up the necessary values\n\n // block compression parameters -- after all codes are used up,\n // and compression rate changes, start over.\n let clear_flg = false;\n let n_bits = g_init_bits;\n let maxcode = (1 << n_bits) - 1;\n\n const ClearCode = 1 << (init_bits - 1);\n const EOFCode = ClearCode + 1;\n let free_ent = ClearCode + 2;\n let a_count = 0; // clear packet\n\n let ent = pixels[0];\n\n let hshift = 0;\n for (let fcode = hsize; fcode < 65536; fcode *= 2) {\n ++hshift;\n }\n hshift = 8 - hshift; // set hash code range bound\n\n outStream.writeByte(initCodeSize); // write \"initial code size\" byte\n\n output(ClearCode);\n\n const length = pixels.length;\n for (let idx = 1; idx < length; idx++) {\n next_block: {\n const c = pixels[idx];\n const fcode = (c << BITS) + ent;\n let i = (c << hshift) ^ ent; // xor hashing\n if (htab[i] === fcode) {\n ent = codetab[i];\n break next_block;\n }\n\n const disp = i === 0 ? 1 : hsize - i; // secondary hash (after G. Knott)\n while (htab[i] >= 0) {\n // non-empty slot\n i -= disp;\n if (i < 0) i += hsize;\n if (htab[i] === fcode) {\n ent = codetab[i];\n break next_block;\n }\n }\n output(ent);\n ent = c;\n if (free_ent < 1 << BITS) {\n codetab[i] = free_ent++; // code -> hashtable\n htab[i] = fcode;\n } else {\n // Clear out the hash table\n // table clear for block compress\n htab.fill(-1);\n free_ent = ClearCode + 2;\n clear_flg = true;\n output(ClearCode);\n }\n }\n }\n\n // Put out the final code.\n output(ent);\n output(EOFCode);\n\n outStream.writeByte(0); // write block terminator\n return outStream.bytesView();\n\n function output(code) {\n cur_accum &= MASKS[cur_bits];\n\n if (cur_bits > 0) cur_accum |= code << cur_bits;\n else cur_accum = code;\n\n cur_bits += n_bits;\n\n while (cur_bits >= 8) {\n // Add a character to the end of the current packet, and if it is 254\n // characters, flush the packet to disk.\n accum[a_count++] = cur_accum & 0xff;\n if (a_count >= 254) {\n outStream.writeByte(a_count);\n outStream.writeBytesView(accum, 0, a_count);\n a_count = 0;\n }\n cur_accum >>= 8;\n cur_bits -= 8;\n }\n\n // If the next entry is going to be too big for the code size,\n // then increase it, if possible.\n if (free_ent > maxcode || clear_flg) {\n if (clear_flg) {\n n_bits = g_init_bits;\n maxcode = (1 << n_bits) - 1;\n clear_flg = false;\n } else {\n ++n_bits;\n maxcode = n_bits === BITS ? (1 << n_bits) : (1 << n_bits) - 1;\n }\n }\n\n if (code == EOFCode) {\n // At EOF, write the rest of the buffer.\n while (cur_bits > 0) {\n // Add a character to the end of the current packet, and if it is 254\n // characters, flush the packet to disk.\n accum[a_count++] = cur_accum & 0xff;\n if (a_count >= 254) {\n outStream.writeByte(a_count);\n outStream.writeBytesView(accum, 0, a_count);\n a_count = 0;\n }\n cur_accum >>= 8;\n cur_bits -= 8;\n }\n // Flush the packet to disk, and reset the accumulator\n if (a_count > 0) {\n outStream.writeByte(a_count);\n outStream.writeBytesView(accum, 0, a_count);\n a_count = 0;\n }\n }\n }\n}\n\nexport default lzwEncode;\n","export function uint32_to_rgba(color) {\n var a = (color >> 24) & 0xff;\n var b = (color >> 16) & 0xff;\n var g = (color >> 8) & 0xff;\n var r = color & 0xff;\n return [r, g, b, a];\n}\n\nexport function rgba_to_uint32(r, g, b, a) {\n return (a << 24) | (b << 16) | (g << 8) | r;\n}\n\nexport function rgb888_to_rgb565(r, g, b) {\n return ((r << 8) & 0xf800) | ((g << 2) & 0x03e0) | (b >> 3);\n}\n\nexport function rgba8888_to_rgba4444(r, g, b, a) {\n return (r >> 4) | (g & 0xf0) | ((b & 0xf0) << 4) | ((a & 0xf0) << 8);\n}\n\nexport function rgb888_to_rgb444(r, g, b) {\n return ((r >> 4) << 8) | (g & 0xf0) | (b >> 4);\n}\n\n// Alternative 565 ?\n// return ((r & 0xf8) << 8) + ((g & 0xfc) << 3) + (b >> 3);\n\n// Alternative 4444 ?\n// ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | (g & 0xf0) | (b >> 4);\n","// Modified from:\n// https://github.com/mcychan/PnnQuant.js/blob/master/src/pnnquant.js\n\n/* Fast pairwise nearest neighbor based algorithm for multilevel thresholding\nCopyright (C) 2004-2019 Mark Tyler and Dmitry Groshev\nCopyright (c) 2018-2021 Miller Cy Chan\n* error measure; time used is proportional to number of bins squared - WJ */\n\nimport {\n rgb888_to_rgb565,\n rgb888_to_rgb444,\n rgba8888_to_rgba4444,\n} from \"./rgb-packing.js\";\n\nfunction clamp(value, min, max) {\n return value < min ? min : value > max ? max : value;\n}\n\nfunction sqr(value) {\n return value * value;\n}\n\nfunction find_nn(bins, idx, hasAlpha) {\n var nn = 0;\n var err = 1e100;\n\n const bin1 = bins[idx];\n const n1 = bin1.cnt;\n const wa = bin1.ac;\n const wr = bin1.rc;\n const wg = bin1.gc;\n const wb = bin1.bc;\n for (var i = bin1.fw; i != 0; i = bins[i].fw) {\n const bin = bins[i];\n const n2 = bin.cnt;\n const nerr2 = (n1 * n2) / (n1 + n2);\n if (nerr2 >= err) continue;\n\n var nerr = 0;\n if (hasAlpha) {\n nerr += nerr2 * sqr(bin.ac - wa);\n if (nerr >= err) continue;\n }\n\n nerr += nerr2 * sqr(bin.rc - wr);\n if (nerr >= err) continue;\n\n nerr += nerr2 * sqr(bin.gc - wg);\n if (nerr >= err) continue;\n\n nerr += nerr2 * sqr(bin.bc - wb);\n if (nerr >= err) continue;\n err = nerr;\n nn = i;\n }\n bin1.err = err;\n bin1.nn = nn;\n}\n\nfunction create_bin() {\n return {\n ac: 0,\n rc: 0,\n gc: 0,\n bc: 0,\n cnt: 0,\n nn: 0,\n fw: 0,\n bk: 0,\n tm: 0,\n mtm: 0,\n err: 0,\n };\n}\n\nfunction bin_add_rgb(bin, r, g, b) {\n bin.rc += r;\n bin.gc += g;\n bin.bc += b;\n bin.cnt++;\n}\n\nfunction create_bin_list(data, format) {\n const bincount = format === \"rgb444\" ? 4096 : 65536;\n const bins = new Array(bincount);\n const size = data.length;\n\n /* Build histogram */\n // Note: Instead of introducing branching/conditions\n // within a very hot per-pixel iteration, we just duplicate the code\n // for each new condition\n if (format === \"rgba4444\") {\n for (let i = 0; i < size; ++i) {\n const color = data[i];\n const a = (color >> 24) & 0xff;\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n\n // reduce to rgb4444 16-bit uint\n const index = rgba8888_to_rgba4444(r, g, b, a);\n let bin = index in bins ? bins[index] : (bins[index] = create_bin());\n bin.rc += r;\n bin.gc += g;\n bin.bc += b;\n bin.ac += a;\n bin.cnt++;\n }\n }\n \n else if (format === \"rgb444\") {\n for (let i = 0; i < size; ++i) {\n const color = data[i];\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n\n // reduce to rgb444 12-bit uint\n const index = rgb888_to_rgb444(r, g, b);\n let bin = index in bins ? bins[index] : (bins[index] = create_bin());\n bin.rc += r;\n bin.gc += g;\n bin.bc += b;\n bin.cnt++;\n }\n } else {\n for (let i = 0; i < size; ++i) {\n const color = data[i];\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n\n // reduce to rgb565 16-bit uint\n const index = rgb888_to_rgb565(r, g, b);\n let bin = index in bins ? bins[index] : (bins[index] = create_bin());\n bin.rc += r;\n bin.gc += g;\n bin.bc += b;\n bin.cnt++;\n }\n }\n return bins;\n}\n\nexport default function quantize(rgba, maxColors, opts = {}) {\n const {\n format = \"rgb565\",\n clearAlpha = true,\n clearAlphaColor = 0x00,\n clearAlphaThreshold = 0,\n oneBitAlpha = false,\n } = opts;\n\n if (!rgba || !rgba.buffer) {\n throw new Error('quantize() expected RGBA Uint8Array data');\n }\n if (!(rgba instanceof Uint8Array) && !(rgba instanceof Uint8ClampedArray)) {\n throw new Error('quantize() expected RGBA Uint8Array data');\n }\n \n const data = new Uint32Array(rgba.buffer);\n\n let useSqrt = opts.useSqrt !== false;\n\n // format can be:\n // rgb565 (default)\n // rgb444\n // rgba4444\n\n const hasAlpha = format === \"rgba4444\";\n const bins = create_bin_list(data, format);\n const bincount = bins.length;\n const bincountMinusOne = bincount - 1;\n const heap = new Uint32Array(bincount + 1);\n\n /* Cluster nonempty bins at one end of array */\n var maxbins = 0;\n for (var i = 0; i < bincount; ++i) {\n const bin = bins[i];\n if (bin != null) {\n var d = 1.0 / bin.cnt;\n if (hasAlpha) bin.ac *= d;\n bin.rc *= d;\n bin.gc *= d;\n bin.bc *= d;\n bins[maxbins++] = bin;\n }\n }\n\n if (sqr(maxColors) / maxbins < 0.022) {\n useSqrt = false;\n }\n\n var i = 0;\n for (; i < maxbins - 1; ++i) {\n bins[i].fw = i + 1;\n bins[i + 1].bk = i;\n if (useSqrt) bins[i].cnt = Math.sqrt(bins[i].cnt);\n }\n if (useSqrt) bins[i].cnt = Math.sqrt(bins[i].cnt);\n\n var h, l, l2;\n /* Initialize nearest neighbors and build heap of them */\n for (i = 0; i < maxbins; ++i) {\n find_nn(bins, i, false);\n /* Push slot on heap */\n var err = bins[i].err;\n for (l = ++heap[0]; l > 1; l = l2) {\n l2 = l >> 1;\n if (bins[(h = heap[l2])].err <= err) break;\n heap[l] = h;\n }\n heap[l] = i;\n }\n\n /* Merge bins which increase error the least */\n var extbins = maxbins - maxColors;\n for (i = 0; i < extbins; ) {\n var tb;\n /* Use heap to find which bins to merge */\n for (;;) {\n var b1 = heap[1];\n tb = bins[b1]; /* One with least error */\n /* Is stored error up to date? */\n if (tb.tm >= tb.mtm && bins[tb.nn].mtm <= tb.tm) break;\n if (tb.mtm == bincountMinusOne)\n /* Deleted node */ b1 = heap[1] = heap[heap[0]--];\n /* Too old error value */ else {\n find_nn(bins, b1, false);\n tb.tm = i;\n }\n /* Push slot down */\n var err = bins[b1].err;\n for (l = 1; (l2 = l + l) <= heap[0]; l = l2) {\n if (l2 < heap[0] && bins[heap[l2]].err > bins[heap[l2 + 1]].err) l2++;\n if (err <= bins[(h = heap[l2])].err) break;\n heap[l] = h;\n }\n heap[l] = b1;\n }\n\n /* Do a merge */\n var nb = bins[tb.nn];\n var n1 = tb.cnt;\n var n2 = nb.cnt;\n var d = 1.0 / (n1 + n2);\n if (hasAlpha) tb.ac = d * (n1 * tb.ac + n2 * nb.ac);\n tb.rc = d * (n1 * tb.rc + n2 * nb.rc);\n tb.gc = d * (n1 * tb.gc + n2 * nb.gc);\n tb.bc = d * (n1 * tb.bc + n2 * nb.bc);\n tb.cnt += nb.cnt;\n tb.mtm = ++i;\n\n /* Unchain deleted bin */\n bins[nb.bk].fw = nb.fw;\n bins[nb.fw].bk = nb.bk;\n nb.mtm = bincountMinusOne;\n }\n\n // let palette = new Uint32Array(maxColors);\n let palette = [];\n\n /* Fill palette */\n var k = 0;\n for (i = 0; ; ++k) {\n let r = clamp(Math.round(bins[i].rc), 0, 0xff);\n let g = clamp(Math.round(bins[i].gc), 0, 0xff);\n let b = clamp(Math.round(bins[i].bc), 0, 0xff);\n\n let a = 0xff;\n if (hasAlpha) {\n a = clamp(Math.round(bins[i].ac), 0, 0xff);\n if (oneBitAlpha) {\n const threshold = typeof oneBitAlpha === \"number\" ? oneBitAlpha : 127;\n a = a <= threshold ? 0x00 : 0xff;\n }\n if (clearAlpha && a <= clearAlphaThreshold) {\n r = g = b = clearAlphaColor;\n a = 0x00;\n }\n }\n\n const color = hasAlpha ? [r, g, b, a] : [r, g, b];\n const exists = existsInPalette(palette, color);\n if (!exists) palette.push(color);\n if ((i = bins[i].fw) == 0) break;\n }\n\n return palette;\n}\n\nfunction existsInPalette(palette, color) {\n for (let i = 0; i < palette.length; i++) {\n const p = palette[i];\n let matchesRGB =\n p[0] === color[0] && p[1] === color[1] && p[2] === color[2];\n let matchesAlpha =\n p.length >= 4 && color.length >= 4 ? p[3] === color[3] : true;\n if (matchesRGB && matchesAlpha) return true;\n }\n return false;\n}\n\n// TODO: Further 'clean' palette by merging nearly-identical colors?\n","function rgb2y(r, g, b) {\n return r * 0.29889531 + g * 0.58662247 + b * 0.11448223;\n}\nfunction rgb2i(r, g, b) {\n return r * 0.59597799 - g * 0.2741761 - b * 0.32180189;\n}\nfunction rgb2q(r, g, b) {\n return r * 0.21147017 - g * 0.52261711 + b * 0.31114694;\n}\n\nexport function colorDifferenceYIQSquared(yiqA, yiqB) {\n const y = yiqA[0] - yiqB[0];\n const i = yiqA[1] - yiqB[1];\n const q = yiqA[2] - yiqB[2];\n const a = alpha(yiqA) - alpha(yiqB);\n return y * y * 0.5053 + i * i * 0.299 + q * q * 0.1957 + a * a;\n}\n\nfunction alpha(array) {\n return array[3] != null ? array[3] : 0xff;\n}\n\nexport function colorDifferenceYIQ(yiqA, yiqB) {\n return Math.sqrt(colorDifferenceYIQSquared(yiqA, yiqB));\n}\n\nexport function colorDifferenceRGBToYIQSquared(rgb1, rgb2) {\n const [r1, g1, b1] = rgb1;\n const [r2, g2, b2] = rgb2;\n const y = rgb2y(r1, g1, b1) - rgb2y(r2, g2, b2),\n i = rgb2i(r1, g1, b1) - rgb2i(r2, g2, b2),\n q = rgb2q(r1, g1, b1) - rgb2q(r2, g2, b2);\n const a = alpha(rgb1) - alpha(rgb2);\n return y * y * 0.5053 + i * i * 0.299 + q * q * 0.1957 + a * a;\n}\n\nexport function colorDifferenceRGBToYIQ(rgb1, rgb2) {\n return Math.sqrt(colorDifferenceRGBToYIQSquared(rgb1, rgb2));\n}\n\nexport function euclideanDistanceSquared(a, b) {\n var sum = 0;\n var n;\n for (n = 0; n < a.length; n++) {\n const dx = a[n] - b[n];\n sum += dx * dx;\n }\n return sum;\n}\n\nexport function euclideanDistance(a, b) {\n return Math.sqrt(euclideanDistanceSquared(a, b));\n}\n","import {\n rgb888_to_rgb444,\n rgb888_to_rgb565,\n rgba8888_to_rgba4444,\n} from \"./rgb-packing.js\";\n\nimport { euclideanDistanceSquared } from \"./color.js\";\n\nfunction roundStep(byte, step) {\n return step > 1 ? Math.round(byte / step) * step : byte;\n}\n\nexport function prequantize(\n rgba,\n { roundRGB = 5, roundAlpha = 10, oneBitAlpha = null } = {}\n) {\n const data = new Uint32Array(rgba.buffer);\n for (let i = 0; i < data.length; i++) {\n const color = data[i];\n let a = (color >> 24) & 0xff;\n let b = (color >> 16) & 0xff;\n let g = (color >> 8) & 0xff;\n let r = color & 0xff;\n\n a = roundStep(a, roundAlpha);\n if (oneBitAlpha) {\n const threshold = typeof oneBitAlpha === \"number\" ? oneBitAlpha : 127;\n a = a <= threshold ? 0x00 : 0xff;\n }\n r = roundStep(r, roundRGB);\n g = roundStep(g, roundRGB);\n b = roundStep(b, roundRGB);\n\n data[i] = (a << 24) | (b << 16) | (g << 8) | (r << 0);\n }\n}\n\nexport function applyPalette(rgba, palette, format = \"rgb565\") {\n if (!rgba || !rgba.buffer) {\n throw new Error('quantize() expected RGBA Uint8Array data');\n }\n if (!(rgba instanceof Uint8Array) && !(rgba instanceof Uint8ClampedArray)) {\n throw new Error('quantize() expected RGBA Uint8Array data');\n }\n if (palette.length > 256) {\n throw new Error('applyPalette() only works with 256 colors or less');\n }\n\n const data = new Uint32Array(rgba.buffer);\n const length = data.length;\n const bincount = format === \"rgb444\" ? 4096 : 65536;\n const index = new Uint8Array(length);\n const cache = new Array(bincount);\n const hasAlpha = format === \"rgba4444\";\n\n // Some duplicate code below due to very hot code path\n // Introducing branching/conditions shows some significant impact\n if (format === \"rgba4444\") {\n for (let i = 0; i < length; i++) {\n const color = data[i];\n const a = (color >> 24) & 0xff;\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n const key = rgba8888_to_rgba4444(r, g, b, a);\n const idx = key in cache ? cache[key] : (cache[key] = nearestColorIndexRGBA(r, g, b, a, palette));\n index[i] = idx;\n }\n } else {\n const rgb888_to_key = format === \"rgb444\" ? rgb888_to_rgb444 : rgb888_to_rgb565;\n for (let i = 0; i < length; i++) {\n const color = data[i];\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n const key = rgb888_to_key(r, g, b);\n const idx = key in cache ? cache[key] : (cache[key] = nearestColorIndexRGB(r, g, b, palette));\n index[i] = idx;\n }\n }\n\n return index;\n}\n\nfunction nearestColorIndexRGBA(r, g, b, a, palette) {\n let k = 0;\n let mindist = 1e100;\n for (let i = 0; i < palette.length; i++) {\n const px2 = palette[i];\n const a2 = px2[3];\n let curdist = sqr(a2 - a);\n if (curdist > mindist) continue;\n const r2 = px2[0];\n curdist += sqr(r2 - r);\n if (curdist > mindist) continue;\n const g2 = px2[1];\n curdist += sqr(g2 - g);\n if (curdist > mindist) continue;\n const b2 = px2[2];\n curdist += sqr(b2 - b);\n if (curdist > mindist) continue;\n mindist = curdist;\n k = i;\n }\n return k;\n}\n\nfunction nearestColorIndexRGB(r, g, b, palette) {\n let k = 0;\n let mindist = 1e100;\n for (let i = 0; i < palette.length; i++) {\n const px2 = palette[i];\n const r2 = px2[0];\n let curdist = sqr(r2 - r);\n if (curdist > mindist) continue;\n const g2 = px2[1];\n curdist += sqr(g2 - g);\n if (curdist > mindist) continue;\n const b2 = px2[2];\n curdist += sqr(b2 - b);\n if (curdist > mindist) continue;\n mindist = curdist;\n k = i;\n }\n return k;\n}\n\nexport function snapColorsToPalette(palette, knownColors, threshold = 5) {\n if (!palette.length || !knownColors.length) return;\n\n const paletteRGB = palette.map((p) => p.slice(0, 3));\n const thresholdSq = threshold * threshold;\n const dim = palette[0].length;\n for (let i = 0; i < knownColors.length; i++) {\n let color = knownColors[i];\n if (color.length < dim) {\n // palette is RGBA, known is RGB\n color = [color[0], color[1], color[2], 0xff];\n } else if (color.length > dim) {\n // palette is RGB, known is RGBA\n color = color.slice(0, 3);\n } else {\n // make sure we always copy known colors\n color = color.slice();\n }\n const r = nearestColorIndexWithDistance(\n paletteRGB,\n color.slice(0, 3),\n euclideanDistanceSquared\n );\n const idx = r[0];\n const distanceSq = r[1];\n if (distanceSq > 0 && distanceSq <= thresholdSq) {\n palette[idx] = color;\n }\n }\n}\n\nfunction sqr(a) {\n return a * a;\n}\n\nexport function nearestColorIndex(\n colors,\n pixel,\n distanceFn = euclideanDistanceSquared\n) {\n let minDist = Infinity;\n let minDistIndex = -1;\n for (let j = 0; j < colors.length; j++) {\n const paletteColor = colors[j];\n const dist = distanceFn(pixel, paletteColor);\n if (dist < minDist) {\n minDist = dist;\n minDistIndex = j;\n }\n }\n return minDistIndex;\n}\n\nexport function nearestColorIndexWithDistance(\n colors,\n pixel,\n distanceFn = euclideanDistanceSquared\n) {\n let minDist = Infinity;\n let minDistIndex = -1;\n for (let j = 0; j < colors.length; j++) {\n const paletteColor = colors[j];\n const dist = distanceFn(pixel, paletteColor);\n if (dist < minDist) {\n minDist = dist;\n minDistIndex = j;\n }\n }\n return [minDistIndex, minDist];\n}\n\nexport function nearestColor(\n colors,\n pixel,\n distanceFn = euclideanDistanceSquared\n) {\n return colors[nearestColorIndex(colors, pixel, distanceFn)];\n}\n","import constants from \"./constants.js\";\nimport lzwEncode from \"./lzwEncode.js\";\nimport createStream from \"./stream.js\";\nimport quantize from \"./pnnquant2.js\";\n\nimport {\n prequantize,\n applyPalette,\n nearestColorIndex,\n nearestColor,\n nearestColorIndexWithDistance,\n snapColorsToPalette,\n} from \"./palettize.js\";\n\nfunction GIFEncoder(opt = {}) {\n const { initialCapacity = 4096, auto = true } = opt;\n\n // Stream all encoded data into this buffer\n const stream = createStream(initialCapacity);\n\n // Shared array data across all frames\n const HSIZE = 5003; // 80% occupancy\n const accum = new Uint8Array(256);\n const htab = new Int32Array(HSIZE);\n const codetab = new Int32Array(HSIZE);\n\n let hasInit = false;\n\n return {\n reset() {\n stream.reset();\n hasInit = false;\n },\n finish() {\n stream.writeByte(constants.trailer);\n },\n bytes() {\n return stream.bytes();\n },\n bytesView() {\n return stream.bytesView();\n },\n get buffer() {\n return stream.buffer;\n },\n get stream() {\n return stream;\n },\n writeHeader,\n writeFrame(index, width, height, opts = {}) {\n const {\n transparent = false,\n transparentIndex = 0x00,\n delay = 0,\n palette = null,\n repeat = 0, // -1=once, 0=forever, >0=count\n colorDepth = 8,\n dispose = -1,\n } = opts;\n\n let first = false;\n if (auto) {\n // In 'auto' mode, the first time we write a frame\n // we will write LSD/GCT/EXT\n if (!hasInit) {\n // have not yet init, we can consider this our first frame\n first = true;\n // in 'auto' mode, we also encode a header on first frame\n // this is different than manual mode where you must encode\n // header yoursef (or perhaps not write header altogether)\n writeHeader();\n hasInit = true;\n }\n } else {\n // in manual mode, the first frame is determined by the options only\n first = Boolean(opts.first);\n }\n\n width = Math.max(0, Math.floor(width));\n height = Math.max(0, Math.floor(height));\n\n // Write pre-frame details such as repeat count and global palette\n if (first) {\n if (!palette) {\n throw new Error(\"First frame must include a { palette } option\");\n }\n encodeLogicalScreenDescriptor(\n stream,\n width,\n height,\n palette,\n colorDepth\n );\n encodeColorTable(stream, palette);\n if (repeat >= 0) {\n encodeNetscapeExt(stream, repeat);\n }\n }\n\n const delayTime = Math.round(delay / 10);\n encodeGraphicControlExt(\n stream,\n dispose,\n delayTime,\n transparent,\n transparentIndex\n );\n\n const useLocalColorTable = Boolean(palette) && !first;\n encodeImageDescriptor(\n stream,\n width,\n height,\n useLocalColorTable ? palette : null\n );\n if (useLocalColorTable) encodeColorTable(stream, palette);\n encodePixels(\n stream,\n index,\n width,\n height,\n colorDepth,\n accum,\n htab,\n codetab\n );\n },\n };\n\n function writeHeader() {\n writeUTFBytes(stream, \"GIF89a\");\n }\n}\n\nfunction encodeGraphicControlExt(\n stream,\n dispose,\n delay,\n transparent,\n transparentIndex\n) {\n stream.writeByte(0x21); // extension introducer\n stream.writeByte(0xf9); // GCE label\n stream.writeByte(4); // data block size\n\n if (transparentIndex < 0) {\n transparentIndex = 0x00;\n transparent = false;\n }\n\n var transp, disp;\n if (!transparent) {\n transp = 0;\n disp = 0; // dispose = no action\n } else {\n transp = 1;\n disp = 2; // force clear if using transparent color\n }\n\n if (dispose >= 0) {\n disp = dispose & 7; // user override\n }\n\n disp <<= 2;\n\n const userInput = 0;\n\n // packed fields\n stream.writeByte(\n 0 | // 1:3 reserved\n disp | // 4:6 disposal\n userInput | // 7 user input - 0 = none\n transp // 8 transparency flag\n );\n\n writeUInt16(stream, delay); // delay x 1/100 sec\n stream.writeByte(transparentIndex || 0x00); // transparent color index\n stream.writeByte(0); // block terminator\n}\n\nfunction encodeLogicalScreenDescriptor(\n stream,\n width,\n height,\n palette,\n colorDepth = 8\n) {\n const globalColorTableFlag = 1;\n const sortFlag = 0;\n const globalColorTableSize = colorTableSize(palette.length) - 1;\n const fields =\n (globalColorTableFlag << 7) |\n ((colorDepth - 1) << 4) |\n (sortFlag << 3) |\n globalColorTableSize;\n const backgroundColorIndex = 0;\n const pixelAspectRatio = 0;\n writeUInt16(stream, width);\n writeUInt16(stream, height);\n stream.writeBytes([fields, backgroundColorIndex, pixelAspectRatio]);\n}\n\nfunction encodeNetscapeExt(stream, repeat) {\n stream.writeByte(0x21); // extension introducer\n stream.writeByte(0xff); // app extension label\n stream.writeByte(11); // block size\n writeUTFBytes(stream, \"NETSCAPE2.0\"); // app id + auth code\n stream.writeByte(3); // sub-block size\n stream.writeByte(1); // loop sub-block id\n writeUInt16(stream, repeat); // loop count (extra iterations, 0=repeat forever)\n stream.writeByte(0); // block terminator\n}\n\nfunction encodeColorTable(stream, palette) {\n const colorTableLength = 1 << colorTableSize(palette.length);\n for (let i = 0; i < colorTableLength; i++) {\n let color = [0, 0, 0];\n if (i < palette.length) {\n color = palette[i];\n }\n stream.writeByte(color[0]);\n stream.writeByte(color[1]);\n stream.writeByte(color[2]);\n }\n}\n\nfunction encodeImageDescriptor(stream, width, height, localPalette) {\n stream.writeByte(0x2c); // image separator\n\n writeUInt16(stream, 0); // x position\n writeUInt16(stream, 0); // y position\n writeUInt16(stream, width); // image size\n writeUInt16(stream, height);\n\n if (localPalette) {\n const interlace = 0;\n const sorted = 0;\n const palSize = colorTableSize(localPalette.length) - 1;\n // local palette\n stream.writeByte(\n 0x80 | // 1 local color table 1=yes\n interlace | // 2 interlace - 0=no\n sorted | // 3 sorted - 0=no\n 0 | // 4-5 reserved\n palSize // 6-8 size of color table\n );\n } else {\n // global palette\n stream.writeByte(0);\n }\n}\n\nfunction encodePixels(\n stream,\n index,\n width,\n height,\n colorDepth = 8,\n accum,\n htab,\n codetab\n) {\n lzwEncode(width, height, index, colorDepth, stream, accum, htab, codetab);\n}\n\n// Utilities\n\nfunction writeUInt16(stream, short) {\n stream.writeByte(short & 0xff);\n stream.writeByte((short >> 8) & 0xff);\n}\n\nfunction writeUTFBytes(stream, text) {\n for (var i = 0; i < text.length; i++) {\n stream.writeByte(text.charCodeAt(i));\n }\n}\n\nfunction colorTableSize(length) {\n return Math.max(Math.ceil(Math.log2(length)), 1);\n}\n\nexport {\n GIFEncoder,\n quantize,\n prequantize,\n applyPalette,\n nearestColorIndex,\n nearestColor,\n nearestColorIndexWithDistance,\n snapColorsToPalette,\n};\n\nexport default GIFEncoder;\n","// Ease-out reveal: alpha goes 0 -> 1 over first 70% of timeline.\nexport function textAlpha(progress: number): number {\n const p = Math.min(progress / 0.7, 1);\n return 1 - Math.pow(1 - p, 3);\n}\n","// Pulsing glow 0..1 using a sine wave over the loop.\nexport function avatarGlow(progress: number): number {\n return (Math.sin(progress * Math.PI * 2) + 1) / 2;\n}\n","// Phase 0..1 used by drawFrame to shift the background sheen.\nexport function backgroundShift(progress: number): number {\n return progress;\n}\n","import type { AnimationType } from '../types.js';\nimport type { FrameState } from '../render/drawFrame.js';\nimport { textAlpha } from './text.js';\nimport { avatarGlow } from './avatar.js';\nimport { backgroundShift } from './background.js';\n\nexport function frameStateFor(animations: AnimationType[], progress: number): FrameState {\n return {\n textAlpha: animations.includes('text') ? textAlpha(progress) : 1,\n avatarGlow: animations.includes('avatar') ? avatarGlow(progress) : 1,\n backgroundShift: animations.includes('background') ? backgroundShift(progress) : 0,\n };\n}\n","import type {\n AnimationType,\n CardOptions,\n FontOptions,\n MemberCountPosition,\n PresetName,\n Theme,\n} from './types.js';\nimport { DEFAULT_OPTIONS } from './constants.js';\nimport { PRESETS } from './presets/index.js';\nimport { WelcomeCardError } from './errors.js';\nimport { renderPNG } from './render/toPNG.js';\nimport { renderGIF } from './render/toGIF.js';\n\nexport class WelcomeCard {\n private opts: CardOptions = { ...DEFAULT_OPTIONS };\n\n setPreset(preset: PresetName): this {\n if (!PRESETS[preset]) {\n throw new WelcomeCardError(\n `Unknown preset \"${preset}\". Allowed: ${Object.keys(PRESETS).join(', ')}`,\n );\n }\n this.opts.preset = preset;\n return this;\n }\n\n setUsername(username: string): this {\n this.opts.username = username;\n return this;\n }\n\n setAvatar(avatar: string | Buffer): this {\n this.opts.avatar = avatar;\n return this;\n }\n\n setSubtitle(subtitle: string): this {\n this.opts.subtitle = subtitle;\n return this;\n }\n\n setMemberCount(count: number): this {\n this.opts.memberCount = count;\n return this;\n }\n\n setMemberCountPosition(position: MemberCountPosition): this {\n this.opts.memberCountPosition = position;\n return this;\n }\n\n setBackground(background: string): this {\n this.opts.background = background;\n return this;\n }\n\n setTheme(theme: Theme): this {\n this.opts.theme = theme;\n return this;\n }\n\n setFont(font: FontOptions): this {\n this.opts.font = { ...this.opts.font, ...font };\n return this;\n }\n\n setAnimations(animations: AnimationType[]): this {\n this.opts.animations = animations;\n return this;\n }\n\n private validate(): void {\n if (!this.opts.username) {\n throw new WelcomeCardError('username is required — call .setUsername() before rendering.');\n }\n }\n\n async toPNG(): Promise<Buffer> {\n this.validate();\n return renderPNG(this.opts);\n }\n\n async toGIF(): Promise<Buffer> {\n this.validate();\n if (this.opts.animations.length === 0) {\n console.warn('[welcomecard] toGIF() called with no animations — output will be static.');\n }\n return renderGIF(this.opts);\n }\n}\n"],"mappings":"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","names":["import_canvas","import_canvas","x","import_canvas"]}
package/dist/index.d.cts CHANGED
@@ -7,6 +7,7 @@ interface FontOptions {
7
7
  family?: string;
8
8
  color?: string;
9
9
  size?: number;
10
+ subtitleSize?: number;
10
11
  }
11
12
  interface CardOptions {
12
13
  preset: PresetName;
package/dist/index.d.ts CHANGED
@@ -7,6 +7,7 @@ interface FontOptions {
7
7
  family?: string;
8
8
  color?: string;
9
9
  size?: number;
10
+ subtitleSize?: number;
10
11
  }
11
12
  interface CardOptions {
12
13
  preset: PresetName;
package/dist/index.js CHANGED
@@ -3,8 +3,8 @@ import {
3
3
  } from "./chunk-PZ5AY32C.js";
4
4
 
5
5
  // src/constants.ts
6
- var CARD_WIDTH = 1024;
7
- var CARD_HEIGHT = 384;
6
+ var CARD_WIDTH = 840;
7
+ var CARD_HEIGHT = 420;
8
8
  var GIF_FRAMES = 30;
9
9
  var GIF_DELAY_MS = 50;
10
10
  var GIF_SCALE = 0.5;
@@ -35,29 +35,58 @@ var DEFAULT_FONT_FAMILY = "WelcomeCard";
35
35
  // src/presets/centered.ts
36
36
  var EDGE_PAD = 24;
37
37
  var TOP_BASELINE = 36;
38
+ function isHexBackground(background) {
39
+ return typeof background === "string" && /^#[0-9a-fA-F]{3,8}$/.test(background);
40
+ }
41
+ function resolveBackgroundColor(background, fallback) {
42
+ return isHexBackground(background) ? background : fallback;
43
+ }
38
44
  function resolvePosition(position, width, height) {
39
45
  const pos = position === void 0 || position === "corner" ? "bottom-right" : position;
40
- const [v, h] = pos === "center" ? ["center", "center"] : pos.split("-");
41
- return {
42
- x: h === "left" ? EDGE_PAD : h === "center" ? width / 2 : width - EDGE_PAD,
43
- y: v === "top" ? TOP_BASELINE : v === "center" ? height / 2 : height - EDGE_PAD,
44
- align: h
45
- };
46
+ const x = { left: EDGE_PAD, center: width / 2, right: width - EDGE_PAD };
47
+ const y = { top: TOP_BASELINE, center: height / 2, bottom: height - EDGE_PAD };
48
+ switch (pos) {
49
+ case "top-left":
50
+ return { x: x.left, y: y.top, align: "left" };
51
+ case "top-center":
52
+ return { x: x.center, y: y.top, align: "center" };
53
+ case "top-right":
54
+ return { x: x.right, y: y.top, align: "right" };
55
+ case "center-left":
56
+ return { x: x.left, y: y.center, align: "left" };
57
+ case "center":
58
+ return { x: x.center, y: y.center, align: "center" };
59
+ case "center-right":
60
+ return { x: x.right, y: y.center, align: "right" };
61
+ case "bottom-left":
62
+ return { x: x.left, y: y.bottom, align: "left" };
63
+ case "bottom-center":
64
+ return { x: x.center, y: y.bottom, align: "center" };
65
+ case "bottom-right":
66
+ return { x: x.right, y: y.bottom, align: "right" };
67
+ default: {
68
+ const _exhausted = pos;
69
+ throw new Error(`Unhandled memberCountPosition: "${_exhausted}"`);
70
+ }
71
+ }
46
72
  }
47
73
  function centeredLayout(opts) {
48
74
  const width = CARD_WIDTH;
49
75
  const height = CARD_HEIGHT;
50
76
  const accent = opts.theme === "dark" ? "#89b4fa" : "#1e66f5";
51
- const bgColor = typeof opts.background === "string" && opts.background.startsWith("#") ? opts.background : opts.theme === "dark" ? "#1e1e2e" : "#eff1f5";
77
+ const bgColor = resolveBackgroundColor(
78
+ opts.background,
79
+ opts.theme === "dark" ? "#1e1e2e" : "#eff1f5"
80
+ );
52
81
  const textColor = opts.font.color ?? (opts.theme === "dark" ? "#ffffff" : "#11111b");
53
82
  const family = opts.font.family ?? DEFAULT_FONT_FAMILY;
54
- const avatarSize = 120;
55
- const avatarY = 50;
83
+ const avatarSize = 170;
84
+ const avatarY = 56;
56
85
  return {
57
86
  width,
58
87
  height,
59
88
  backgroundColor: bgColor,
60
- background: typeof opts.background === "string" && opts.background.startsWith("#") ? void 0 : opts.background,
89
+ background: isHexBackground(opts.background) ? void 0 : opts.background,
61
90
  avatar: {
62
91
  x: width / 2 - avatarSize / 2,
63
92
  y: avatarY,
@@ -68,8 +97,8 @@ function centeredLayout(opts) {
68
97
  username: {
69
98
  text: opts.username ?? "",
70
99
  x: width / 2,
71
- y: avatarY + avatarSize + 60,
72
- size: opts.font.size ?? 44,
100
+ y: avatarY + avatarSize + 66,
101
+ size: opts.font.size ?? 56,
73
102
  color: textColor,
74
103
  family,
75
104
  align: "center"
@@ -77,8 +106,8 @@ function centeredLayout(opts) {
77
106
  subtitle: opts.subtitle ? {
78
107
  text: opts.subtitle,
79
108
  x: width / 2,
80
- y: avatarY + avatarSize + 105,
81
- size: 24,
109
+ y: avatarY + avatarSize + 122,
110
+ size: opts.font.subtitleSize ?? Math.round((opts.font.size ?? 56) * 0.61),
82
111
  color: textColor,
83
112
  family,
84
113
  align: "center"
@@ -87,7 +116,7 @@ function centeredLayout(opts) {
87
116
  text: `MEMBER #${opts.memberCount}`,
88
117
  // centered preset: everything centered by default, count included
89
118
  ...resolvePosition(opts.memberCountPosition ?? "bottom-center", width, height),
90
- size: 16,
119
+ size: 20,
91
120
  color: textColor,
92
121
  family
93
122
  } : void 0
@@ -99,7 +128,7 @@ function neonLayout(opts) {
99
128
  const base = centeredLayout(opts);
100
129
  return {
101
130
  ...base,
102
- backgroundColor: opts.background?.startsWith("#") ? opts.background : "#0b0b1a",
131
+ backgroundColor: resolveBackgroundColor(opts.background, "#0b0b1a"),
103
132
  avatar: { ...base.avatar, ringColor: "#00ffd5" },
104
133
  username: { ...base.username, color: opts.font.color ?? "#00ffd5" }
105
134
  };
@@ -110,7 +139,7 @@ function minimalLayout(opts) {
110
139
  const base = centeredLayout(opts);
111
140
  return {
112
141
  ...base,
113
- backgroundColor: opts.background?.startsWith("#") ? opts.background : "#ffffff",
142
+ backgroundColor: resolveBackgroundColor(opts.background, "#ffffff"),
114
143
  avatar: { ...base.avatar, ringColor: "#222222" },
115
144
  username: { ...base.username, color: opts.font.color ?? "#111111" },
116
145
  subtitle: base.subtitle ? { ...base.subtitle, color: "#555555" } : void 0
@@ -124,10 +153,13 @@ function heroLayout(opts) {
124
153
  const textX = avatarX + base.avatar.size + 40;
125
154
  return {
126
155
  ...base,
127
- backgroundColor: opts.background?.startsWith("#") ? opts.background : "#101830",
156
+ backgroundColor: resolveBackgroundColor(
157
+ opts.background,
158
+ opts.theme === "dark" ? "#1b1f2a" : "#e8ecf4"
159
+ ),
128
160
  avatar: { ...base.avatar, x: avatarX, y: base.height / 2 - base.avatar.size / 2 },
129
- username: { ...base.username, x: textX, y: base.height / 2 - 6, align: "left" },
130
- subtitle: base.subtitle ? { ...base.subtitle, x: textX, y: base.height / 2 + 30, align: "left" } : void 0,
161
+ username: { ...base.username, x: textX, y: base.height / 2 - 12, align: "left" },
162
+ subtitle: base.subtitle ? { ...base.subtitle, x: textX, y: base.height / 2 + 42, align: "left" } : void 0,
131
163
  memberCount: base.memberCount ? (
132
164
  // hero is asymmetric — default the count to the corner, not bottom-center
133
165
  {
@@ -170,21 +202,34 @@ function layout(opts) {
170
202
 
171
203
  // src/assets/loadImage.ts
172
204
  import { loadImage, createCanvas } from "@napi-rs/canvas";
205
+ var MAX_CACHE = 256;
206
+ function boundedSet(map, key, value) {
207
+ if (map.size >= MAX_CACHE) {
208
+ map.delete(map.keys().next().value);
209
+ }
210
+ map.set(key, value);
211
+ }
212
+ var cache = /* @__PURE__ */ new Map();
213
+ var solidCache = /* @__PURE__ */ new Map();
173
214
  async function solidImage(color, w, h) {
215
+ const key = `${color}:${w}x${h}`;
216
+ const hit = solidCache.get(key);
217
+ if (hit) return hit;
174
218
  const canvas = createCanvas(w, h);
175
219
  const ctx = canvas.getContext("2d");
176
220
  ctx.fillStyle = color;
177
221
  ctx.fillRect(0, 0, w, h);
178
- return loadImage(canvas.toBuffer("image/png"));
222
+ const img = await loadImage(canvas.toBuffer("image/png"));
223
+ boundedSet(solidCache, key, img);
224
+ return img;
179
225
  }
180
- var cache = /* @__PURE__ */ new Map();
181
226
  async function loadImageOrFallback(source, fallbackColor, w = 256, h = 256) {
182
227
  if (source === void 0) return solidImage(fallbackColor, w, h);
183
228
  const hit = cache.get(source);
184
229
  if (hit) return hit;
185
230
  try {
186
231
  const img = await loadImage(source);
187
- cache.set(source, img);
232
+ boundedSet(cache, source, img);
188
233
  return img;
189
234
  } catch {
190
235
  return solidImage(fallbackColor, w, h);
@@ -641,6 +686,12 @@ async function renderGIF(opts) {
641
686
  const enc = GIFEncoder();
642
687
  const frames = opts.animations.length === 0 ? 1 : GIF_FRAMES;
643
688
  let palette;
689
+ if (frames > 1) {
690
+ const paletteState = frameStateFor(opts.animations, 0.5);
691
+ await drawFrame(ctx, l, paletteState);
692
+ outCtx.drawImage(canvas, 0, 0, gw, gh);
693
+ palette = quantize(outCtx.getImageData(0, 0, gw, gh).data, 256);
694
+ }
644
695
  for (let i = 0; i < frames; i++) {
645
696
  const progress = frames === 1 ? 0 : i / frames;
646
697
  const state = frameStateFor(opts.animations, progress);
@@ -657,7 +708,7 @@ async function renderGIF(opts) {
657
708
 
658
709
  // src/WelcomeCard.ts
659
710
  var WelcomeCard = class {
660
- opts = { ...DEFAULT_OPTIONS, font: {}, animations: [] };
711
+ opts = { ...DEFAULT_OPTIONS };
661
712
  setPreset(preset) {
662
713
  if (!PRESETS[preset]) {
663
714
  throw new WelcomeCardError(
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants.ts","../src/assets/fonts/register.ts","../src/presets/centered.ts","../src/presets/neon.ts","../src/presets/minimal.ts","../src/presets/hero.ts","../src/presets/index.ts","../src/errors.ts","../src/render/toPNG.ts","../src/render/layout.ts","../src/assets/loadImage.ts","../src/render/drawFrame.ts","../src/render/toGIF.ts","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/constants.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/stream.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/lzwEncode.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/rgb-packing.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/pnnquant2.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/color.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/palettize.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/index.js","../src/animate/text.ts","../src/animate/avatar.ts","../src/animate/background.ts","../src/animate/index.ts","../src/WelcomeCard.ts"],"sourcesContent":["import type { CardOptions } from './types.js';\n\nexport const CARD_WIDTH = 1024;\nexport const CARD_HEIGHT = 384; // ~16:6 banner\n\nexport const GIF_FRAMES = 30;\nexport const GIF_DELAY_MS = 50; // ~20fps\nexport const GIF_SCALE = 0.5; // GIFs render at half size to stay under Discord upload limits\n\nexport const DEFAULT_OPTIONS: CardOptions = {\n preset: 'centered',\n theme: 'dark',\n font: {},\n animations: [],\n};\n","import { GlobalFonts } from '@napi-rs/canvas';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport { existsSync } from 'node:fs';\n\nconst here = dirname(fileURLToPath(import.meta.url));\n\n// dev/tests run from src/assets/fonts; the published build runs from dist\n// with the font copied next to it (tsup publicDir).\nconst candidates = [\n join(here, 'Poppins-Bold.ttf'),\n join(here, 'assets', 'fonts', 'Poppins-Bold.ttf'),\n join(here, '..', 'src', 'assets', 'fonts', 'Poppins-Bold.ttf'),\n];\n\nconst fontPath = candidates.find(existsSync);\nif (fontPath) {\n GlobalFonts.registerFromPath(fontPath, 'WelcomeCard');\n}\n\nexport const DEFAULT_FONT_FAMILY = 'WelcomeCard';\n","import { CARD_WIDTH, CARD_HEIGHT } from '../constants.js';\nimport type { CardOptions, MemberCountPosition } from '../types.js';\nimport { DEFAULT_FONT_FAMILY } from '../assets/fonts/register.js';\n\nconst EDGE_PAD = 24;\nconst TOP_BASELINE = 36; // baseline y for top-anchored text\n\nexport function resolvePosition(\n position: MemberCountPosition | undefined,\n width: number,\n height: number,\n): { x: number; y: number; align: 'left' | 'center' | 'right' } {\n const pos = position === undefined || position === 'corner' ? 'bottom-right' : position;\n const [v, h] = pos === 'center' ? ['center', 'center'] : pos.split('-');\n return {\n x: h === 'left' ? EDGE_PAD : h === 'center' ? width / 2 : width - EDGE_PAD,\n y: v === 'top' ? TOP_BASELINE : v === 'center' ? height / 2 : height - EDGE_PAD,\n align: h as 'left' | 'center' | 'right',\n };\n}\n\nexport interface TextBox {\n text: string;\n x: number;\n y: number;\n size: number;\n color: string;\n family: string;\n align: 'left' | 'center' | 'right';\n}\n\nexport interface LayoutResult {\n width: number;\n height: number;\n backgroundColor: string;\n background?: string | Buffer;\n avatar: { x: number; y: number; size: number; ringColor: string; source?: string | Buffer };\n username: TextBox;\n subtitle?: TextBox;\n memberCount?: TextBox;\n}\n\nexport function centeredLayout(opts: CardOptions): LayoutResult {\n const width = CARD_WIDTH;\n const height = CARD_HEIGHT;\n const accent = opts.theme === 'dark' ? '#89b4fa' : '#1e66f5';\n const bgColor =\n typeof opts.background === 'string' && opts.background.startsWith('#')\n ? opts.background\n : opts.theme === 'dark'\n ? '#1e1e2e'\n : '#eff1f5';\n const textColor = opts.font.color ?? (opts.theme === 'dark' ? '#ffffff' : '#11111b');\n const family = opts.font.family ?? DEFAULT_FONT_FAMILY;\n\n const avatarSize = 120;\n const avatarY = 50;\n\n return {\n width,\n height,\n backgroundColor: bgColor,\n background:\n typeof opts.background === 'string' && opts.background.startsWith('#')\n ? undefined\n : opts.background,\n avatar: {\n x: width / 2 - avatarSize / 2,\n y: avatarY,\n size: avatarSize,\n ringColor: accent,\n source: opts.avatar,\n },\n username: {\n text: opts.username ?? '',\n x: width / 2,\n y: avatarY + avatarSize + 60,\n size: opts.font.size ?? 44,\n color: textColor,\n family,\n align: 'center',\n },\n subtitle: opts.subtitle\n ? {\n text: opts.subtitle,\n x: width / 2,\n y: avatarY + avatarSize + 105,\n size: 24,\n color: textColor,\n family,\n align: 'center',\n }\n : undefined,\n memberCount:\n opts.memberCount !== undefined\n ? {\n text: `MEMBER #${opts.memberCount}`,\n // centered preset: everything centered by default, count included\n ...resolvePosition(opts.memberCountPosition ?? 'bottom-center', width, height),\n size: 16,\n color: textColor,\n family,\n }\n : undefined,\n };\n}\n","import { centeredLayout } from './centered.js';\nimport type { CardOptions } from '../types.js';\nimport type { LayoutResult } from './centered.js';\n\nexport function neonLayout(opts: CardOptions): LayoutResult {\n const base = centeredLayout(opts);\n return {\n ...base,\n backgroundColor: opts.background?.startsWith('#') ? opts.background : '#0b0b1a',\n avatar: { ...base.avatar, ringColor: '#00ffd5' },\n username: { ...base.username, color: opts.font.color ?? '#00ffd5' },\n };\n}\n","import { centeredLayout } from './centered.js';\nimport type { CardOptions } from '../types.js';\nimport type { LayoutResult } from './centered.js';\n\nexport function minimalLayout(opts: CardOptions): LayoutResult {\n const base = centeredLayout(opts);\n return {\n ...base,\n backgroundColor: opts.background?.startsWith('#') ? opts.background : '#ffffff',\n avatar: { ...base.avatar, ringColor: '#222222' },\n username: { ...base.username, color: opts.font.color ?? '#111111' },\n subtitle: base.subtitle ? { ...base.subtitle, color: '#555555' } : undefined,\n };\n}\n","import { centeredLayout, resolvePosition } from './centered.js';\nimport type { CardOptions } from '../types.js';\nimport type { LayoutResult } from './centered.js';\n\n// Hero: avatar shifted left, text left-aligned beside it.\nexport function heroLayout(opts: CardOptions): LayoutResult {\n const base = centeredLayout(opts);\n const avatarX = 60;\n const textX = avatarX + base.avatar.size + 40;\n return {\n ...base,\n backgroundColor: opts.background?.startsWith('#') ? opts.background : '#101830',\n avatar: { ...base.avatar, x: avatarX, y: base.height / 2 - base.avatar.size / 2 },\n username: { ...base.username, x: textX, y: base.height / 2 - 6, align: 'left' },\n subtitle: base.subtitle\n ? { ...base.subtitle, x: textX, y: base.height / 2 + 30, align: 'left' }\n : undefined,\n memberCount: base.memberCount\n ? // hero is asymmetric — default the count to the corner, not bottom-center\n {\n ...base.memberCount,\n ...resolvePosition(opts.memberCountPosition ?? 'bottom-right', base.width, base.height),\n }\n : undefined,\n };\n}\n","import type { CardOptions, PresetName } from '../types.js';\nimport { centeredLayout, type LayoutResult } from './centered.js';\nimport { neonLayout } from './neon.js';\nimport { minimalLayout } from './minimal.js';\nimport { heroLayout } from './hero.js';\n\nexport type { LayoutResult, TextBox } from './centered.js';\nexport type LayoutFn = (opts: CardOptions) => LayoutResult;\n\nexport const PRESETS: Record<PresetName, LayoutFn> = {\n centered: centeredLayout,\n neon: neonLayout,\n minimal: minimalLayout,\n hero: heroLayout,\n};\n","export class WelcomeCardError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WelcomeCardError';\n }\n}\n","import { createCanvas } from '@napi-rs/canvas';\nimport '../assets/fonts/register.js';\nimport type { CardOptions } from '../types.js';\nimport { layout } from './layout.js';\nimport { drawFrame, STATIC_FRAME } from './drawFrame.js';\n\nexport async function renderPNG(opts: CardOptions): Promise<Buffer> {\n const l = layout(opts);\n const canvas = createCanvas(l.width, l.height);\n const ctx = canvas.getContext('2d');\n await drawFrame(ctx, l, STATIC_FRAME);\n return canvas.toBuffer('image/png');\n}\n","import type { CardOptions } from '../types.js';\nimport { PRESETS, type LayoutResult } from '../presets/index.js';\nimport { WelcomeCardError } from '../errors.js';\n\nexport function layout(opts: CardOptions): LayoutResult {\n const fn = PRESETS[opts.preset];\n if (!fn) {\n throw new WelcomeCardError(\n `Unknown preset \"${opts.preset}\". Allowed: ${Object.keys(PRESETS).join(', ')}`,\n );\n }\n return fn(opts);\n}\n","import { loadImage, createCanvas, type Image } from '@napi-rs/canvas';\n\nasync function solidImage(color: string, w: number, h: number): Promise<Image> {\n const canvas = createCanvas(w, h);\n const ctx = canvas.getContext('2d');\n ctx.fillStyle = color;\n ctx.fillRect(0, 0, w, h);\n return loadImage(canvas.toBuffer('image/png'));\n}\n\n// Cache so GIF rendering (N frames) fetches each URL/Buffer only once.\nconst cache = new Map<string | Buffer, Image>();\n\nexport async function loadImageOrFallback(\n source: string | Buffer | undefined,\n fallbackColor: string,\n w = 256,\n h = 256,\n): Promise<Image> {\n if (source === undefined) return solidImage(fallbackColor, w, h);\n const hit = cache.get(source);\n if (hit) return hit;\n try {\n const img = await loadImage(source);\n cache.set(source, img);\n return img;\n } catch {\n return solidImage(fallbackColor, w, h);\n }\n}\n","import type { SKRSContext2D } from '@napi-rs/canvas';\nimport type { LayoutResult, TextBox } from '../presets/index.js';\nimport { loadImageOrFallback } from '../assets/loadImage.js';\n\nexport interface FrameState {\n textAlpha: number; // 0..1 reveal for text\n avatarGlow: number; // 0..1 glow intensity\n backgroundShift: number; // 0..1 gradient phase\n}\n\nexport const STATIC_FRAME: FrameState = { textAlpha: 1, avatarGlow: 1, backgroundShift: 0 };\n\nfunction drawText(ctx: SKRSContext2D, box: TextBox, alpha: number) {\n ctx.save();\n ctx.globalAlpha = alpha;\n ctx.fillStyle = box.color;\n ctx.textAlign = box.align;\n ctx.textBaseline = 'alphabetic';\n ctx.font = `${box.size}px ${box.family}`;\n ctx.fillText(box.text, box.x, box.y);\n ctx.restore();\n}\n\nexport async function drawFrame(\n ctx: SKRSContext2D,\n l: LayoutResult,\n state: FrameState,\n): Promise<void> {\n // background\n ctx.fillStyle = l.backgroundColor;\n ctx.fillRect(0, 0, l.width, l.height);\n if (l.background !== undefined) {\n const bg = await loadImageOrFallback(l.background, l.backgroundColor, l.width, l.height);\n ctx.drawImage(bg, 0, 0, l.width, l.height);\n }\n if (state.backgroundShift > 0) {\n // diagonal sheen sliding across the card; phase 0..1 loops with the GIF\n const x = (state.backgroundShift * 2 - 1) * l.width * 2;\n const g = ctx.createLinearGradient(x, 0, x + l.width, l.height);\n g.addColorStop(0, 'rgba(255,255,255,0)');\n g.addColorStop(0.5, 'rgba(255,255,255,0.10)');\n g.addColorStop(1, 'rgba(255,255,255,0)');\n ctx.fillStyle = g;\n ctx.fillRect(0, 0, l.width, l.height);\n }\n\n // avatar (circular) with glow ring\n const { x, y, size, ringColor } = l.avatar;\n const cx = x + size / 2;\n const cy = y + size / 2;\n ctx.save();\n ctx.shadowColor = ringColor;\n ctx.shadowBlur = 10 + state.avatarGlow * 25;\n ctx.lineWidth = 6;\n ctx.strokeStyle = ringColor;\n ctx.beginPath();\n ctx.arc(cx, cy, size / 2 + 3, 0, Math.PI * 2);\n ctx.stroke();\n ctx.restore();\n\n const avatarImg = await loadImageOrFallback(l.avatar.source, ringColor, size, size);\n ctx.save();\n ctx.beginPath();\n ctx.arc(cx, cy, size / 2, 0, Math.PI * 2);\n ctx.clip();\n ctx.drawImage(avatarImg, x, y, size, size);\n ctx.restore();\n\n // text\n drawText(ctx, l.username, state.textAlpha);\n if (l.subtitle) drawText(ctx, l.subtitle, state.textAlpha);\n if (l.memberCount) drawText(ctx, l.memberCount, state.textAlpha);\n}\n","import { createCanvas } from '@napi-rs/canvas';\nimport * as gifencMod from 'gifenc';\n// gifenc ships dual CJS/ESM with inconsistent interop — named exports may live on the\n// namespace (vite/bundlers) or behind .default (node CJS-ESM interop). Pick whichever has them.\ntype Gifenc = typeof import('gifenc');\nconst { GIFEncoder, quantize, applyPalette } =\n 'GIFEncoder' in gifencMod ? (gifencMod as Gifenc) : (gifencMod as { default: Gifenc }).default;\nimport '../assets/fonts/register.js';\nimport type { CardOptions } from '../types.js';\nimport { GIF_FRAMES, GIF_DELAY_MS, GIF_SCALE } from '../constants.js';\nimport { layout } from './layout.js';\nimport { drawFrame } from './drawFrame.js';\nimport { frameStateFor } from '../animate/index.js';\n\nexport async function renderGIF(opts: CardOptions): Promise<Buffer> {\n const l = layout(opts);\n // draw at full size, encode at half size: smaller files, under Discord limits\n const canvas = createCanvas(l.width, l.height);\n const ctx = canvas.getContext('2d');\n const gw = Math.round(l.width * GIF_SCALE);\n const gh = Math.round(l.height * GIF_SCALE);\n const out = createCanvas(gw, gh);\n const outCtx = out.getContext('2d');\n const enc = GIFEncoder();\n\n const frames = opts.animations.length === 0 ? 1 : GIF_FRAMES;\n // one shared palette for all frames: stable colors (no flicker), faster encode\n let palette: number[][] | undefined;\n for (let i = 0; i < frames; i++) {\n const progress = frames === 1 ? 0 : i / frames;\n const state = frameStateFor(opts.animations, progress);\n await drawFrame(ctx, l, state);\n outCtx.drawImage(canvas, 0, 0, gw, gh);\n const { data } = outCtx.getImageData(0, 0, gw, gh);\n palette ??= quantize(data, 256);\n const index = applyPalette(data, palette);\n enc.writeFrame(index, gw, gh, { palette, delay: GIF_DELAY_MS });\n }\n enc.finish();\n return Buffer.from(enc.bytes());\n}\n","export default {\n signature: \"GIF\",\n version: \"89a\",\n trailer: 0x3B,\n extensionIntroducer: 0x21,\n applicationExtensionLabel: 0xFF,\n graphicControlExtensionLabel: 0xF9,\n imageSeparator: 0x2C,\n // Header\n signatureSize: 3,\n versionSize: 3,\n globalColorTableFlagMask: 0b10000000,\n colorResolutionMask: 0b01110000,\n sortFlagMask: 0b00001000,\n globalColorTableSizeMask: 0b00000111,\n // Application extension\n applicationIdentifierSize: 8,\n applicationAuthCodeSize: 3,\n // Graphic control extension\n disposalMethodMask: 0b00011100,\n userInputFlagMask: 0b00000010,\n transparentColorFlagMask: 0b00000001,\n // Image descriptor\n localColorTableFlagMask: 0b10000000,\n interlaceFlagMask: 0b01000000,\n idSortFlagMask: 0b00100000,\n localColorTableSizeMask: 0b00000111\n}\n","export default function createStream(initialCapacity = 256) {\n let cursor = 0;\n let contents = new Uint8Array(initialCapacity);\n\n return {\n get buffer() {\n return contents.buffer;\n },\n reset() {\n cursor = 0;\n },\n bytesView() {\n return contents.subarray(0, cursor);\n },\n bytes() {\n return contents.slice(0, cursor);\n },\n writeByte(byte) {\n expand(cursor + 1);\n contents[cursor] = byte;\n cursor++;\n },\n writeBytes(data, offset = 0, byteLength = data.length) {\n expand(cursor + byteLength);\n for (let i = 0; i < byteLength; i++) {\n contents[cursor++] = data[i + offset];\n }\n },\n writeBytesView(data, offset = 0, byteLength = data.byteLength) {\n expand(cursor + byteLength);\n contents.set(data.subarray(offset, offset + byteLength), cursor);\n cursor += byteLength;\n },\n };\n\n function expand(newCapacity) {\n var prevCapacity = contents.length;\n if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough.\n // Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity.\n // For small filesizes (<1MB), perform size*2 geometric increase, but for large sizes, do a much more conservative size*1.125 increase to\n // avoid overshooting the allocation cap by a very large margin.\n var CAPACITY_DOUBLING_MAX = 1024 * 1024;\n newCapacity = Math.max(\n newCapacity,\n (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) >>>\n 0\n );\n if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.\n const oldContents = contents;\n contents = new Uint8Array(newCapacity); // Allocate new storage.\n if (cursor > 0) contents.set(oldContents.subarray(0, cursor), 0);\n }\n}\n","/*\n LZWEncoder.js\n Authors\n Kevin Weiner (original Java version - kweiner@fmsware.com)\n Thibault Imbert (AS3 version - bytearray.org)\n Johan Nordberg (JS version - code@johan-nordberg.com)\n Acknowledgements\n GIFCOMPR.C - GIF Image compression routines\n Lempel-Ziv compression based on 'compress'. GIF modifications by\n David Rowley (mgardi@watdcsu.waterloo.edu)\n GIF Image compression - modified 'compress'\n Based on: compress.c - File compression ala IEEE Computer, June 1984.\n By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)\n Jim McKie (decvax!mcvax!jim)\n Steve Davies (decvax!vax135!petsd!peora!srd)\n Ken Turkowski (decvax!decwrl!turtlevax!ken)\n James A. Woods (decvax!ihnp4!ames!jaw)\n Joe Orost (decvax!vax135!petsd!joe)\n Matt DesLauriers (@mattdesl - V8/JS optimizations)\n Mathieu Henri (@p01 - JS optimization)\n*/\n\nimport createStream from \"./stream.js\";\n\nconst EOF = -1;\nconst BITS = 12;\nconst DEFAULT_HSIZE = 5003; // 80% occupancy\nconst MASKS = [\n 0x0000,\n 0x0001,\n 0x0003,\n 0x0007,\n 0x000f,\n 0x001f,\n 0x003f,\n 0x007f,\n 0x00ff,\n 0x01ff,\n 0x03ff,\n 0x07ff,\n 0x0fff,\n 0x1fff,\n 0x3fff,\n 0x7fff,\n 0xffff,\n];\n\nfunction lzwEncode(\n width,\n height,\n pixels,\n colorDepth,\n outStream = createStream(512),\n accum = new Uint8Array(256),\n htab = new Int32Array(DEFAULT_HSIZE),\n codetab = new Int32Array(DEFAULT_HSIZE)\n) {\n const hsize = htab.length;\n const initCodeSize = Math.max(2, colorDepth);\n\n accum.fill(0);\n codetab.fill(0);\n htab.fill(-1);\n\n let cur_accum = 0;\n let cur_bits = 0;\n\n // Algorithm: use open addressing double hashing (no chaining) on the\n // prefix code / next character combination. We do a variant of Knuth's\n // algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime\n // secondary probe. Here, the modular division first probe is gives way\n // to a faster exclusive-or manipulation. Also do block compression with\n // an adaptive reset, whereby the code table is cleared when the compression\n // ratio decreases, but after the table fills. The variable-length output\n // codes are re-sized at this point, and a special CLEAR code is generated\n // for the decompressor. Late addition: construct the table according to\n // file size for noticeable speed improvement on small files. Please direct\n // questions about this implementation to ames!jaw.\n\n // compress and write the pixel data\n const init_bits = initCodeSize + 1;\n\n // Set up the globals: g_init_bits - initial number of bits\n const g_init_bits = init_bits;\n\n // Set up the necessary values\n\n // block compression parameters -- after all codes are used up,\n // and compression rate changes, start over.\n let clear_flg = false;\n let n_bits = g_init_bits;\n let maxcode = (1 << n_bits) - 1;\n\n const ClearCode = 1 << (init_bits - 1);\n const EOFCode = ClearCode + 1;\n let free_ent = ClearCode + 2;\n let a_count = 0; // clear packet\n\n let ent = pixels[0];\n\n let hshift = 0;\n for (let fcode = hsize; fcode < 65536; fcode *= 2) {\n ++hshift;\n }\n hshift = 8 - hshift; // set hash code range bound\n\n outStream.writeByte(initCodeSize); // write \"initial code size\" byte\n\n output(ClearCode);\n\n const length = pixels.length;\n for (let idx = 1; idx < length; idx++) {\n next_block: {\n const c = pixels[idx];\n const fcode = (c << BITS) + ent;\n let i = (c << hshift) ^ ent; // xor hashing\n if (htab[i] === fcode) {\n ent = codetab[i];\n break next_block;\n }\n\n const disp = i === 0 ? 1 : hsize - i; // secondary hash (after G. Knott)\n while (htab[i] >= 0) {\n // non-empty slot\n i -= disp;\n if (i < 0) i += hsize;\n if (htab[i] === fcode) {\n ent = codetab[i];\n break next_block;\n }\n }\n output(ent);\n ent = c;\n if (free_ent < 1 << BITS) {\n codetab[i] = free_ent++; // code -> hashtable\n htab[i] = fcode;\n } else {\n // Clear out the hash table\n // table clear for block compress\n htab.fill(-1);\n free_ent = ClearCode + 2;\n clear_flg = true;\n output(ClearCode);\n }\n }\n }\n\n // Put out the final code.\n output(ent);\n output(EOFCode);\n\n outStream.writeByte(0); // write block terminator\n return outStream.bytesView();\n\n function output(code) {\n cur_accum &= MASKS[cur_bits];\n\n if (cur_bits > 0) cur_accum |= code << cur_bits;\n else cur_accum = code;\n\n cur_bits += n_bits;\n\n while (cur_bits >= 8) {\n // Add a character to the end of the current packet, and if it is 254\n // characters, flush the packet to disk.\n accum[a_count++] = cur_accum & 0xff;\n if (a_count >= 254) {\n outStream.writeByte(a_count);\n outStream.writeBytesView(accum, 0, a_count);\n a_count = 0;\n }\n cur_accum >>= 8;\n cur_bits -= 8;\n }\n\n // If the next entry is going to be too big for the code size,\n // then increase it, if possible.\n if (free_ent > maxcode || clear_flg) {\n if (clear_flg) {\n n_bits = g_init_bits;\n maxcode = (1 << n_bits) - 1;\n clear_flg = false;\n } else {\n ++n_bits;\n maxcode = n_bits === BITS ? (1 << n_bits) : (1 << n_bits) - 1;\n }\n }\n\n if (code == EOFCode) {\n // At EOF, write the rest of the buffer.\n while (cur_bits > 0) {\n // Add a character to the end of the current packet, and if it is 254\n // characters, flush the packet to disk.\n accum[a_count++] = cur_accum & 0xff;\n if (a_count >= 254) {\n outStream.writeByte(a_count);\n outStream.writeBytesView(accum, 0, a_count);\n a_count = 0;\n }\n cur_accum >>= 8;\n cur_bits -= 8;\n }\n // Flush the packet to disk, and reset the accumulator\n if (a_count > 0) {\n outStream.writeByte(a_count);\n outStream.writeBytesView(accum, 0, a_count);\n a_count = 0;\n }\n }\n }\n}\n\nexport default lzwEncode;\n","export function uint32_to_rgba(color) {\n var a = (color >> 24) & 0xff;\n var b = (color >> 16) & 0xff;\n var g = (color >> 8) & 0xff;\n var r = color & 0xff;\n return [r, g, b, a];\n}\n\nexport function rgba_to_uint32(r, g, b, a) {\n return (a << 24) | (b << 16) | (g << 8) | r;\n}\n\nexport function rgb888_to_rgb565(r, g, b) {\n return ((r << 8) & 0xf800) | ((g << 2) & 0x03e0) | (b >> 3);\n}\n\nexport function rgba8888_to_rgba4444(r, g, b, a) {\n return (r >> 4) | (g & 0xf0) | ((b & 0xf0) << 4) | ((a & 0xf0) << 8);\n}\n\nexport function rgb888_to_rgb444(r, g, b) {\n return ((r >> 4) << 8) | (g & 0xf0) | (b >> 4);\n}\n\n// Alternative 565 ?\n// return ((r & 0xf8) << 8) + ((g & 0xfc) << 3) + (b >> 3);\n\n// Alternative 4444 ?\n// ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | (g & 0xf0) | (b >> 4);\n","// Modified from:\n// https://github.com/mcychan/PnnQuant.js/blob/master/src/pnnquant.js\n\n/* Fast pairwise nearest neighbor based algorithm for multilevel thresholding\nCopyright (C) 2004-2019 Mark Tyler and Dmitry Groshev\nCopyright (c) 2018-2021 Miller Cy Chan\n* error measure; time used is proportional to number of bins squared - WJ */\n\nimport {\n rgb888_to_rgb565,\n rgb888_to_rgb444,\n rgba8888_to_rgba4444,\n} from \"./rgb-packing.js\";\n\nfunction clamp(value, min, max) {\n return value < min ? min : value > max ? max : value;\n}\n\nfunction sqr(value) {\n return value * value;\n}\n\nfunction find_nn(bins, idx, hasAlpha) {\n var nn = 0;\n var err = 1e100;\n\n const bin1 = bins[idx];\n const n1 = bin1.cnt;\n const wa = bin1.ac;\n const wr = bin1.rc;\n const wg = bin1.gc;\n const wb = bin1.bc;\n for (var i = bin1.fw; i != 0; i = bins[i].fw) {\n const bin = bins[i];\n const n2 = bin.cnt;\n const nerr2 = (n1 * n2) / (n1 + n2);\n if (nerr2 >= err) continue;\n\n var nerr = 0;\n if (hasAlpha) {\n nerr += nerr2 * sqr(bin.ac - wa);\n if (nerr >= err) continue;\n }\n\n nerr += nerr2 * sqr(bin.rc - wr);\n if (nerr >= err) continue;\n\n nerr += nerr2 * sqr(bin.gc - wg);\n if (nerr >= err) continue;\n\n nerr += nerr2 * sqr(bin.bc - wb);\n if (nerr >= err) continue;\n err = nerr;\n nn = i;\n }\n bin1.err = err;\n bin1.nn = nn;\n}\n\nfunction create_bin() {\n return {\n ac: 0,\n rc: 0,\n gc: 0,\n bc: 0,\n cnt: 0,\n nn: 0,\n fw: 0,\n bk: 0,\n tm: 0,\n mtm: 0,\n err: 0,\n };\n}\n\nfunction bin_add_rgb(bin, r, g, b) {\n bin.rc += r;\n bin.gc += g;\n bin.bc += b;\n bin.cnt++;\n}\n\nfunction create_bin_list(data, format) {\n const bincount = format === \"rgb444\" ? 4096 : 65536;\n const bins = new Array(bincount);\n const size = data.length;\n\n /* Build histogram */\n // Note: Instead of introducing branching/conditions\n // within a very hot per-pixel iteration, we just duplicate the code\n // for each new condition\n if (format === \"rgba4444\") {\n for (let i = 0; i < size; ++i) {\n const color = data[i];\n const a = (color >> 24) & 0xff;\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n\n // reduce to rgb4444 16-bit uint\n const index = rgba8888_to_rgba4444(r, g, b, a);\n let bin = index in bins ? bins[index] : (bins[index] = create_bin());\n bin.rc += r;\n bin.gc += g;\n bin.bc += b;\n bin.ac += a;\n bin.cnt++;\n }\n }\n \n else if (format === \"rgb444\") {\n for (let i = 0; i < size; ++i) {\n const color = data[i];\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n\n // reduce to rgb444 12-bit uint\n const index = rgb888_to_rgb444(r, g, b);\n let bin = index in bins ? bins[index] : (bins[index] = create_bin());\n bin.rc += r;\n bin.gc += g;\n bin.bc += b;\n bin.cnt++;\n }\n } else {\n for (let i = 0; i < size; ++i) {\n const color = data[i];\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n\n // reduce to rgb565 16-bit uint\n const index = rgb888_to_rgb565(r, g, b);\n let bin = index in bins ? bins[index] : (bins[index] = create_bin());\n bin.rc += r;\n bin.gc += g;\n bin.bc += b;\n bin.cnt++;\n }\n }\n return bins;\n}\n\nexport default function quantize(rgba, maxColors, opts = {}) {\n const {\n format = \"rgb565\",\n clearAlpha = true,\n clearAlphaColor = 0x00,\n clearAlphaThreshold = 0,\n oneBitAlpha = false,\n } = opts;\n\n if (!rgba || !rgba.buffer) {\n throw new Error('quantize() expected RGBA Uint8Array data');\n }\n if (!(rgba instanceof Uint8Array) && !(rgba instanceof Uint8ClampedArray)) {\n throw new Error('quantize() expected RGBA Uint8Array data');\n }\n \n const data = new Uint32Array(rgba.buffer);\n\n let useSqrt = opts.useSqrt !== false;\n\n // format can be:\n // rgb565 (default)\n // rgb444\n // rgba4444\n\n const hasAlpha = format === \"rgba4444\";\n const bins = create_bin_list(data, format);\n const bincount = bins.length;\n const bincountMinusOne = bincount - 1;\n const heap = new Uint32Array(bincount + 1);\n\n /* Cluster nonempty bins at one end of array */\n var maxbins = 0;\n for (var i = 0; i < bincount; ++i) {\n const bin = bins[i];\n if (bin != null) {\n var d = 1.0 / bin.cnt;\n if (hasAlpha) bin.ac *= d;\n bin.rc *= d;\n bin.gc *= d;\n bin.bc *= d;\n bins[maxbins++] = bin;\n }\n }\n\n if (sqr(maxColors) / maxbins < 0.022) {\n useSqrt = false;\n }\n\n var i = 0;\n for (; i < maxbins - 1; ++i) {\n bins[i].fw = i + 1;\n bins[i + 1].bk = i;\n if (useSqrt) bins[i].cnt = Math.sqrt(bins[i].cnt);\n }\n if (useSqrt) bins[i].cnt = Math.sqrt(bins[i].cnt);\n\n var h, l, l2;\n /* Initialize nearest neighbors and build heap of them */\n for (i = 0; i < maxbins; ++i) {\n find_nn(bins, i, false);\n /* Push slot on heap */\n var err = bins[i].err;\n for (l = ++heap[0]; l > 1; l = l2) {\n l2 = l >> 1;\n if (bins[(h = heap[l2])].err <= err) break;\n heap[l] = h;\n }\n heap[l] = i;\n }\n\n /* Merge bins which increase error the least */\n var extbins = maxbins - maxColors;\n for (i = 0; i < extbins; ) {\n var tb;\n /* Use heap to find which bins to merge */\n for (;;) {\n var b1 = heap[1];\n tb = bins[b1]; /* One with least error */\n /* Is stored error up to date? */\n if (tb.tm >= tb.mtm && bins[tb.nn].mtm <= tb.tm) break;\n if (tb.mtm == bincountMinusOne)\n /* Deleted node */ b1 = heap[1] = heap[heap[0]--];\n /* Too old error value */ else {\n find_nn(bins, b1, false);\n tb.tm = i;\n }\n /* Push slot down */\n var err = bins[b1].err;\n for (l = 1; (l2 = l + l) <= heap[0]; l = l2) {\n if (l2 < heap[0] && bins[heap[l2]].err > bins[heap[l2 + 1]].err) l2++;\n if (err <= bins[(h = heap[l2])].err) break;\n heap[l] = h;\n }\n heap[l] = b1;\n }\n\n /* Do a merge */\n var nb = bins[tb.nn];\n var n1 = tb.cnt;\n var n2 = nb.cnt;\n var d = 1.0 / (n1 + n2);\n if (hasAlpha) tb.ac = d * (n1 * tb.ac + n2 * nb.ac);\n tb.rc = d * (n1 * tb.rc + n2 * nb.rc);\n tb.gc = d * (n1 * tb.gc + n2 * nb.gc);\n tb.bc = d * (n1 * tb.bc + n2 * nb.bc);\n tb.cnt += nb.cnt;\n tb.mtm = ++i;\n\n /* Unchain deleted bin */\n bins[nb.bk].fw = nb.fw;\n bins[nb.fw].bk = nb.bk;\n nb.mtm = bincountMinusOne;\n }\n\n // let palette = new Uint32Array(maxColors);\n let palette = [];\n\n /* Fill palette */\n var k = 0;\n for (i = 0; ; ++k) {\n let r = clamp(Math.round(bins[i].rc), 0, 0xff);\n let g = clamp(Math.round(bins[i].gc), 0, 0xff);\n let b = clamp(Math.round(bins[i].bc), 0, 0xff);\n\n let a = 0xff;\n if (hasAlpha) {\n a = clamp(Math.round(bins[i].ac), 0, 0xff);\n if (oneBitAlpha) {\n const threshold = typeof oneBitAlpha === \"number\" ? oneBitAlpha : 127;\n a = a <= threshold ? 0x00 : 0xff;\n }\n if (clearAlpha && a <= clearAlphaThreshold) {\n r = g = b = clearAlphaColor;\n a = 0x00;\n }\n }\n\n const color = hasAlpha ? [r, g, b, a] : [r, g, b];\n const exists = existsInPalette(palette, color);\n if (!exists) palette.push(color);\n if ((i = bins[i].fw) == 0) break;\n }\n\n return palette;\n}\n\nfunction existsInPalette(palette, color) {\n for (let i = 0; i < palette.length; i++) {\n const p = palette[i];\n let matchesRGB =\n p[0] === color[0] && p[1] === color[1] && p[2] === color[2];\n let matchesAlpha =\n p.length >= 4 && color.length >= 4 ? p[3] === color[3] : true;\n if (matchesRGB && matchesAlpha) return true;\n }\n return false;\n}\n\n// TODO: Further 'clean' palette by merging nearly-identical colors?\n","function rgb2y(r, g, b) {\n return r * 0.29889531 + g * 0.58662247 + b * 0.11448223;\n}\nfunction rgb2i(r, g, b) {\n return r * 0.59597799 - g * 0.2741761 - b * 0.32180189;\n}\nfunction rgb2q(r, g, b) {\n return r * 0.21147017 - g * 0.52261711 + b * 0.31114694;\n}\n\nexport function colorDifferenceYIQSquared(yiqA, yiqB) {\n const y = yiqA[0] - yiqB[0];\n const i = yiqA[1] - yiqB[1];\n const q = yiqA[2] - yiqB[2];\n const a = alpha(yiqA) - alpha(yiqB);\n return y * y * 0.5053 + i * i * 0.299 + q * q * 0.1957 + a * a;\n}\n\nfunction alpha(array) {\n return array[3] != null ? array[3] : 0xff;\n}\n\nexport function colorDifferenceYIQ(yiqA, yiqB) {\n return Math.sqrt(colorDifferenceYIQSquared(yiqA, yiqB));\n}\n\nexport function colorDifferenceRGBToYIQSquared(rgb1, rgb2) {\n const [r1, g1, b1] = rgb1;\n const [r2, g2, b2] = rgb2;\n const y = rgb2y(r1, g1, b1) - rgb2y(r2, g2, b2),\n i = rgb2i(r1, g1, b1) - rgb2i(r2, g2, b2),\n q = rgb2q(r1, g1, b1) - rgb2q(r2, g2, b2);\n const a = alpha(rgb1) - alpha(rgb2);\n return y * y * 0.5053 + i * i * 0.299 + q * q * 0.1957 + a * a;\n}\n\nexport function colorDifferenceRGBToYIQ(rgb1, rgb2) {\n return Math.sqrt(colorDifferenceRGBToYIQSquared(rgb1, rgb2));\n}\n\nexport function euclideanDistanceSquared(a, b) {\n var sum = 0;\n var n;\n for (n = 0; n < a.length; n++) {\n const dx = a[n] - b[n];\n sum += dx * dx;\n }\n return sum;\n}\n\nexport function euclideanDistance(a, b) {\n return Math.sqrt(euclideanDistanceSquared(a, b));\n}\n","import {\n rgb888_to_rgb444,\n rgb888_to_rgb565,\n rgba8888_to_rgba4444,\n} from \"./rgb-packing.js\";\n\nimport { euclideanDistanceSquared } from \"./color.js\";\n\nfunction roundStep(byte, step) {\n return step > 1 ? Math.round(byte / step) * step : byte;\n}\n\nexport function prequantize(\n rgba,\n { roundRGB = 5, roundAlpha = 10, oneBitAlpha = null } = {}\n) {\n const data = new Uint32Array(rgba.buffer);\n for (let i = 0; i < data.length; i++) {\n const color = data[i];\n let a = (color >> 24) & 0xff;\n let b = (color >> 16) & 0xff;\n let g = (color >> 8) & 0xff;\n let r = color & 0xff;\n\n a = roundStep(a, roundAlpha);\n if (oneBitAlpha) {\n const threshold = typeof oneBitAlpha === \"number\" ? oneBitAlpha : 127;\n a = a <= threshold ? 0x00 : 0xff;\n }\n r = roundStep(r, roundRGB);\n g = roundStep(g, roundRGB);\n b = roundStep(b, roundRGB);\n\n data[i] = (a << 24) | (b << 16) | (g << 8) | (r << 0);\n }\n}\n\nexport function applyPalette(rgba, palette, format = \"rgb565\") {\n if (!rgba || !rgba.buffer) {\n throw new Error('quantize() expected RGBA Uint8Array data');\n }\n if (!(rgba instanceof Uint8Array) && !(rgba instanceof Uint8ClampedArray)) {\n throw new Error('quantize() expected RGBA Uint8Array data');\n }\n if (palette.length > 256) {\n throw new Error('applyPalette() only works with 256 colors or less');\n }\n\n const data = new Uint32Array(rgba.buffer);\n const length = data.length;\n const bincount = format === \"rgb444\" ? 4096 : 65536;\n const index = new Uint8Array(length);\n const cache = new Array(bincount);\n const hasAlpha = format === \"rgba4444\";\n\n // Some duplicate code below due to very hot code path\n // Introducing branching/conditions shows some significant impact\n if (format === \"rgba4444\") {\n for (let i = 0; i < length; i++) {\n const color = data[i];\n const a = (color >> 24) & 0xff;\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n const key = rgba8888_to_rgba4444(r, g, b, a);\n const idx = key in cache ? cache[key] : (cache[key] = nearestColorIndexRGBA(r, g, b, a, palette));\n index[i] = idx;\n }\n } else {\n const rgb888_to_key = format === \"rgb444\" ? rgb888_to_rgb444 : rgb888_to_rgb565;\n for (let i = 0; i < length; i++) {\n const color = data[i];\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n const key = rgb888_to_key(r, g, b);\n const idx = key in cache ? cache[key] : (cache[key] = nearestColorIndexRGB(r, g, b, palette));\n index[i] = idx;\n }\n }\n\n return index;\n}\n\nfunction nearestColorIndexRGBA(r, g, b, a, palette) {\n let k = 0;\n let mindist = 1e100;\n for (let i = 0; i < palette.length; i++) {\n const px2 = palette[i];\n const a2 = px2[3];\n let curdist = sqr(a2 - a);\n if (curdist > mindist) continue;\n const r2 = px2[0];\n curdist += sqr(r2 - r);\n if (curdist > mindist) continue;\n const g2 = px2[1];\n curdist += sqr(g2 - g);\n if (curdist > mindist) continue;\n const b2 = px2[2];\n curdist += sqr(b2 - b);\n if (curdist > mindist) continue;\n mindist = curdist;\n k = i;\n }\n return k;\n}\n\nfunction nearestColorIndexRGB(r, g, b, palette) {\n let k = 0;\n let mindist = 1e100;\n for (let i = 0; i < palette.length; i++) {\n const px2 = palette[i];\n const r2 = px2[0];\n let curdist = sqr(r2 - r);\n if (curdist > mindist) continue;\n const g2 = px2[1];\n curdist += sqr(g2 - g);\n if (curdist > mindist) continue;\n const b2 = px2[2];\n curdist += sqr(b2 - b);\n if (curdist > mindist) continue;\n mindist = curdist;\n k = i;\n }\n return k;\n}\n\nexport function snapColorsToPalette(palette, knownColors, threshold = 5) {\n if (!palette.length || !knownColors.length) return;\n\n const paletteRGB = palette.map((p) => p.slice(0, 3));\n const thresholdSq = threshold * threshold;\n const dim = palette[0].length;\n for (let i = 0; i < knownColors.length; i++) {\n let color = knownColors[i];\n if (color.length < dim) {\n // palette is RGBA, known is RGB\n color = [color[0], color[1], color[2], 0xff];\n } else if (color.length > dim) {\n // palette is RGB, known is RGBA\n color = color.slice(0, 3);\n } else {\n // make sure we always copy known colors\n color = color.slice();\n }\n const r = nearestColorIndexWithDistance(\n paletteRGB,\n color.slice(0, 3),\n euclideanDistanceSquared\n );\n const idx = r[0];\n const distanceSq = r[1];\n if (distanceSq > 0 && distanceSq <= thresholdSq) {\n palette[idx] = color;\n }\n }\n}\n\nfunction sqr(a) {\n return a * a;\n}\n\nexport function nearestColorIndex(\n colors,\n pixel,\n distanceFn = euclideanDistanceSquared\n) {\n let minDist = Infinity;\n let minDistIndex = -1;\n for (let j = 0; j < colors.length; j++) {\n const paletteColor = colors[j];\n const dist = distanceFn(pixel, paletteColor);\n if (dist < minDist) {\n minDist = dist;\n minDistIndex = j;\n }\n }\n return minDistIndex;\n}\n\nexport function nearestColorIndexWithDistance(\n colors,\n pixel,\n distanceFn = euclideanDistanceSquared\n) {\n let minDist = Infinity;\n let minDistIndex = -1;\n for (let j = 0; j < colors.length; j++) {\n const paletteColor = colors[j];\n const dist = distanceFn(pixel, paletteColor);\n if (dist < minDist) {\n minDist = dist;\n minDistIndex = j;\n }\n }\n return [minDistIndex, minDist];\n}\n\nexport function nearestColor(\n colors,\n pixel,\n distanceFn = euclideanDistanceSquared\n) {\n return colors[nearestColorIndex(colors, pixel, distanceFn)];\n}\n","import constants from \"./constants.js\";\nimport lzwEncode from \"./lzwEncode.js\";\nimport createStream from \"./stream.js\";\nimport quantize from \"./pnnquant2.js\";\n\nimport {\n prequantize,\n applyPalette,\n nearestColorIndex,\n nearestColor,\n nearestColorIndexWithDistance,\n snapColorsToPalette,\n} from \"./palettize.js\";\n\nfunction GIFEncoder(opt = {}) {\n const { initialCapacity = 4096, auto = true } = opt;\n\n // Stream all encoded data into this buffer\n const stream = createStream(initialCapacity);\n\n // Shared array data across all frames\n const HSIZE = 5003; // 80% occupancy\n const accum = new Uint8Array(256);\n const htab = new Int32Array(HSIZE);\n const codetab = new Int32Array(HSIZE);\n\n let hasInit = false;\n\n return {\n reset() {\n stream.reset();\n hasInit = false;\n },\n finish() {\n stream.writeByte(constants.trailer);\n },\n bytes() {\n return stream.bytes();\n },\n bytesView() {\n return stream.bytesView();\n },\n get buffer() {\n return stream.buffer;\n },\n get stream() {\n return stream;\n },\n writeHeader,\n writeFrame(index, width, height, opts = {}) {\n const {\n transparent = false,\n transparentIndex = 0x00,\n delay = 0,\n palette = null,\n repeat = 0, // -1=once, 0=forever, >0=count\n colorDepth = 8,\n dispose = -1,\n } = opts;\n\n let first = false;\n if (auto) {\n // In 'auto' mode, the first time we write a frame\n // we will write LSD/GCT/EXT\n if (!hasInit) {\n // have not yet init, we can consider this our first frame\n first = true;\n // in 'auto' mode, we also encode a header on first frame\n // this is different than manual mode where you must encode\n // header yoursef (or perhaps not write header altogether)\n writeHeader();\n hasInit = true;\n }\n } else {\n // in manual mode, the first frame is determined by the options only\n first = Boolean(opts.first);\n }\n\n width = Math.max(0, Math.floor(width));\n height = Math.max(0, Math.floor(height));\n\n // Write pre-frame details such as repeat count and global palette\n if (first) {\n if (!palette) {\n throw new Error(\"First frame must include a { palette } option\");\n }\n encodeLogicalScreenDescriptor(\n stream,\n width,\n height,\n palette,\n colorDepth\n );\n encodeColorTable(stream, palette);\n if (repeat >= 0) {\n encodeNetscapeExt(stream, repeat);\n }\n }\n\n const delayTime = Math.round(delay / 10);\n encodeGraphicControlExt(\n stream,\n dispose,\n delayTime,\n transparent,\n transparentIndex\n );\n\n const useLocalColorTable = Boolean(palette) && !first;\n encodeImageDescriptor(\n stream,\n width,\n height,\n useLocalColorTable ? palette : null\n );\n if (useLocalColorTable) encodeColorTable(stream, palette);\n encodePixels(\n stream,\n index,\n width,\n height,\n colorDepth,\n accum,\n htab,\n codetab\n );\n },\n };\n\n function writeHeader() {\n writeUTFBytes(stream, \"GIF89a\");\n }\n}\n\nfunction encodeGraphicControlExt(\n stream,\n dispose,\n delay,\n transparent,\n transparentIndex\n) {\n stream.writeByte(0x21); // extension introducer\n stream.writeByte(0xf9); // GCE label\n stream.writeByte(4); // data block size\n\n if (transparentIndex < 0) {\n transparentIndex = 0x00;\n transparent = false;\n }\n\n var transp, disp;\n if (!transparent) {\n transp = 0;\n disp = 0; // dispose = no action\n } else {\n transp = 1;\n disp = 2; // force clear if using transparent color\n }\n\n if (dispose >= 0) {\n disp = dispose & 7; // user override\n }\n\n disp <<= 2;\n\n const userInput = 0;\n\n // packed fields\n stream.writeByte(\n 0 | // 1:3 reserved\n disp | // 4:6 disposal\n userInput | // 7 user input - 0 = none\n transp // 8 transparency flag\n );\n\n writeUInt16(stream, delay); // delay x 1/100 sec\n stream.writeByte(transparentIndex || 0x00); // transparent color index\n stream.writeByte(0); // block terminator\n}\n\nfunction encodeLogicalScreenDescriptor(\n stream,\n width,\n height,\n palette,\n colorDepth = 8\n) {\n const globalColorTableFlag = 1;\n const sortFlag = 0;\n const globalColorTableSize = colorTableSize(palette.length) - 1;\n const fields =\n (globalColorTableFlag << 7) |\n ((colorDepth - 1) << 4) |\n (sortFlag << 3) |\n globalColorTableSize;\n const backgroundColorIndex = 0;\n const pixelAspectRatio = 0;\n writeUInt16(stream, width);\n writeUInt16(stream, height);\n stream.writeBytes([fields, backgroundColorIndex, pixelAspectRatio]);\n}\n\nfunction encodeNetscapeExt(stream, repeat) {\n stream.writeByte(0x21); // extension introducer\n stream.writeByte(0xff); // app extension label\n stream.writeByte(11); // block size\n writeUTFBytes(stream, \"NETSCAPE2.0\"); // app id + auth code\n stream.writeByte(3); // sub-block size\n stream.writeByte(1); // loop sub-block id\n writeUInt16(stream, repeat); // loop count (extra iterations, 0=repeat forever)\n stream.writeByte(0); // block terminator\n}\n\nfunction encodeColorTable(stream, palette) {\n const colorTableLength = 1 << colorTableSize(palette.length);\n for (let i = 0; i < colorTableLength; i++) {\n let color = [0, 0, 0];\n if (i < palette.length) {\n color = palette[i];\n }\n stream.writeByte(color[0]);\n stream.writeByte(color[1]);\n stream.writeByte(color[2]);\n }\n}\n\nfunction encodeImageDescriptor(stream, width, height, localPalette) {\n stream.writeByte(0x2c); // image separator\n\n writeUInt16(stream, 0); // x position\n writeUInt16(stream, 0); // y position\n writeUInt16(stream, width); // image size\n writeUInt16(stream, height);\n\n if (localPalette) {\n const interlace = 0;\n const sorted = 0;\n const palSize = colorTableSize(localPalette.length) - 1;\n // local palette\n stream.writeByte(\n 0x80 | // 1 local color table 1=yes\n interlace | // 2 interlace - 0=no\n sorted | // 3 sorted - 0=no\n 0 | // 4-5 reserved\n palSize // 6-8 size of color table\n );\n } else {\n // global palette\n stream.writeByte(0);\n }\n}\n\nfunction encodePixels(\n stream,\n index,\n width,\n height,\n colorDepth = 8,\n accum,\n htab,\n codetab\n) {\n lzwEncode(width, height, index, colorDepth, stream, accum, htab, codetab);\n}\n\n// Utilities\n\nfunction writeUInt16(stream, short) {\n stream.writeByte(short & 0xff);\n stream.writeByte((short >> 8) & 0xff);\n}\n\nfunction writeUTFBytes(stream, text) {\n for (var i = 0; i < text.length; i++) {\n stream.writeByte(text.charCodeAt(i));\n }\n}\n\nfunction colorTableSize(length) {\n return Math.max(Math.ceil(Math.log2(length)), 1);\n}\n\nexport {\n GIFEncoder,\n quantize,\n prequantize,\n applyPalette,\n nearestColorIndex,\n nearestColor,\n nearestColorIndexWithDistance,\n snapColorsToPalette,\n};\n\nexport default GIFEncoder;\n","// Ease-out reveal: alpha goes 0 -> 1 over first 70% of timeline.\nexport function textAlpha(progress: number): number {\n const p = Math.min(progress / 0.7, 1);\n return 1 - Math.pow(1 - p, 3);\n}\n","// Pulsing glow 0..1 using a sine wave over the loop.\nexport function avatarGlow(progress: number): number {\n return (Math.sin(progress * Math.PI * 2) + 1) / 2;\n}\n","// Phase 0..1 used by drawFrame to shift the background sheen.\nexport function backgroundShift(progress: number): number {\n return progress;\n}\n","import type { AnimationType } from '../types.js';\nimport type { FrameState } from '../render/drawFrame.js';\nimport { textAlpha } from './text.js';\nimport { avatarGlow } from './avatar.js';\nimport { backgroundShift } from './background.js';\n\nexport function frameStateFor(animations: AnimationType[], progress: number): FrameState {\n return {\n textAlpha: animations.includes('text') ? textAlpha(progress) : 1,\n avatarGlow: animations.includes('avatar') ? avatarGlow(progress) : 1,\n backgroundShift: animations.includes('background') ? backgroundShift(progress) : 0,\n };\n}\n","import type {\n AnimationType,\n CardOptions,\n FontOptions,\n MemberCountPosition,\n PresetName,\n Theme,\n} from './types.js';\nimport { DEFAULT_OPTIONS } from './constants.js';\nimport { PRESETS } from './presets/index.js';\nimport { WelcomeCardError } from './errors.js';\nimport { renderPNG } from './render/toPNG.js';\nimport { renderGIF } from './render/toGIF.js';\n\nexport class WelcomeCard {\n private opts: CardOptions = { ...DEFAULT_OPTIONS, font: {}, animations: [] };\n\n setPreset(preset: PresetName): this {\n if (!PRESETS[preset]) {\n throw new WelcomeCardError(\n `Unknown preset \"${preset}\". Allowed: ${Object.keys(PRESETS).join(', ')}`,\n );\n }\n this.opts.preset = preset;\n return this;\n }\n\n setUsername(username: string): this {\n this.opts.username = username;\n return this;\n }\n\n setAvatar(avatar: string | Buffer): this {\n this.opts.avatar = avatar;\n return this;\n }\n\n setSubtitle(subtitle: string): this {\n this.opts.subtitle = subtitle;\n return this;\n }\n\n setMemberCount(count: number): this {\n this.opts.memberCount = count;\n return this;\n }\n\n setMemberCountPosition(position: MemberCountPosition): this {\n this.opts.memberCountPosition = position;\n return this;\n }\n\n setBackground(background: string): this {\n this.opts.background = background;\n return this;\n }\n\n setTheme(theme: Theme): this {\n this.opts.theme = theme;\n return this;\n }\n\n setFont(font: FontOptions): this {\n this.opts.font = { ...this.opts.font, ...font };\n return this;\n }\n\n setAnimations(animations: AnimationType[]): this {\n this.opts.animations = animations;\n return this;\n }\n\n private validate(): void {\n if (!this.opts.username) {\n throw new WelcomeCardError('username is required — call .setUsername() before rendering.');\n }\n }\n\n async toPNG(): Promise<Buffer> {\n this.validate();\n return renderPNG(this.opts);\n }\n\n async toGIF(): Promise<Buffer> {\n this.validate();\n if (this.opts.animations.length === 0) {\n console.warn('[welcomecard] toGIF() called with no animations — output will be static.');\n }\n return renderGIF(this.opts);\n }\n}\n"],"mappings":"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","names":["createCanvas","x","createCanvas","createCanvas","createCanvas"]}
1
+ {"version":3,"sources":["../src/constants.ts","../src/assets/fonts/register.ts","../src/presets/centered.ts","../src/presets/neon.ts","../src/presets/minimal.ts","../src/presets/hero.ts","../src/presets/index.ts","../src/errors.ts","../src/render/toPNG.ts","../src/render/layout.ts","../src/assets/loadImage.ts","../src/render/drawFrame.ts","../src/render/toGIF.ts","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/constants.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/stream.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/lzwEncode.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/rgb-packing.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/pnnquant2.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/color.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/palettize.js","../node_modules/.pnpm/gifenc@1.0.3/node_modules/gifenc/src/index.js","../src/animate/text.ts","../src/animate/avatar.ts","../src/animate/background.ts","../src/animate/index.ts","../src/WelcomeCard.ts"],"sourcesContent":["import type { CardOptions } from './types.js';\n\nexport const CARD_WIDTH = 840;\nexport const CARD_HEIGHT = 420; // 2:1 banner\n\nexport const GIF_FRAMES = 30;\nexport const GIF_DELAY_MS = 50; // ~20fps\nexport const GIF_SCALE = 0.5; // GIFs render at half size to stay under Discord upload limits\n\nexport const DEFAULT_OPTIONS: CardOptions = {\n preset: 'centered',\n theme: 'dark',\n font: {},\n animations: [],\n};\n","import { GlobalFonts } from '@napi-rs/canvas';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport { existsSync } from 'node:fs';\n\nconst here = dirname(fileURLToPath(import.meta.url));\n\n// dev/tests run from src/assets/fonts; the published build runs from dist\n// with the font copied next to it (tsup publicDir).\nconst candidates = [\n join(here, 'Poppins-Bold.ttf'),\n join(here, 'assets', 'fonts', 'Poppins-Bold.ttf'),\n join(here, '..', 'src', 'assets', 'fonts', 'Poppins-Bold.ttf'),\n];\n\nconst fontPath = candidates.find(existsSync);\nif (fontPath) {\n GlobalFonts.registerFromPath(fontPath, 'WelcomeCard');\n}\n\nexport const DEFAULT_FONT_FAMILY = 'WelcomeCard';\n","import { CARD_WIDTH, CARD_HEIGHT } from '../constants.js';\nimport type { CardOptions, MemberCountPosition } from '../types.js';\nimport { DEFAULT_FONT_FAMILY } from '../assets/fonts/register.js';\n\nconst EDGE_PAD = 24;\nconst TOP_BASELINE = 36; // baseline y for top-anchored text\n\nexport function isHexBackground(background: string | undefined): background is string {\n return typeof background === 'string' && /^#[0-9a-fA-F]{3,8}$/.test(background);\n}\n\nexport function resolveBackgroundColor(background: string | undefined, fallback: string): string {\n return isHexBackground(background) ? background : fallback;\n}\n\nexport function resolvePosition(\n position: MemberCountPosition | undefined,\n width: number,\n height: number,\n): { x: number; y: number; align: 'left' | 'center' | 'right' } {\n const pos = position === undefined || position === 'corner' ? 'bottom-right' : position;\n const x = { left: EDGE_PAD, center: width / 2, right: width - EDGE_PAD } as const;\n const y = { top: TOP_BASELINE, center: height / 2, bottom: height - EDGE_PAD } as const;\n switch (pos) {\n case 'top-left': return { x: x.left, y: y.top, align: 'left' };\n case 'top-center': return { x: x.center, y: y.top, align: 'center' };\n case 'top-right': return { x: x.right, y: y.top, align: 'right' };\n case 'center-left': return { x: x.left, y: y.center, align: 'left' };\n case 'center': return { x: x.center, y: y.center, align: 'center' };\n case 'center-right': return { x: x.right, y: y.center, align: 'right' };\n case 'bottom-left': return { x: x.left, y: y.bottom, align: 'left' };\n case 'bottom-center': return { x: x.center, y: y.bottom, align: 'center' };\n case 'bottom-right': return { x: x.right, y: y.bottom, align: 'right' };\n default: {\n const _exhausted: never = pos;\n throw new Error(`Unhandled memberCountPosition: \"${_exhausted as string}\"`);\n }\n }\n}\n\nexport interface TextBox {\n text: string;\n x: number;\n y: number;\n size: number;\n color: string;\n family: string;\n align: 'left' | 'center' | 'right';\n}\n\nexport interface LayoutResult {\n width: number;\n height: number;\n backgroundColor: string;\n background?: string;\n avatar: { x: number; y: number; size: number; ringColor: string; source?: string | Buffer };\n username: TextBox;\n subtitle?: TextBox;\n memberCount?: TextBox;\n}\n\nexport function centeredLayout(opts: CardOptions): LayoutResult {\n const width = CARD_WIDTH;\n const height = CARD_HEIGHT;\n const accent = opts.theme === 'dark' ? '#89b4fa' : '#1e66f5';\n const bgColor = resolveBackgroundColor(\n opts.background,\n opts.theme === 'dark' ? '#1e1e2e' : '#eff1f5',\n );\n const textColor = opts.font.color ?? (opts.theme === 'dark' ? '#ffffff' : '#11111b');\n const family = opts.font.family ?? DEFAULT_FONT_FAMILY;\n\n const avatarSize = 170;\n const avatarY = 56;\n\n return {\n width,\n height,\n backgroundColor: bgColor,\n background: isHexBackground(opts.background) ? undefined : opts.background,\n avatar: {\n x: width / 2 - avatarSize / 2,\n y: avatarY,\n size: avatarSize,\n ringColor: accent,\n source: opts.avatar,\n },\n username: {\n text: opts.username ?? '',\n x: width / 2,\n y: avatarY + avatarSize + 66,\n size: opts.font.size ?? 56,\n color: textColor,\n family,\n align: 'center',\n },\n subtitle: opts.subtitle\n ? {\n text: opts.subtitle,\n x: width / 2,\n y: avatarY + avatarSize + 122,\n size: opts.font.subtitleSize ?? Math.round((opts.font.size ?? 56) * 0.61),\n color: textColor,\n family,\n align: 'center',\n }\n : undefined,\n memberCount:\n opts.memberCount !== undefined\n ? {\n text: `MEMBER #${opts.memberCount}`,\n // centered preset: everything centered by default, count included\n ...resolvePosition(opts.memberCountPosition ?? 'bottom-center', width, height),\n size: 20,\n color: textColor,\n family,\n }\n : undefined,\n };\n}\n","import { centeredLayout, resolveBackgroundColor } from './centered.js';\nimport type { CardOptions } from '../types.js';\nimport type { LayoutResult } from './centered.js';\n\nexport function neonLayout(opts: CardOptions): LayoutResult {\n const base = centeredLayout(opts);\n return {\n ...base,\n backgroundColor: resolveBackgroundColor(opts.background, '#0b0b1a'),\n avatar: { ...base.avatar, ringColor: '#00ffd5' },\n username: { ...base.username, color: opts.font.color ?? '#00ffd5' },\n };\n}\n","import { centeredLayout, resolveBackgroundColor } from './centered.js';\nimport type { CardOptions } from '../types.js';\nimport type { LayoutResult } from './centered.js';\n\nexport function minimalLayout(opts: CardOptions): LayoutResult {\n const base = centeredLayout(opts);\n return {\n ...base,\n backgroundColor: resolveBackgroundColor(opts.background, '#ffffff'),\n avatar: { ...base.avatar, ringColor: '#222222' },\n username: { ...base.username, color: opts.font.color ?? '#111111' },\n subtitle: base.subtitle ? { ...base.subtitle, color: '#555555' } : undefined,\n };\n}\n","import { centeredLayout, resolvePosition, resolveBackgroundColor } from './centered.js';\nimport type { CardOptions } from '../types.js';\nimport type { LayoutResult } from './centered.js';\n\n// Hero: avatar shifted left, text left-aligned beside it.\nexport function heroLayout(opts: CardOptions): LayoutResult {\n const base = centeredLayout(opts);\n const avatarX = 60;\n const textX = avatarX + base.avatar.size + 40;\n return {\n ...base,\n backgroundColor: resolveBackgroundColor(\n opts.background,\n opts.theme === 'dark' ? '#1b1f2a' : '#e8ecf4',\n ),\n avatar: { ...base.avatar, x: avatarX, y: base.height / 2 - base.avatar.size / 2 },\n username: { ...base.username, x: textX, y: base.height / 2 - 12, align: 'left' },\n subtitle: base.subtitle\n ? { ...base.subtitle, x: textX, y: base.height / 2 + 42, align: 'left' }\n : undefined,\n memberCount: base.memberCount\n ? // hero is asymmetric — default the count to the corner, not bottom-center\n {\n ...base.memberCount,\n ...resolvePosition(opts.memberCountPosition ?? 'bottom-right', base.width, base.height),\n }\n : undefined,\n };\n}\n","import type { CardOptions, PresetName } from '../types.js';\nimport { centeredLayout, type LayoutResult } from './centered.js';\nimport { neonLayout } from './neon.js';\nimport { minimalLayout } from './minimal.js';\nimport { heroLayout } from './hero.js';\n\nexport type { LayoutResult, TextBox } from './centered.js';\nexport type LayoutFn = (opts: CardOptions) => LayoutResult;\n\nexport const PRESETS: Record<PresetName, LayoutFn> = {\n centered: centeredLayout,\n neon: neonLayout,\n minimal: minimalLayout,\n hero: heroLayout,\n};\n","export class WelcomeCardError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WelcomeCardError';\n }\n}\n","import { createCanvas } from '@napi-rs/canvas';\nimport '../assets/fonts/register.js';\nimport type { CardOptions } from '../types.js';\nimport { layout } from './layout.js';\nimport { drawFrame, STATIC_FRAME } from './drawFrame.js';\n\nexport async function renderPNG(opts: CardOptions): Promise<Buffer> {\n const l = layout(opts);\n const canvas = createCanvas(l.width, l.height);\n const ctx = canvas.getContext('2d');\n await drawFrame(ctx, l, STATIC_FRAME);\n return canvas.toBuffer('image/png');\n}\n","import type { CardOptions } from '../types.js';\nimport { PRESETS, type LayoutResult } from '../presets/index.js';\nimport { WelcomeCardError } from '../errors.js';\n\nexport function layout(opts: CardOptions): LayoutResult {\n const fn = PRESETS[opts.preset];\n if (!fn) {\n throw new WelcomeCardError(\n `Unknown preset \"${opts.preset}\". Allowed: ${Object.keys(PRESETS).join(', ')}`,\n );\n }\n return fn(opts);\n}\n","import { loadImage, createCanvas, type Image } from '@napi-rs/canvas';\n\nconst MAX_CACHE = 256;\n\nfunction boundedSet<K>(map: Map<K, Image>, key: K, value: Image): void {\n if (map.size >= MAX_CACHE) {\n map.delete(map.keys().next().value!);\n }\n map.set(key, value);\n}\n\n// Cache so GIF rendering (N frames) fetches each URL/Buffer only once.\nconst cache = new Map<string | Buffer, Image>();\nconst solidCache = new Map<string, Image>();\n\nasync function solidImage(color: string, w: number, h: number): Promise<Image> {\n const key = `${color}:${w}x${h}`;\n const hit = solidCache.get(key);\n if (hit) return hit;\n const canvas = createCanvas(w, h);\n const ctx = canvas.getContext('2d');\n ctx.fillStyle = color;\n ctx.fillRect(0, 0, w, h);\n const img = await loadImage(canvas.toBuffer('image/png'));\n boundedSet(solidCache, key, img);\n return img;\n}\n\nexport async function loadImageOrFallback(\n source: string | Buffer | undefined,\n fallbackColor: string,\n w = 256,\n h = 256,\n): Promise<Image> {\n if (source === undefined) return solidImage(fallbackColor, w, h);\n const hit = cache.get(source);\n if (hit) return hit;\n try {\n const img = await loadImage(source);\n boundedSet(cache, source, img);\n return img;\n } catch {\n return solidImage(fallbackColor, w, h);\n }\n}\n","import type { SKRSContext2D } from '@napi-rs/canvas';\nimport type { LayoutResult, TextBox } from '../presets/index.js';\nimport { loadImageOrFallback } from '../assets/loadImage.js';\n\nexport interface FrameState {\n textAlpha: number; // 0..1 reveal for text\n avatarGlow: number; // 0..1 glow intensity\n backgroundShift: number; // 0..1 gradient phase\n}\n\nexport const STATIC_FRAME: FrameState = { textAlpha: 1, avatarGlow: 1, backgroundShift: 0 };\n\nfunction drawText(ctx: SKRSContext2D, box: TextBox, alpha: number) {\n ctx.save();\n ctx.globalAlpha = alpha;\n ctx.fillStyle = box.color;\n ctx.textAlign = box.align;\n ctx.textBaseline = 'alphabetic';\n ctx.font = `${box.size}px ${box.family}`;\n ctx.fillText(box.text, box.x, box.y);\n ctx.restore();\n}\n\nexport async function drawFrame(\n ctx: SKRSContext2D,\n l: LayoutResult,\n state: FrameState,\n): Promise<void> {\n // background\n ctx.fillStyle = l.backgroundColor;\n ctx.fillRect(0, 0, l.width, l.height);\n if (l.background !== undefined) {\n const bg = await loadImageOrFallback(l.background, l.backgroundColor, l.width, l.height);\n ctx.drawImage(bg, 0, 0, l.width, l.height);\n }\n if (state.backgroundShift > 0) {\n // diagonal sheen sliding across the card; phase 0..1 loops with the GIF\n const x = (state.backgroundShift * 2 - 1) * l.width * 2;\n const g = ctx.createLinearGradient(x, 0, x + l.width, l.height);\n g.addColorStop(0, 'rgba(255,255,255,0)');\n g.addColorStop(0.5, 'rgba(255,255,255,0.10)');\n g.addColorStop(1, 'rgba(255,255,255,0)');\n ctx.fillStyle = g;\n ctx.fillRect(0, 0, l.width, l.height);\n }\n\n // avatar (circular) with glow ring\n const { x, y, size, ringColor } = l.avatar;\n const cx = x + size / 2;\n const cy = y + size / 2;\n ctx.save();\n ctx.shadowColor = ringColor;\n ctx.shadowBlur = 10 + state.avatarGlow * 25;\n ctx.lineWidth = 6;\n ctx.strokeStyle = ringColor;\n ctx.beginPath();\n ctx.arc(cx, cy, size / 2 + 3, 0, Math.PI * 2);\n ctx.stroke();\n ctx.restore();\n\n const avatarImg = await loadImageOrFallback(l.avatar.source, ringColor, size, size);\n ctx.save();\n ctx.beginPath();\n ctx.arc(cx, cy, size / 2, 0, Math.PI * 2);\n ctx.clip();\n ctx.drawImage(avatarImg, x, y, size, size);\n ctx.restore();\n\n // text\n drawText(ctx, l.username, state.textAlpha);\n if (l.subtitle) drawText(ctx, l.subtitle, state.textAlpha);\n if (l.memberCount) drawText(ctx, l.memberCount, state.textAlpha);\n}\n","import { createCanvas } from '@napi-rs/canvas';\nimport * as gifencMod from 'gifenc';\n// gifenc ships dual CJS/ESM with inconsistent interop — named exports may live on the\n// namespace (vite/bundlers) or behind .default (node CJS-ESM interop). Pick whichever has them.\ntype Gifenc = typeof import('gifenc');\nconst { GIFEncoder, quantize, applyPalette } =\n 'GIFEncoder' in gifencMod ? (gifencMod as Gifenc) : (gifencMod as { default: Gifenc }).default;\nimport '../assets/fonts/register.js';\nimport type { CardOptions } from '../types.js';\nimport { GIF_FRAMES, GIF_DELAY_MS, GIF_SCALE } from '../constants.js';\nimport { layout } from './layout.js';\nimport { drawFrame } from './drawFrame.js';\nimport { frameStateFor } from '../animate/index.js';\n\nexport async function renderGIF(opts: CardOptions): Promise<Buffer> {\n const l = layout(opts);\n // draw at full size, encode at half size: smaller files, under Discord limits\n const canvas = createCanvas(l.width, l.height);\n const ctx = canvas.getContext('2d');\n const gw = Math.round(l.width * GIF_SCALE);\n const gh = Math.round(l.height * GIF_SCALE);\n const out = createCanvas(gw, gh);\n const outCtx = out.getContext('2d');\n const enc = GIFEncoder();\n\n const frames = opts.animations.length === 0 ? 1 : GIF_FRAMES;\n\n // For animated GIFs, build palette from progress=0.5: sheen peaks there so\n // highlight colours absent from frame 0 are represented. For static (1 frame),\n // skip the pre-render and derive the palette from the single rendered frame.\n let palette: ReturnType<typeof quantize> | undefined;\n if (frames > 1) {\n const paletteState = frameStateFor(opts.animations, 0.5);\n await drawFrame(ctx, l, paletteState);\n outCtx.drawImage(canvas, 0, 0, gw, gh);\n palette = quantize(outCtx.getImageData(0, 0, gw, gh).data, 256);\n }\n\n for (let i = 0; i < frames; i++) {\n const progress = frames === 1 ? 0 : i / frames;\n const state = frameStateFor(opts.animations, progress);\n await drawFrame(ctx, l, state);\n outCtx.drawImage(canvas, 0, 0, gw, gh);\n const { data } = outCtx.getImageData(0, 0, gw, gh);\n palette ??= quantize(data, 256);\n const index = applyPalette(data, palette);\n enc.writeFrame(index, gw, gh, { palette, delay: GIF_DELAY_MS });\n }\n enc.finish();\n return Buffer.from(enc.bytes());\n}\n","export default {\n signature: \"GIF\",\n version: \"89a\",\n trailer: 0x3B,\n extensionIntroducer: 0x21,\n applicationExtensionLabel: 0xFF,\n graphicControlExtensionLabel: 0xF9,\n imageSeparator: 0x2C,\n // Header\n signatureSize: 3,\n versionSize: 3,\n globalColorTableFlagMask: 0b10000000,\n colorResolutionMask: 0b01110000,\n sortFlagMask: 0b00001000,\n globalColorTableSizeMask: 0b00000111,\n // Application extension\n applicationIdentifierSize: 8,\n applicationAuthCodeSize: 3,\n // Graphic control extension\n disposalMethodMask: 0b00011100,\n userInputFlagMask: 0b00000010,\n transparentColorFlagMask: 0b00000001,\n // Image descriptor\n localColorTableFlagMask: 0b10000000,\n interlaceFlagMask: 0b01000000,\n idSortFlagMask: 0b00100000,\n localColorTableSizeMask: 0b00000111\n}\n","export default function createStream(initialCapacity = 256) {\n let cursor = 0;\n let contents = new Uint8Array(initialCapacity);\n\n return {\n get buffer() {\n return contents.buffer;\n },\n reset() {\n cursor = 0;\n },\n bytesView() {\n return contents.subarray(0, cursor);\n },\n bytes() {\n return contents.slice(0, cursor);\n },\n writeByte(byte) {\n expand(cursor + 1);\n contents[cursor] = byte;\n cursor++;\n },\n writeBytes(data, offset = 0, byteLength = data.length) {\n expand(cursor + byteLength);\n for (let i = 0; i < byteLength; i++) {\n contents[cursor++] = data[i + offset];\n }\n },\n writeBytesView(data, offset = 0, byteLength = data.byteLength) {\n expand(cursor + byteLength);\n contents.set(data.subarray(offset, offset + byteLength), cursor);\n cursor += byteLength;\n },\n };\n\n function expand(newCapacity) {\n var prevCapacity = contents.length;\n if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough.\n // Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity.\n // For small filesizes (<1MB), perform size*2 geometric increase, but for large sizes, do a much more conservative size*1.125 increase to\n // avoid overshooting the allocation cap by a very large margin.\n var CAPACITY_DOUBLING_MAX = 1024 * 1024;\n newCapacity = Math.max(\n newCapacity,\n (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) >>>\n 0\n );\n if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.\n const oldContents = contents;\n contents = new Uint8Array(newCapacity); // Allocate new storage.\n if (cursor > 0) contents.set(oldContents.subarray(0, cursor), 0);\n }\n}\n","/*\n LZWEncoder.js\n Authors\n Kevin Weiner (original Java version - kweiner@fmsware.com)\n Thibault Imbert (AS3 version - bytearray.org)\n Johan Nordberg (JS version - code@johan-nordberg.com)\n Acknowledgements\n GIFCOMPR.C - GIF Image compression routines\n Lempel-Ziv compression based on 'compress'. GIF modifications by\n David Rowley (mgardi@watdcsu.waterloo.edu)\n GIF Image compression - modified 'compress'\n Based on: compress.c - File compression ala IEEE Computer, June 1984.\n By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)\n Jim McKie (decvax!mcvax!jim)\n Steve Davies (decvax!vax135!petsd!peora!srd)\n Ken Turkowski (decvax!decwrl!turtlevax!ken)\n James A. Woods (decvax!ihnp4!ames!jaw)\n Joe Orost (decvax!vax135!petsd!joe)\n Matt DesLauriers (@mattdesl - V8/JS optimizations)\n Mathieu Henri (@p01 - JS optimization)\n*/\n\nimport createStream from \"./stream.js\";\n\nconst EOF = -1;\nconst BITS = 12;\nconst DEFAULT_HSIZE = 5003; // 80% occupancy\nconst MASKS = [\n 0x0000,\n 0x0001,\n 0x0003,\n 0x0007,\n 0x000f,\n 0x001f,\n 0x003f,\n 0x007f,\n 0x00ff,\n 0x01ff,\n 0x03ff,\n 0x07ff,\n 0x0fff,\n 0x1fff,\n 0x3fff,\n 0x7fff,\n 0xffff,\n];\n\nfunction lzwEncode(\n width,\n height,\n pixels,\n colorDepth,\n outStream = createStream(512),\n accum = new Uint8Array(256),\n htab = new Int32Array(DEFAULT_HSIZE),\n codetab = new Int32Array(DEFAULT_HSIZE)\n) {\n const hsize = htab.length;\n const initCodeSize = Math.max(2, colorDepth);\n\n accum.fill(0);\n codetab.fill(0);\n htab.fill(-1);\n\n let cur_accum = 0;\n let cur_bits = 0;\n\n // Algorithm: use open addressing double hashing (no chaining) on the\n // prefix code / next character combination. We do a variant of Knuth's\n // algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime\n // secondary probe. Here, the modular division first probe is gives way\n // to a faster exclusive-or manipulation. Also do block compression with\n // an adaptive reset, whereby the code table is cleared when the compression\n // ratio decreases, but after the table fills. The variable-length output\n // codes are re-sized at this point, and a special CLEAR code is generated\n // for the decompressor. Late addition: construct the table according to\n // file size for noticeable speed improvement on small files. Please direct\n // questions about this implementation to ames!jaw.\n\n // compress and write the pixel data\n const init_bits = initCodeSize + 1;\n\n // Set up the globals: g_init_bits - initial number of bits\n const g_init_bits = init_bits;\n\n // Set up the necessary values\n\n // block compression parameters -- after all codes are used up,\n // and compression rate changes, start over.\n let clear_flg = false;\n let n_bits = g_init_bits;\n let maxcode = (1 << n_bits) - 1;\n\n const ClearCode = 1 << (init_bits - 1);\n const EOFCode = ClearCode + 1;\n let free_ent = ClearCode + 2;\n let a_count = 0; // clear packet\n\n let ent = pixels[0];\n\n let hshift = 0;\n for (let fcode = hsize; fcode < 65536; fcode *= 2) {\n ++hshift;\n }\n hshift = 8 - hshift; // set hash code range bound\n\n outStream.writeByte(initCodeSize); // write \"initial code size\" byte\n\n output(ClearCode);\n\n const length = pixels.length;\n for (let idx = 1; idx < length; idx++) {\n next_block: {\n const c = pixels[idx];\n const fcode = (c << BITS) + ent;\n let i = (c << hshift) ^ ent; // xor hashing\n if (htab[i] === fcode) {\n ent = codetab[i];\n break next_block;\n }\n\n const disp = i === 0 ? 1 : hsize - i; // secondary hash (after G. Knott)\n while (htab[i] >= 0) {\n // non-empty slot\n i -= disp;\n if (i < 0) i += hsize;\n if (htab[i] === fcode) {\n ent = codetab[i];\n break next_block;\n }\n }\n output(ent);\n ent = c;\n if (free_ent < 1 << BITS) {\n codetab[i] = free_ent++; // code -> hashtable\n htab[i] = fcode;\n } else {\n // Clear out the hash table\n // table clear for block compress\n htab.fill(-1);\n free_ent = ClearCode + 2;\n clear_flg = true;\n output(ClearCode);\n }\n }\n }\n\n // Put out the final code.\n output(ent);\n output(EOFCode);\n\n outStream.writeByte(0); // write block terminator\n return outStream.bytesView();\n\n function output(code) {\n cur_accum &= MASKS[cur_bits];\n\n if (cur_bits > 0) cur_accum |= code << cur_bits;\n else cur_accum = code;\n\n cur_bits += n_bits;\n\n while (cur_bits >= 8) {\n // Add a character to the end of the current packet, and if it is 254\n // characters, flush the packet to disk.\n accum[a_count++] = cur_accum & 0xff;\n if (a_count >= 254) {\n outStream.writeByte(a_count);\n outStream.writeBytesView(accum, 0, a_count);\n a_count = 0;\n }\n cur_accum >>= 8;\n cur_bits -= 8;\n }\n\n // If the next entry is going to be too big for the code size,\n // then increase it, if possible.\n if (free_ent > maxcode || clear_flg) {\n if (clear_flg) {\n n_bits = g_init_bits;\n maxcode = (1 << n_bits) - 1;\n clear_flg = false;\n } else {\n ++n_bits;\n maxcode = n_bits === BITS ? (1 << n_bits) : (1 << n_bits) - 1;\n }\n }\n\n if (code == EOFCode) {\n // At EOF, write the rest of the buffer.\n while (cur_bits > 0) {\n // Add a character to the end of the current packet, and if it is 254\n // characters, flush the packet to disk.\n accum[a_count++] = cur_accum & 0xff;\n if (a_count >= 254) {\n outStream.writeByte(a_count);\n outStream.writeBytesView(accum, 0, a_count);\n a_count = 0;\n }\n cur_accum >>= 8;\n cur_bits -= 8;\n }\n // Flush the packet to disk, and reset the accumulator\n if (a_count > 0) {\n outStream.writeByte(a_count);\n outStream.writeBytesView(accum, 0, a_count);\n a_count = 0;\n }\n }\n }\n}\n\nexport default lzwEncode;\n","export function uint32_to_rgba(color) {\n var a = (color >> 24) & 0xff;\n var b = (color >> 16) & 0xff;\n var g = (color >> 8) & 0xff;\n var r = color & 0xff;\n return [r, g, b, a];\n}\n\nexport function rgba_to_uint32(r, g, b, a) {\n return (a << 24) | (b << 16) | (g << 8) | r;\n}\n\nexport function rgb888_to_rgb565(r, g, b) {\n return ((r << 8) & 0xf800) | ((g << 2) & 0x03e0) | (b >> 3);\n}\n\nexport function rgba8888_to_rgba4444(r, g, b, a) {\n return (r >> 4) | (g & 0xf0) | ((b & 0xf0) << 4) | ((a & 0xf0) << 8);\n}\n\nexport function rgb888_to_rgb444(r, g, b) {\n return ((r >> 4) << 8) | (g & 0xf0) | (b >> 4);\n}\n\n// Alternative 565 ?\n// return ((r & 0xf8) << 8) + ((g & 0xfc) << 3) + (b >> 3);\n\n// Alternative 4444 ?\n// ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | (g & 0xf0) | (b >> 4);\n","// Modified from:\n// https://github.com/mcychan/PnnQuant.js/blob/master/src/pnnquant.js\n\n/* Fast pairwise nearest neighbor based algorithm for multilevel thresholding\nCopyright (C) 2004-2019 Mark Tyler and Dmitry Groshev\nCopyright (c) 2018-2021 Miller Cy Chan\n* error measure; time used is proportional to number of bins squared - WJ */\n\nimport {\n rgb888_to_rgb565,\n rgb888_to_rgb444,\n rgba8888_to_rgba4444,\n} from \"./rgb-packing.js\";\n\nfunction clamp(value, min, max) {\n return value < min ? min : value > max ? max : value;\n}\n\nfunction sqr(value) {\n return value * value;\n}\n\nfunction find_nn(bins, idx, hasAlpha) {\n var nn = 0;\n var err = 1e100;\n\n const bin1 = bins[idx];\n const n1 = bin1.cnt;\n const wa = bin1.ac;\n const wr = bin1.rc;\n const wg = bin1.gc;\n const wb = bin1.bc;\n for (var i = bin1.fw; i != 0; i = bins[i].fw) {\n const bin = bins[i];\n const n2 = bin.cnt;\n const nerr2 = (n1 * n2) / (n1 + n2);\n if (nerr2 >= err) continue;\n\n var nerr = 0;\n if (hasAlpha) {\n nerr += nerr2 * sqr(bin.ac - wa);\n if (nerr >= err) continue;\n }\n\n nerr += nerr2 * sqr(bin.rc - wr);\n if (nerr >= err) continue;\n\n nerr += nerr2 * sqr(bin.gc - wg);\n if (nerr >= err) continue;\n\n nerr += nerr2 * sqr(bin.bc - wb);\n if (nerr >= err) continue;\n err = nerr;\n nn = i;\n }\n bin1.err = err;\n bin1.nn = nn;\n}\n\nfunction create_bin() {\n return {\n ac: 0,\n rc: 0,\n gc: 0,\n bc: 0,\n cnt: 0,\n nn: 0,\n fw: 0,\n bk: 0,\n tm: 0,\n mtm: 0,\n err: 0,\n };\n}\n\nfunction bin_add_rgb(bin, r, g, b) {\n bin.rc += r;\n bin.gc += g;\n bin.bc += b;\n bin.cnt++;\n}\n\nfunction create_bin_list(data, format) {\n const bincount = format === \"rgb444\" ? 4096 : 65536;\n const bins = new Array(bincount);\n const size = data.length;\n\n /* Build histogram */\n // Note: Instead of introducing branching/conditions\n // within a very hot per-pixel iteration, we just duplicate the code\n // for each new condition\n if (format === \"rgba4444\") {\n for (let i = 0; i < size; ++i) {\n const color = data[i];\n const a = (color >> 24) & 0xff;\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n\n // reduce to rgb4444 16-bit uint\n const index = rgba8888_to_rgba4444(r, g, b, a);\n let bin = index in bins ? bins[index] : (bins[index] = create_bin());\n bin.rc += r;\n bin.gc += g;\n bin.bc += b;\n bin.ac += a;\n bin.cnt++;\n }\n }\n \n else if (format === \"rgb444\") {\n for (let i = 0; i < size; ++i) {\n const color = data[i];\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n\n // reduce to rgb444 12-bit uint\n const index = rgb888_to_rgb444(r, g, b);\n let bin = index in bins ? bins[index] : (bins[index] = create_bin());\n bin.rc += r;\n bin.gc += g;\n bin.bc += b;\n bin.cnt++;\n }\n } else {\n for (let i = 0; i < size; ++i) {\n const color = data[i];\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n\n // reduce to rgb565 16-bit uint\n const index = rgb888_to_rgb565(r, g, b);\n let bin = index in bins ? bins[index] : (bins[index] = create_bin());\n bin.rc += r;\n bin.gc += g;\n bin.bc += b;\n bin.cnt++;\n }\n }\n return bins;\n}\n\nexport default function quantize(rgba, maxColors, opts = {}) {\n const {\n format = \"rgb565\",\n clearAlpha = true,\n clearAlphaColor = 0x00,\n clearAlphaThreshold = 0,\n oneBitAlpha = false,\n } = opts;\n\n if (!rgba || !rgba.buffer) {\n throw new Error('quantize() expected RGBA Uint8Array data');\n }\n if (!(rgba instanceof Uint8Array) && !(rgba instanceof Uint8ClampedArray)) {\n throw new Error('quantize() expected RGBA Uint8Array data');\n }\n \n const data = new Uint32Array(rgba.buffer);\n\n let useSqrt = opts.useSqrt !== false;\n\n // format can be:\n // rgb565 (default)\n // rgb444\n // rgba4444\n\n const hasAlpha = format === \"rgba4444\";\n const bins = create_bin_list(data, format);\n const bincount = bins.length;\n const bincountMinusOne = bincount - 1;\n const heap = new Uint32Array(bincount + 1);\n\n /* Cluster nonempty bins at one end of array */\n var maxbins = 0;\n for (var i = 0; i < bincount; ++i) {\n const bin = bins[i];\n if (bin != null) {\n var d = 1.0 / bin.cnt;\n if (hasAlpha) bin.ac *= d;\n bin.rc *= d;\n bin.gc *= d;\n bin.bc *= d;\n bins[maxbins++] = bin;\n }\n }\n\n if (sqr(maxColors) / maxbins < 0.022) {\n useSqrt = false;\n }\n\n var i = 0;\n for (; i < maxbins - 1; ++i) {\n bins[i].fw = i + 1;\n bins[i + 1].bk = i;\n if (useSqrt) bins[i].cnt = Math.sqrt(bins[i].cnt);\n }\n if (useSqrt) bins[i].cnt = Math.sqrt(bins[i].cnt);\n\n var h, l, l2;\n /* Initialize nearest neighbors and build heap of them */\n for (i = 0; i < maxbins; ++i) {\n find_nn(bins, i, false);\n /* Push slot on heap */\n var err = bins[i].err;\n for (l = ++heap[0]; l > 1; l = l2) {\n l2 = l >> 1;\n if (bins[(h = heap[l2])].err <= err) break;\n heap[l] = h;\n }\n heap[l] = i;\n }\n\n /* Merge bins which increase error the least */\n var extbins = maxbins - maxColors;\n for (i = 0; i < extbins; ) {\n var tb;\n /* Use heap to find which bins to merge */\n for (;;) {\n var b1 = heap[1];\n tb = bins[b1]; /* One with least error */\n /* Is stored error up to date? */\n if (tb.tm >= tb.mtm && bins[tb.nn].mtm <= tb.tm) break;\n if (tb.mtm == bincountMinusOne)\n /* Deleted node */ b1 = heap[1] = heap[heap[0]--];\n /* Too old error value */ else {\n find_nn(bins, b1, false);\n tb.tm = i;\n }\n /* Push slot down */\n var err = bins[b1].err;\n for (l = 1; (l2 = l + l) <= heap[0]; l = l2) {\n if (l2 < heap[0] && bins[heap[l2]].err > bins[heap[l2 + 1]].err) l2++;\n if (err <= bins[(h = heap[l2])].err) break;\n heap[l] = h;\n }\n heap[l] = b1;\n }\n\n /* Do a merge */\n var nb = bins[tb.nn];\n var n1 = tb.cnt;\n var n2 = nb.cnt;\n var d = 1.0 / (n1 + n2);\n if (hasAlpha) tb.ac = d * (n1 * tb.ac + n2 * nb.ac);\n tb.rc = d * (n1 * tb.rc + n2 * nb.rc);\n tb.gc = d * (n1 * tb.gc + n2 * nb.gc);\n tb.bc = d * (n1 * tb.bc + n2 * nb.bc);\n tb.cnt += nb.cnt;\n tb.mtm = ++i;\n\n /* Unchain deleted bin */\n bins[nb.bk].fw = nb.fw;\n bins[nb.fw].bk = nb.bk;\n nb.mtm = bincountMinusOne;\n }\n\n // let palette = new Uint32Array(maxColors);\n let palette = [];\n\n /* Fill palette */\n var k = 0;\n for (i = 0; ; ++k) {\n let r = clamp(Math.round(bins[i].rc), 0, 0xff);\n let g = clamp(Math.round(bins[i].gc), 0, 0xff);\n let b = clamp(Math.round(bins[i].bc), 0, 0xff);\n\n let a = 0xff;\n if (hasAlpha) {\n a = clamp(Math.round(bins[i].ac), 0, 0xff);\n if (oneBitAlpha) {\n const threshold = typeof oneBitAlpha === \"number\" ? oneBitAlpha : 127;\n a = a <= threshold ? 0x00 : 0xff;\n }\n if (clearAlpha && a <= clearAlphaThreshold) {\n r = g = b = clearAlphaColor;\n a = 0x00;\n }\n }\n\n const color = hasAlpha ? [r, g, b, a] : [r, g, b];\n const exists = existsInPalette(palette, color);\n if (!exists) palette.push(color);\n if ((i = bins[i].fw) == 0) break;\n }\n\n return palette;\n}\n\nfunction existsInPalette(palette, color) {\n for (let i = 0; i < palette.length; i++) {\n const p = palette[i];\n let matchesRGB =\n p[0] === color[0] && p[1] === color[1] && p[2] === color[2];\n let matchesAlpha =\n p.length >= 4 && color.length >= 4 ? p[3] === color[3] : true;\n if (matchesRGB && matchesAlpha) return true;\n }\n return false;\n}\n\n// TODO: Further 'clean' palette by merging nearly-identical colors?\n","function rgb2y(r, g, b) {\n return r * 0.29889531 + g * 0.58662247 + b * 0.11448223;\n}\nfunction rgb2i(r, g, b) {\n return r * 0.59597799 - g * 0.2741761 - b * 0.32180189;\n}\nfunction rgb2q(r, g, b) {\n return r * 0.21147017 - g * 0.52261711 + b * 0.31114694;\n}\n\nexport function colorDifferenceYIQSquared(yiqA, yiqB) {\n const y = yiqA[0] - yiqB[0];\n const i = yiqA[1] - yiqB[1];\n const q = yiqA[2] - yiqB[2];\n const a = alpha(yiqA) - alpha(yiqB);\n return y * y * 0.5053 + i * i * 0.299 + q * q * 0.1957 + a * a;\n}\n\nfunction alpha(array) {\n return array[3] != null ? array[3] : 0xff;\n}\n\nexport function colorDifferenceYIQ(yiqA, yiqB) {\n return Math.sqrt(colorDifferenceYIQSquared(yiqA, yiqB));\n}\n\nexport function colorDifferenceRGBToYIQSquared(rgb1, rgb2) {\n const [r1, g1, b1] = rgb1;\n const [r2, g2, b2] = rgb2;\n const y = rgb2y(r1, g1, b1) - rgb2y(r2, g2, b2),\n i = rgb2i(r1, g1, b1) - rgb2i(r2, g2, b2),\n q = rgb2q(r1, g1, b1) - rgb2q(r2, g2, b2);\n const a = alpha(rgb1) - alpha(rgb2);\n return y * y * 0.5053 + i * i * 0.299 + q * q * 0.1957 + a * a;\n}\n\nexport function colorDifferenceRGBToYIQ(rgb1, rgb2) {\n return Math.sqrt(colorDifferenceRGBToYIQSquared(rgb1, rgb2));\n}\n\nexport function euclideanDistanceSquared(a, b) {\n var sum = 0;\n var n;\n for (n = 0; n < a.length; n++) {\n const dx = a[n] - b[n];\n sum += dx * dx;\n }\n return sum;\n}\n\nexport function euclideanDistance(a, b) {\n return Math.sqrt(euclideanDistanceSquared(a, b));\n}\n","import {\n rgb888_to_rgb444,\n rgb888_to_rgb565,\n rgba8888_to_rgba4444,\n} from \"./rgb-packing.js\";\n\nimport { euclideanDistanceSquared } from \"./color.js\";\n\nfunction roundStep(byte, step) {\n return step > 1 ? Math.round(byte / step) * step : byte;\n}\n\nexport function prequantize(\n rgba,\n { roundRGB = 5, roundAlpha = 10, oneBitAlpha = null } = {}\n) {\n const data = new Uint32Array(rgba.buffer);\n for (let i = 0; i < data.length; i++) {\n const color = data[i];\n let a = (color >> 24) & 0xff;\n let b = (color >> 16) & 0xff;\n let g = (color >> 8) & 0xff;\n let r = color & 0xff;\n\n a = roundStep(a, roundAlpha);\n if (oneBitAlpha) {\n const threshold = typeof oneBitAlpha === \"number\" ? oneBitAlpha : 127;\n a = a <= threshold ? 0x00 : 0xff;\n }\n r = roundStep(r, roundRGB);\n g = roundStep(g, roundRGB);\n b = roundStep(b, roundRGB);\n\n data[i] = (a << 24) | (b << 16) | (g << 8) | (r << 0);\n }\n}\n\nexport function applyPalette(rgba, palette, format = \"rgb565\") {\n if (!rgba || !rgba.buffer) {\n throw new Error('quantize() expected RGBA Uint8Array data');\n }\n if (!(rgba instanceof Uint8Array) && !(rgba instanceof Uint8ClampedArray)) {\n throw new Error('quantize() expected RGBA Uint8Array data');\n }\n if (palette.length > 256) {\n throw new Error('applyPalette() only works with 256 colors or less');\n }\n\n const data = new Uint32Array(rgba.buffer);\n const length = data.length;\n const bincount = format === \"rgb444\" ? 4096 : 65536;\n const index = new Uint8Array(length);\n const cache = new Array(bincount);\n const hasAlpha = format === \"rgba4444\";\n\n // Some duplicate code below due to very hot code path\n // Introducing branching/conditions shows some significant impact\n if (format === \"rgba4444\") {\n for (let i = 0; i < length; i++) {\n const color = data[i];\n const a = (color >> 24) & 0xff;\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n const key = rgba8888_to_rgba4444(r, g, b, a);\n const idx = key in cache ? cache[key] : (cache[key] = nearestColorIndexRGBA(r, g, b, a, palette));\n index[i] = idx;\n }\n } else {\n const rgb888_to_key = format === \"rgb444\" ? rgb888_to_rgb444 : rgb888_to_rgb565;\n for (let i = 0; i < length; i++) {\n const color = data[i];\n const b = (color >> 16) & 0xff;\n const g = (color >> 8) & 0xff;\n const r = color & 0xff;\n const key = rgb888_to_key(r, g, b);\n const idx = key in cache ? cache[key] : (cache[key] = nearestColorIndexRGB(r, g, b, palette));\n index[i] = idx;\n }\n }\n\n return index;\n}\n\nfunction nearestColorIndexRGBA(r, g, b, a, palette) {\n let k = 0;\n let mindist = 1e100;\n for (let i = 0; i < palette.length; i++) {\n const px2 = palette[i];\n const a2 = px2[3];\n let curdist = sqr(a2 - a);\n if (curdist > mindist) continue;\n const r2 = px2[0];\n curdist += sqr(r2 - r);\n if (curdist > mindist) continue;\n const g2 = px2[1];\n curdist += sqr(g2 - g);\n if (curdist > mindist) continue;\n const b2 = px2[2];\n curdist += sqr(b2 - b);\n if (curdist > mindist) continue;\n mindist = curdist;\n k = i;\n }\n return k;\n}\n\nfunction nearestColorIndexRGB(r, g, b, palette) {\n let k = 0;\n let mindist = 1e100;\n for (let i = 0; i < palette.length; i++) {\n const px2 = palette[i];\n const r2 = px2[0];\n let curdist = sqr(r2 - r);\n if (curdist > mindist) continue;\n const g2 = px2[1];\n curdist += sqr(g2 - g);\n if (curdist > mindist) continue;\n const b2 = px2[2];\n curdist += sqr(b2 - b);\n if (curdist > mindist) continue;\n mindist = curdist;\n k = i;\n }\n return k;\n}\n\nexport function snapColorsToPalette(palette, knownColors, threshold = 5) {\n if (!palette.length || !knownColors.length) return;\n\n const paletteRGB = palette.map((p) => p.slice(0, 3));\n const thresholdSq = threshold * threshold;\n const dim = palette[0].length;\n for (let i = 0; i < knownColors.length; i++) {\n let color = knownColors[i];\n if (color.length < dim) {\n // palette is RGBA, known is RGB\n color = [color[0], color[1], color[2], 0xff];\n } else if (color.length > dim) {\n // palette is RGB, known is RGBA\n color = color.slice(0, 3);\n } else {\n // make sure we always copy known colors\n color = color.slice();\n }\n const r = nearestColorIndexWithDistance(\n paletteRGB,\n color.slice(0, 3),\n euclideanDistanceSquared\n );\n const idx = r[0];\n const distanceSq = r[1];\n if (distanceSq > 0 && distanceSq <= thresholdSq) {\n palette[idx] = color;\n }\n }\n}\n\nfunction sqr(a) {\n return a * a;\n}\n\nexport function nearestColorIndex(\n colors,\n pixel,\n distanceFn = euclideanDistanceSquared\n) {\n let minDist = Infinity;\n let minDistIndex = -1;\n for (let j = 0; j < colors.length; j++) {\n const paletteColor = colors[j];\n const dist = distanceFn(pixel, paletteColor);\n if (dist < minDist) {\n minDist = dist;\n minDistIndex = j;\n }\n }\n return minDistIndex;\n}\n\nexport function nearestColorIndexWithDistance(\n colors,\n pixel,\n distanceFn = euclideanDistanceSquared\n) {\n let minDist = Infinity;\n let minDistIndex = -1;\n for (let j = 0; j < colors.length; j++) {\n const paletteColor = colors[j];\n const dist = distanceFn(pixel, paletteColor);\n if (dist < minDist) {\n minDist = dist;\n minDistIndex = j;\n }\n }\n return [minDistIndex, minDist];\n}\n\nexport function nearestColor(\n colors,\n pixel,\n distanceFn = euclideanDistanceSquared\n) {\n return colors[nearestColorIndex(colors, pixel, distanceFn)];\n}\n","import constants from \"./constants.js\";\nimport lzwEncode from \"./lzwEncode.js\";\nimport createStream from \"./stream.js\";\nimport quantize from \"./pnnquant2.js\";\n\nimport {\n prequantize,\n applyPalette,\n nearestColorIndex,\n nearestColor,\n nearestColorIndexWithDistance,\n snapColorsToPalette,\n} from \"./palettize.js\";\n\nfunction GIFEncoder(opt = {}) {\n const { initialCapacity = 4096, auto = true } = opt;\n\n // Stream all encoded data into this buffer\n const stream = createStream(initialCapacity);\n\n // Shared array data across all frames\n const HSIZE = 5003; // 80% occupancy\n const accum = new Uint8Array(256);\n const htab = new Int32Array(HSIZE);\n const codetab = new Int32Array(HSIZE);\n\n let hasInit = false;\n\n return {\n reset() {\n stream.reset();\n hasInit = false;\n },\n finish() {\n stream.writeByte(constants.trailer);\n },\n bytes() {\n return stream.bytes();\n },\n bytesView() {\n return stream.bytesView();\n },\n get buffer() {\n return stream.buffer;\n },\n get stream() {\n return stream;\n },\n writeHeader,\n writeFrame(index, width, height, opts = {}) {\n const {\n transparent = false,\n transparentIndex = 0x00,\n delay = 0,\n palette = null,\n repeat = 0, // -1=once, 0=forever, >0=count\n colorDepth = 8,\n dispose = -1,\n } = opts;\n\n let first = false;\n if (auto) {\n // In 'auto' mode, the first time we write a frame\n // we will write LSD/GCT/EXT\n if (!hasInit) {\n // have not yet init, we can consider this our first frame\n first = true;\n // in 'auto' mode, we also encode a header on first frame\n // this is different than manual mode where you must encode\n // header yoursef (or perhaps not write header altogether)\n writeHeader();\n hasInit = true;\n }\n } else {\n // in manual mode, the first frame is determined by the options only\n first = Boolean(opts.first);\n }\n\n width = Math.max(0, Math.floor(width));\n height = Math.max(0, Math.floor(height));\n\n // Write pre-frame details such as repeat count and global palette\n if (first) {\n if (!palette) {\n throw new Error(\"First frame must include a { palette } option\");\n }\n encodeLogicalScreenDescriptor(\n stream,\n width,\n height,\n palette,\n colorDepth\n );\n encodeColorTable(stream, palette);\n if (repeat >= 0) {\n encodeNetscapeExt(stream, repeat);\n }\n }\n\n const delayTime = Math.round(delay / 10);\n encodeGraphicControlExt(\n stream,\n dispose,\n delayTime,\n transparent,\n transparentIndex\n );\n\n const useLocalColorTable = Boolean(palette) && !first;\n encodeImageDescriptor(\n stream,\n width,\n height,\n useLocalColorTable ? palette : null\n );\n if (useLocalColorTable) encodeColorTable(stream, palette);\n encodePixels(\n stream,\n index,\n width,\n height,\n colorDepth,\n accum,\n htab,\n codetab\n );\n },\n };\n\n function writeHeader() {\n writeUTFBytes(stream, \"GIF89a\");\n }\n}\n\nfunction encodeGraphicControlExt(\n stream,\n dispose,\n delay,\n transparent,\n transparentIndex\n) {\n stream.writeByte(0x21); // extension introducer\n stream.writeByte(0xf9); // GCE label\n stream.writeByte(4); // data block size\n\n if (transparentIndex < 0) {\n transparentIndex = 0x00;\n transparent = false;\n }\n\n var transp, disp;\n if (!transparent) {\n transp = 0;\n disp = 0; // dispose = no action\n } else {\n transp = 1;\n disp = 2; // force clear if using transparent color\n }\n\n if (dispose >= 0) {\n disp = dispose & 7; // user override\n }\n\n disp <<= 2;\n\n const userInput = 0;\n\n // packed fields\n stream.writeByte(\n 0 | // 1:3 reserved\n disp | // 4:6 disposal\n userInput | // 7 user input - 0 = none\n transp // 8 transparency flag\n );\n\n writeUInt16(stream, delay); // delay x 1/100 sec\n stream.writeByte(transparentIndex || 0x00); // transparent color index\n stream.writeByte(0); // block terminator\n}\n\nfunction encodeLogicalScreenDescriptor(\n stream,\n width,\n height,\n palette,\n colorDepth = 8\n) {\n const globalColorTableFlag = 1;\n const sortFlag = 0;\n const globalColorTableSize = colorTableSize(palette.length) - 1;\n const fields =\n (globalColorTableFlag << 7) |\n ((colorDepth - 1) << 4) |\n (sortFlag << 3) |\n globalColorTableSize;\n const backgroundColorIndex = 0;\n const pixelAspectRatio = 0;\n writeUInt16(stream, width);\n writeUInt16(stream, height);\n stream.writeBytes([fields, backgroundColorIndex, pixelAspectRatio]);\n}\n\nfunction encodeNetscapeExt(stream, repeat) {\n stream.writeByte(0x21); // extension introducer\n stream.writeByte(0xff); // app extension label\n stream.writeByte(11); // block size\n writeUTFBytes(stream, \"NETSCAPE2.0\"); // app id + auth code\n stream.writeByte(3); // sub-block size\n stream.writeByte(1); // loop sub-block id\n writeUInt16(stream, repeat); // loop count (extra iterations, 0=repeat forever)\n stream.writeByte(0); // block terminator\n}\n\nfunction encodeColorTable(stream, palette) {\n const colorTableLength = 1 << colorTableSize(palette.length);\n for (let i = 0; i < colorTableLength; i++) {\n let color = [0, 0, 0];\n if (i < palette.length) {\n color = palette[i];\n }\n stream.writeByte(color[0]);\n stream.writeByte(color[1]);\n stream.writeByte(color[2]);\n }\n}\n\nfunction encodeImageDescriptor(stream, width, height, localPalette) {\n stream.writeByte(0x2c); // image separator\n\n writeUInt16(stream, 0); // x position\n writeUInt16(stream, 0); // y position\n writeUInt16(stream, width); // image size\n writeUInt16(stream, height);\n\n if (localPalette) {\n const interlace = 0;\n const sorted = 0;\n const palSize = colorTableSize(localPalette.length) - 1;\n // local palette\n stream.writeByte(\n 0x80 | // 1 local color table 1=yes\n interlace | // 2 interlace - 0=no\n sorted | // 3 sorted - 0=no\n 0 | // 4-5 reserved\n palSize // 6-8 size of color table\n );\n } else {\n // global palette\n stream.writeByte(0);\n }\n}\n\nfunction encodePixels(\n stream,\n index,\n width,\n height,\n colorDepth = 8,\n accum,\n htab,\n codetab\n) {\n lzwEncode(width, height, index, colorDepth, stream, accum, htab, codetab);\n}\n\n// Utilities\n\nfunction writeUInt16(stream, short) {\n stream.writeByte(short & 0xff);\n stream.writeByte((short >> 8) & 0xff);\n}\n\nfunction writeUTFBytes(stream, text) {\n for (var i = 0; i < text.length; i++) {\n stream.writeByte(text.charCodeAt(i));\n }\n}\n\nfunction colorTableSize(length) {\n return Math.max(Math.ceil(Math.log2(length)), 1);\n}\n\nexport {\n GIFEncoder,\n quantize,\n prequantize,\n applyPalette,\n nearestColorIndex,\n nearestColor,\n nearestColorIndexWithDistance,\n snapColorsToPalette,\n};\n\nexport default GIFEncoder;\n","// Ease-out reveal: alpha goes 0 -> 1 over first 70% of timeline.\nexport function textAlpha(progress: number): number {\n const p = Math.min(progress / 0.7, 1);\n return 1 - Math.pow(1 - p, 3);\n}\n","// Pulsing glow 0..1 using a sine wave over the loop.\nexport function avatarGlow(progress: number): number {\n return (Math.sin(progress * Math.PI * 2) + 1) / 2;\n}\n","// Phase 0..1 used by drawFrame to shift the background sheen.\nexport function backgroundShift(progress: number): number {\n return progress;\n}\n","import type { AnimationType } from '../types.js';\nimport type { FrameState } from '../render/drawFrame.js';\nimport { textAlpha } from './text.js';\nimport { avatarGlow } from './avatar.js';\nimport { backgroundShift } from './background.js';\n\nexport function frameStateFor(animations: AnimationType[], progress: number): FrameState {\n return {\n textAlpha: animations.includes('text') ? textAlpha(progress) : 1,\n avatarGlow: animations.includes('avatar') ? avatarGlow(progress) : 1,\n backgroundShift: animations.includes('background') ? backgroundShift(progress) : 0,\n };\n}\n","import type {\n AnimationType,\n CardOptions,\n FontOptions,\n MemberCountPosition,\n PresetName,\n Theme,\n} from './types.js';\nimport { DEFAULT_OPTIONS } from './constants.js';\nimport { PRESETS } from './presets/index.js';\nimport { WelcomeCardError } from './errors.js';\nimport { renderPNG } from './render/toPNG.js';\nimport { renderGIF } from './render/toGIF.js';\n\nexport class WelcomeCard {\n private opts: CardOptions = { ...DEFAULT_OPTIONS };\n\n setPreset(preset: PresetName): this {\n if (!PRESETS[preset]) {\n throw new WelcomeCardError(\n `Unknown preset \"${preset}\". Allowed: ${Object.keys(PRESETS).join(', ')}`,\n );\n }\n this.opts.preset = preset;\n return this;\n }\n\n setUsername(username: string): this {\n this.opts.username = username;\n return this;\n }\n\n setAvatar(avatar: string | Buffer): this {\n this.opts.avatar = avatar;\n return this;\n }\n\n setSubtitle(subtitle: string): this {\n this.opts.subtitle = subtitle;\n return this;\n }\n\n setMemberCount(count: number): this {\n this.opts.memberCount = count;\n return this;\n }\n\n setMemberCountPosition(position: MemberCountPosition): this {\n this.opts.memberCountPosition = position;\n return this;\n }\n\n setBackground(background: string): this {\n this.opts.background = background;\n return this;\n }\n\n setTheme(theme: Theme): this {\n this.opts.theme = theme;\n return this;\n }\n\n setFont(font: FontOptions): this {\n this.opts.font = { ...this.opts.font, ...font };\n return this;\n }\n\n setAnimations(animations: AnimationType[]): this {\n this.opts.animations = animations;\n return this;\n }\n\n private validate(): void {\n if (!this.opts.username) {\n throw new WelcomeCardError('username is required — call .setUsername() before rendering.');\n }\n }\n\n async toPNG(): Promise<Buffer> {\n this.validate();\n return renderPNG(this.opts);\n }\n\n async toGIF(): Promise<Buffer> {\n this.validate();\n if (this.opts.animations.length === 0) {\n console.warn('[welcomecard] toGIF() called with no animations — output will be static.');\n }\n return renderGIF(this.opts);\n }\n}\n"],"mappings":";;;;;AAEO,IAAM,aAAa;AACnB,IAAM,cAAc;AAEpB,IAAM,aAAa;AACnB,IAAM,eAAe;AACrB,IAAM,YAAY;AAElB,IAAM,kBAA+B;AAAA,EAC1C,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM,CAAC;AAAA,EACP,YAAY,CAAC;AACf;;;ACdA,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAC9B,SAAS,SAAS,YAAY;AAC9B,SAAS,kBAAkB;AAE3B,IAAM,OAAO,QAAQ,cAAc,YAAY,GAAG,CAAC;AAInD,IAAM,aAAa;AAAA,EACjB,KAAK,MAAM,kBAAkB;AAAA,EAC7B,KAAK,MAAM,UAAU,SAAS,kBAAkB;AAAA,EAChD,KAAK,MAAM,MAAM,OAAO,UAAU,SAAS,kBAAkB;AAC/D;AAEA,IAAM,WAAW,WAAW,KAAK,UAAU;AAC3C,IAAI,UAAU;AACZ,cAAY,iBAAiB,UAAU,aAAa;AACtD;AAEO,IAAM,sBAAsB;;;AChBnC,IAAM,WAAW;AACjB,IAAM,eAAe;AAEd,SAAS,gBAAgB,YAAsD;AACpF,SAAO,OAAO,eAAe,YAAY,sBAAsB,KAAK,UAAU;AAChF;AAEO,SAAS,uBAAuB,YAAgC,UAA0B;AAC/F,SAAO,gBAAgB,UAAU,IAAI,aAAa;AACpD;AAEO,SAAS,gBACd,UACA,OACA,QAC8D;AAC9D,QAAM,MAAM,aAAa,UAAa,aAAa,WAAW,iBAAiB;AAC/E,QAAM,IAAI,EAAE,MAAM,UAAU,QAAQ,QAAQ,GAAG,OAAO,QAAQ,SAAS;AACvE,QAAM,IAAI,EAAE,KAAK,cAAc,QAAQ,SAAS,GAAG,QAAQ,SAAS,SAAS;AAC7E,UAAQ,KAAK;AAAA,IACX,KAAK;AAAiB,aAAO,EAAE,GAAG,EAAE,MAAQ,GAAG,EAAE,KAAQ,OAAO,OAAS;AAAA,IACzE,KAAK;AAAiB,aAAO,EAAE,GAAG,EAAE,QAAS,GAAG,EAAE,KAAQ,OAAO,SAAS;AAAA,IAC1E,KAAK;AAAiB,aAAO,EAAE,GAAG,EAAE,OAAS,GAAG,EAAE,KAAQ,OAAO,QAAS;AAAA,IAC1E,KAAK;AAAiB,aAAO,EAAE,GAAG,EAAE,MAAQ,GAAG,EAAE,QAAQ,OAAO,OAAS;AAAA,IACzE,KAAK;AAAiB,aAAO,EAAE,GAAG,EAAE,QAAS,GAAG,EAAE,QAAQ,OAAO,SAAS;AAAA,IAC1E,KAAK;AAAiB,aAAO,EAAE,GAAG,EAAE,OAAS,GAAG,EAAE,QAAQ,OAAO,QAAS;AAAA,IAC1E,KAAK;AAAiB,aAAO,EAAE,GAAG,EAAE,MAAQ,GAAG,EAAE,QAAQ,OAAO,OAAS;AAAA,IACzE,KAAK;AAAiB,aAAO,EAAE,GAAG,EAAE,QAAS,GAAG,EAAE,QAAQ,OAAO,SAAS;AAAA,IAC1E,KAAK;AAAiB,aAAO,EAAE,GAAG,EAAE,OAAS,GAAG,EAAE,QAAQ,OAAO,QAAS;AAAA,IAC1E,SAAS;AACP,YAAM,aAAoB;AAC1B,YAAM,IAAI,MAAM,mCAAmC,UAAoB,GAAG;AAAA,IAC5E;AAAA,EACF;AACF;AAuBO,SAAS,eAAe,MAAiC;AAC9D,QAAM,QAAQ;AACd,QAAM,SAAS;AACf,QAAM,SAAS,KAAK,UAAU,SAAS,YAAY;AACnD,QAAM,UAAU;AAAA,IACd,KAAK;AAAA,IACL,KAAK,UAAU,SAAS,YAAY;AAAA,EACtC;AACA,QAAM,YAAY,KAAK,KAAK,UAAU,KAAK,UAAU,SAAS,YAAY;AAC1E,QAAM,SAAS,KAAK,KAAK,UAAU;AAEnC,QAAM,aAAa;AACnB,QAAM,UAAU;AAEhB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,iBAAiB;AAAA,IACjB,YAAY,gBAAgB,KAAK,UAAU,IAAI,SAAY,KAAK;AAAA,IAChE,QAAQ;AAAA,MACN,GAAG,QAAQ,IAAI,aAAa;AAAA,MAC5B,GAAG;AAAA,MACH,MAAM;AAAA,MACN,WAAW;AAAA,MACX,QAAQ,KAAK;AAAA,IACf;AAAA,IACA,UAAU;AAAA,MACR,MAAM,KAAK,YAAY;AAAA,MACvB,GAAG,QAAQ;AAAA,MACX,GAAG,UAAU,aAAa;AAAA,MAC1B,MAAM,KAAK,KAAK,QAAQ;AAAA,MACxB,OAAO;AAAA,MACP;AAAA,MACA,OAAO;AAAA,IACT;AAAA,IACA,UAAU,KAAK,WACX;AAAA,MACE,MAAM,KAAK;AAAA,MACX,GAAG,QAAQ;AAAA,MACX,GAAG,UAAU,aAAa;AAAA,MAC1B,MAAM,KAAK,KAAK,gBAAgB,KAAK,OAAO,KAAK,KAAK,QAAQ,MAAM,IAAI;AAAA,MACxE,OAAO;AAAA,MACP;AAAA,MACA,OAAO;AAAA,IACT,IACA;AAAA,IACJ,aACE,KAAK,gBAAgB,SACjB;AAAA,MACE,MAAM,WAAW,KAAK,WAAW;AAAA;AAAA,MAEjC,GAAG,gBAAgB,KAAK,uBAAuB,iBAAiB,OAAO,MAAM;AAAA,MAC7E,MAAM;AAAA,MACN,OAAO;AAAA,MACP;AAAA,IACF,IACA;AAAA,EACR;AACF;;;ACnHO,SAAS,WAAW,MAAiC;AAC1D,QAAM,OAAO,eAAe,IAAI;AAChC,SAAO;AAAA,IACL,GAAG;AAAA,IACH,iBAAiB,uBAAuB,KAAK,YAAY,SAAS;AAAA,IAClE,QAAQ,EAAE,GAAG,KAAK,QAAQ,WAAW,UAAU;AAAA,IAC/C,UAAU,EAAE,GAAG,KAAK,UAAU,OAAO,KAAK,KAAK,SAAS,UAAU;AAAA,EACpE;AACF;;;ACRO,SAAS,cAAc,MAAiC;AAC7D,QAAM,OAAO,eAAe,IAAI;AAChC,SAAO;AAAA,IACL,GAAG;AAAA,IACH,iBAAiB,uBAAuB,KAAK,YAAY,SAAS;AAAA,IAClE,QAAQ,EAAE,GAAG,KAAK,QAAQ,WAAW,UAAU;AAAA,IAC/C,UAAU,EAAE,GAAG,KAAK,UAAU,OAAO,KAAK,KAAK,SAAS,UAAU;AAAA,IAClE,UAAU,KAAK,WAAW,EAAE,GAAG,KAAK,UAAU,OAAO,UAAU,IAAI;AAAA,EACrE;AACF;;;ACRO,SAAS,WAAW,MAAiC;AAC1D,QAAM,OAAO,eAAe,IAAI;AAChC,QAAM,UAAU;AAChB,QAAM,QAAQ,UAAU,KAAK,OAAO,OAAO;AAC3C,SAAO;AAAA,IACL,GAAG;AAAA,IACH,iBAAiB;AAAA,MACf,KAAK;AAAA,MACL,KAAK,UAAU,SAAS,YAAY;AAAA,IACtC;AAAA,IACA,QAAQ,EAAE,GAAG,KAAK,QAAQ,GAAG,SAAS,GAAG,KAAK,SAAS,IAAI,KAAK,OAAO,OAAO,EAAE;AAAA,IAChF,UAAU,EAAE,GAAG,KAAK,UAAU,GAAG,OAAO,GAAG,KAAK,SAAS,IAAI,IAAI,OAAO,OAAO;AAAA,IAC/E,UAAU,KAAK,WACX,EAAE,GAAG,KAAK,UAAU,GAAG,OAAO,GAAG,KAAK,SAAS,IAAI,IAAI,OAAO,OAAO,IACrE;AAAA,IACJ,aAAa,KAAK;AAAA;AAAA,MAEd;AAAA,QACE,GAAG,KAAK;AAAA,QACR,GAAG,gBAAgB,KAAK,uBAAuB,gBAAgB,KAAK,OAAO,KAAK,MAAM;AAAA,MACxF;AAAA,QACA;AAAA,EACN;AACF;;;ACnBO,IAAM,UAAwC;AAAA,EACnD,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AACR;;;ACdO,IAAM,mBAAN,cAA+B,MAAM;AAAA,EAC1C,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;;;ACLA,SAAS,gBAAAA,qBAAoB;;;ACItB,SAAS,OAAO,MAAiC;AACtD,QAAM,KAAK,QAAQ,KAAK,MAAM;AAC9B,MAAI,CAAC,IAAI;AACP,UAAM,IAAI;AAAA,MACR,mBAAmB,KAAK,MAAM,eAAe,OAAO,KAAK,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,IAC9E;AAAA,EACF;AACA,SAAO,GAAG,IAAI;AAChB;;;ACZA,SAAS,WAAW,oBAAgC;AAEpD,IAAM,YAAY;AAElB,SAAS,WAAc,KAAoB,KAAQ,OAAoB;AACrE,MAAI,IAAI,QAAQ,WAAW;AACzB,QAAI,OAAO,IAAI,KAAK,EAAE,KAAK,EAAE,KAAM;AAAA,EACrC;AACA,MAAI,IAAI,KAAK,KAAK;AACpB;AAGA,IAAM,QAAQ,oBAAI,IAA4B;AAC9C,IAAM,aAAa,oBAAI,IAAmB;AAE1C,eAAe,WAAW,OAAe,GAAW,GAA2B;AAC7E,QAAM,MAAM,GAAG,KAAK,IAAI,CAAC,IAAI,CAAC;AAC9B,QAAM,MAAM,WAAW,IAAI,GAAG;AAC9B,MAAI,IAAK,QAAO;AAChB,QAAM,SAAS,aAAa,GAAG,CAAC;AAChC,QAAM,MAAM,OAAO,WAAW,IAAI;AAClC,MAAI,YAAY;AAChB,MAAI,SAAS,GAAG,GAAG,GAAG,CAAC;AACvB,QAAM,MAAM,MAAM,UAAU,OAAO,SAAS,WAAW,CAAC;AACxD,aAAW,YAAY,KAAK,GAAG;AAC/B,SAAO;AACT;AAEA,eAAsB,oBACpB,QACA,eACA,IAAI,KACJ,IAAI,KACY;AAChB,MAAI,WAAW,OAAW,QAAO,WAAW,eAAe,GAAG,CAAC;AAC/D,QAAM,MAAM,MAAM,IAAI,MAAM;AAC5B,MAAI,IAAK,QAAO;AAChB,MAAI;AACF,UAAM,MAAM,MAAM,UAAU,MAAM;AAClC,eAAW,OAAO,QAAQ,GAAG;AAC7B,WAAO;AAAA,EACT,QAAQ;AACN,WAAO,WAAW,eAAe,GAAG,CAAC;AAAA,EACvC;AACF;;;AClCO,IAAM,eAA2B,EAAE,WAAW,GAAG,YAAY,GAAG,iBAAiB,EAAE;AAE1F,SAAS,SAAS,KAAoB,KAAc,OAAe;AACjE,MAAI,KAAK;AACT,MAAI,cAAc;AAClB,MAAI,YAAY,IAAI;AACpB,MAAI,YAAY,IAAI;AACpB,MAAI,eAAe;AACnB,MAAI,OAAO,GAAG,IAAI,IAAI,MAAM,IAAI,MAAM;AACtC,MAAI,SAAS,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC;AACnC,MAAI,QAAQ;AACd;AAEA,eAAsB,UACpB,KACA,GACA,OACe;AAEf,MAAI,YAAY,EAAE;AAClB,MAAI,SAAS,GAAG,GAAG,EAAE,OAAO,EAAE,MAAM;AACpC,MAAI,EAAE,eAAe,QAAW;AAC9B,UAAM,KAAK,MAAM,oBAAoB,EAAE,YAAY,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM;AACvF,QAAI,UAAU,IAAI,GAAG,GAAG,EAAE,OAAO,EAAE,MAAM;AAAA,EAC3C;AACA,MAAI,MAAM,kBAAkB,GAAG;AAE7B,UAAMC,MAAK,MAAM,kBAAkB,IAAI,KAAK,EAAE,QAAQ;AACtD,UAAM,IAAI,IAAI,qBAAqBA,IAAG,GAAGA,KAAI,EAAE,OAAO,EAAE,MAAM;AAC9D,MAAE,aAAa,GAAG,qBAAqB;AACvC,MAAE,aAAa,KAAK,wBAAwB;AAC5C,MAAE,aAAa,GAAG,qBAAqB;AACvC,QAAI,YAAY;AAChB,QAAI,SAAS,GAAG,GAAG,EAAE,OAAO,EAAE,MAAM;AAAA,EACtC;AAGA,QAAM,EAAE,GAAG,GAAG,MAAM,UAAU,IAAI,EAAE;AACpC,QAAM,KAAK,IAAI,OAAO;AACtB,QAAM,KAAK,IAAI,OAAO;AACtB,MAAI,KAAK;AACT,MAAI,cAAc;AAClB,MAAI,aAAa,KAAK,MAAM,aAAa;AACzC,MAAI,YAAY;AAChB,MAAI,cAAc;AAClB,MAAI,UAAU;AACd,MAAI,IAAI,IAAI,IAAI,OAAO,IAAI,GAAG,GAAG,KAAK,KAAK,CAAC;AAC5C,MAAI,OAAO;AACX,MAAI,QAAQ;AAEZ,QAAM,YAAY,MAAM,oBAAoB,EAAE,OAAO,QAAQ,WAAW,MAAM,IAAI;AAClF,MAAI,KAAK;AACT,MAAI,UAAU;AACd,MAAI,IAAI,IAAI,IAAI,OAAO,GAAG,GAAG,KAAK,KAAK,CAAC;AACxC,MAAI,KAAK;AACT,MAAI,UAAU,WAAW,GAAG,GAAG,MAAM,IAAI;AACzC,MAAI,QAAQ;AAGZ,WAAS,KAAK,EAAE,UAAU,MAAM,SAAS;AACzC,MAAI,EAAE,SAAU,UAAS,KAAK,EAAE,UAAU,MAAM,SAAS;AACzD,MAAI,EAAE,YAAa,UAAS,KAAK,EAAE,aAAa,MAAM,SAAS;AACjE;;;AHlEA,eAAsB,UAAU,MAAoC;AAClE,QAAM,IAAI,OAAO,IAAI;AACrB,QAAM,SAASC,cAAa,EAAE,OAAO,EAAE,MAAM;AAC7C,QAAM,MAAM,OAAO,WAAW,IAAI;AAClC,QAAM,UAAU,KAAK,GAAG,YAAY;AACpC,SAAO,OAAO,SAAS,WAAW;AACpC;;;AIZA,SAAS,gBAAAC,qBAAoB;;;ACA7B;;;;;;;;;;;;AAAA,IAAO,IAAQ,EACb,WAAW,OACX,SAAS,OACT,SAAS,IACT,qBAAqB,IACrB,2BAA2B,KAC3B,8BAA8B,KAC9B,gBAAgB,IAEhB,eAAe,GACf,aAAa,GACb,0BAA0B,KAC1B,qBAAqB,KACrB,cAAc,GACd,0BAA0B,GAE1B,2BAA2B,GAC3B,yBAAyB,GAEzB,oBAAoB,IACpB,mBAAmB,GACnB,0BAA0B,GAE1B,yBAAyB,KACzB,mBAAmB,IACnB,gBAAgB,IAChB,yBAAyB,EAAA;AC1BZ,SAAA,EAAsB,IAAkB,KAAK;AAC1D,MAAI,IAAS,GACT,IAAW,IAAI,WAAW,CAAA;AAE9B,SAAO,EAAA,IACD,SAAS;AACX,WAAO,EAAS;EAAA,GAElB,QAAQ;AACN,QAAS;EAAA,GAEX,YAAY;AACV,WAAO,EAAS,SAAS,GAAG,CAAA;EAAA,GAE9B,QAAQ;AACN,WAAO,EAAS,MAAM,GAAG,CAAA;EAAA,GAE3B,UAAU,GAAM;AACd,MAAO,IAAS,CAAA,GAChB,EAAS,CAAA,IAAU,GACnB;EAAA,GAEF,WAAW,GAAM,IAAS,GAAG,IAAa,EAAK,QAAQ;AACrD,MAAO,IAAS,CAAA;AAChB,aAAS,IAAI,GAAG,IAAI,GAAY,IAC9B,GAAS,GAAA,IAAY,EAAK,IAAI,CAAA;EAAA,GAGlC,eAAe,GAAM,IAAS,GAAG,IAAa,EAAK,YAAY;AAC7D,MAAO,IAAS,CAAA,GAChB,EAAS,IAAI,EAAK,SAAS,GAAQ,IAAS,CAAA,GAAa,CAAA,GACzD,KAAU;EAAA,EAAA;AAId,WAAA,EAAgB,GAAa;AAC3B,QAAI,IAAe,EAAS;AAC5B,QAAI,KAAgB,EAAa;AAIjC,QAAI,IAAwB,OAAO;AACnC,QAAc,KAAK,IACjB,GACC,KAAgB,IAAe,IAAwB,IAAM,WAC5D,CAAA,GAEA,KAAgB,MAAG,IAAc,KAAK,IAAI,GAAa,GAAA;AAC3D,QAAM,IAAc;AACpB,QAAW,IAAI,WAAW,CAAA,GACtB,IAAS,KAAG,EAAS,IAAI,EAAY,SAAS,GAAG,CAAA,GAAS,CAAA;EAAA;AAAA;ACzBlE,IAAM,IAAO;AAAb,IACM,IAAgB;AADtB,IAEM,KAAQ,CACZ,GACA,GACA,GACA,GACA,IACA,IACA,IACA,KACA,KACA,KACA,MACA,MACA,MACA,MACA,OACA,OACA,KAAA;AAGF,SAAA,GACE,GACA,GACA,GACA,GACA,IAAY,EAAa,GAAA,GACzB,IAAQ,IAAI,WAAW,GAAA,GACvB,IAAO,IAAI,WAAW,CAAA,GACtB,IAAU,IAAI,WAAW,CAAA,GACzB;AACA,MAAM,IAAQ,EAAK,QACb,IAAe,KAAK,IAAI,GAAG,CAAA;AAEjC,IAAM,KAAK,CAAA,GACX,EAAQ,KAAK,CAAA,GACb,EAAK,KAAK,EAAA;AAEV,MAAI,IAAY,GACZ,IAAW,GAeT,IAAY,IAAe,GAG3B,IAAc,GAMhB,IAAY,OACZ,IAAS,GACT,KAAW,KAAK,KAAU,GAExB,IAAY,KAAM,IAAY,GAC9B,IAAU,IAAY,GACxB,IAAW,IAAY,GACvB,IAAU,GAEV,IAAM,EAAO,CAAA,GAEb,IAAS;AACb,WAAS,IAAQ,GAAO,IAAQ,OAAO,KAAS,EAC9C,GAAE;AAEJ,MAAS,IAAI,GAEb,EAAU,UAAU,CAAA,GAEpB,EAAO,CAAA;AAEP,MAAM,IAAS,EAAO;AACtB,WAAS,IAAM,GAAG,IAAM,GAAQ,KAAO;AACrC,OAAY;AACV,UAAM,IAAI,EAAO,CAAA,GACX,KAAS,KAAK,KAAQ,GACxB,IAAK,KAAK,IAAU;AACxB,UAAI,EAAK,CAAA,MAAO,GAAO;AACrB,YAAM,EAAQ,CAAA;AACd,cAAA;MAAA;AAGF,UAAM,IAAO,MAAM,IAAI,IAAI,IAAQ;AACnC,aAAO,EAAK,CAAA,KAAM,IAIhB,KAFA,KAAK,GACD,IAAI,MAAG,KAAK,IACZ,EAAK,CAAA,MAAO,GAAO;AACrB,YAAM,EAAQ,CAAA;AACd,cAAA;MAAA;AAGJ,QAAO,CAAA,GACP,IAAM,GACF,IAAW,KAAK,KAClB,EAAQ,CAAA,IAAK,KACb,EAAK,CAAA,IAAK,MAIV,EAAK,KAAK,EAAA,GACV,IAAW,IAAY,GACvB,IAAY,MACZ,EAAO,CAAA;IAAA;EAAA;AAMb,SAAA,EAAO,CAAA,GACP,EAAO,CAAA,GAEP,EAAU,UAAU,CAAA,GACb,EAAU,UAAA;AAEjB,WAAA,EAAgB,GAAM;AAQpB,SAPA,KAAa,GAAM,CAAA,GAEf,IAAW,IAAG,KAAa,KAAQ,IAClC,IAAY,GAEjB,KAAY,GAEL,KAAY,IAGjB,GAAM,GAAA,IAAa,IAAY,KAC3B,KAAW,QACb,EAAU,UAAU,CAAA,GACpB,EAAU,eAAe,GAAO,GAAG,CAAA,GACnC,IAAU,IAEZ,MAAc,GACd,KAAY;AAgBd,SAXI,IAAW,KAAW,OACpB,KACF,IAAS,GACT,KAAW,KAAK,KAAU,GAC1B,IAAY,UAEZ,EAAE,GACF,IAAU,MAAW,IAAQ,KAAK,KAAW,KAAK,KAAU,KAI5D,KAAQ,GAAS;AAEnB,aAAO,IAAW,IAGhB,GAAM,GAAA,IAAa,IAAY,KAC3B,KAAW,QACb,EAAU,UAAU,CAAA,GACpB,EAAU,eAAe,GAAO,GAAG,CAAA,GACnC,IAAU,IAEZ,MAAc,GACd,KAAY;AAGV,UAAU,MACZ,EAAU,UAAU,CAAA,GACpB,EAAU,eAAe,GAAO,GAAG,CAAA,GACnC,IAAU;IAAA;EAAA;AAAA;AAMlB,IAAO,IAAQ;ACxMR,SAAA,EAA0B,GAAG,GAAG,GAAG;AACxC,SAAS,KAAK,IAAK,QAAY,KAAK,IAAK,MAAW,KAAK;AAAA;AAGpD,SAAA,EAA8B,GAAG,GAAG,GAAG,GAAG;AAC/C,SAAQ,KAAK,IAAM,IAAI,OAAU,IAAI,QAAS,KAAO,IAAI,QAAS;AAAA;AAG7D,SAAA,EAA0B,GAAG,GAAG,GAAG;AACxC,SAAS,KAAK,KAAM,IAAM,IAAI,MAAS,KAAK;AAAA;ACP9C,SAAA,EAAe,GAAO,GAAK,GAAK;AAC9B,SAAO,IAAQ,IAAM,IAAM,IAAQ,IAAM,IAAM;AAAA;AAGjD,SAAA,EAAa,GAAO;AAClB,SAAO,IAAQ;AAAA;AAGjB,SAAA,GAAiB,GAAM,GAAK,GAAU;AACpC,MAAI,IAAK,GACL,IAAM;AAEV,MAAM,IAAO,EAAK,CAAA,GACZ,IAAK,EAAK,KACV,IAAK,EAAK,IACV,IAAK,EAAK,IACV,IAAK,EAAK,IACV,IAAK,EAAK;AAChB,WAAS,IAAI,EAAK,IAAI,KAAK,GAAG,IAAI,EAAK,CAAA,EAAG,IAAI;AAC5C,QAAM,IAAM,EAAK,CAAA,GACX,IAAK,EAAI,KACT,IAAS,IAAK,KAAO,IAAK;AAChC,QAAI,EAAA,KAAS,IAEb;AAAA,UAAI,IAAO;AACP,YACF,KAAQ,IAAQ,EAAI,EAAI,KAAK,CAAA,GACzB,KAAQ,OAGd,KAAQ,IAAQ,EAAI,EAAI,KAAK,CAAA,GACzB,EAAA,KAAQ,OAEZ,KAAQ,IAAQ,EAAI,EAAI,KAAK,CAAA,GACzB,EAAA,KAAQ,OAEZ,KAAQ,IAAQ,EAAI,EAAI,KAAK,CAAA,GACzB,EAAA,KAAQ,OACZ,IAAM,GACN,IAAK;IAAA;EAAA;AAEP,IAAK,MAAM,GACX,EAAK,KAAK;AAAA;AAGZ,SAAA,IAAsB;AACpB,SAAO,EACL,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,KAAK,GACL,KAAK,EAAA;AAAA;AAWT,SAAA,GAAyB,GAAM,GAAQ;AACrC,MAAM,IAAW,MAAW,WAAW,OAAO,OACxC,IAAO,IAAI,MAAM,CAAA,GACjB,IAAO,EAAK;AAMlB,MAAI,MAAW,WACb,UAAS,IAAI,GAAG,IAAI,GAAM,EAAE,GAAG;AAC7B,QAAM,IAAQ,EAAK,CAAA,GACb,IAAK,KAAS,KAAM,KACpB,IAAK,KAAS,KAAM,KACpB,IAAK,KAAS,IAAK,KACnB,IAAI,IAAQ,KAGZ,IAAQ,EAAqB,GAAG,GAAG,GAAG,CAAA,GACxC,IAAM,KAAS,IAAO,EAAK,CAAA,IAAU,EAAK,CAAA,IAAS,EAAA;AACvD,MAAI,MAAM,GACV,EAAI,MAAM,GACV,EAAI,MAAM,GACV,EAAI,MAAM,GACV,EAAI;EAAA;WAIC,MAAW,SAClB,UAAS,IAAI,GAAG,IAAI,GAAM,EAAE,GAAG;AAC7B,QAAM,IAAQ,EAAK,CAAA,GACb,IAAK,KAAS,KAAM,KACpB,IAAK,KAAS,IAAK,KACnB,IAAI,IAAQ,KAGZ,IAAQ,EAAiB,GAAG,GAAG,CAAA,GACjC,IAAM,KAAS,IAAO,EAAK,CAAA,IAAU,EAAK,CAAA,IAAS,EAAA;AACvD,MAAI,MAAM,GACV,EAAI,MAAM,GACV,EAAI,MAAM,GACV,EAAI;EAAA;MAGN,UAAS,IAAI,GAAG,IAAI,GAAM,EAAE,GAAG;AAC7B,QAAM,IAAQ,EAAK,CAAA,GACb,IAAK,KAAS,KAAM,KACpB,IAAK,KAAS,IAAK,KACnB,IAAI,IAAQ,KAGZ,IAAQ,EAAiB,GAAG,GAAG,CAAA,GACjC,IAAM,KAAS,IAAO,EAAK,CAAA,IAAU,EAAK,CAAA,IAAS,EAAA;AACvD,MAAI,MAAM,GACV,EAAI,MAAM,GACV,EAAI,MAAM,GACV,EAAI;EAAA;AAGR,SAAO;AAAA;AAGM,SAAA,EAAkB,GAAM,GAAW,IAAO,CAAA,GAAI;AAC3D,MAAM,EACJ,QAAA,IAAS,UACT,YAAA,IAAa,MACb,iBAAA,IAAkB,GAClB,qBAAA,IAAsB,GACtB,aAAA,IAAc,MAAA,IACZ;AAEJ,MAAI,CAAC,KAAQ,CAAC,EAAK,OACjB,OAAM,IAAI,MAAM,0CAAA;AAElB,MAAI,EAAE,aAAgB,eAAe,EAAE,aAAgB,mBACrD,OAAM,IAAI,MAAM,0CAAA;AAGlB,MAAM,IAAO,IAAI,YAAY,EAAK,MAAA,GAE9B,IAAU,EAAK,YAAY,OAOzB,IAAW,MAAW,YACtB,IAAO,GAAgB,GAAM,CAAA,GAC7B,IAAW,EAAK,QAChB,IAAmB,IAAW,GAC9B,IAAO,IAAI,YAAY,IAAW,CAAA;AAIxC,WADI,IAAU,GACL,IAAI,GAAG,IAAI,GAAU,EAAE,GAAG;AACjC,QAAM,IAAM,EAAK,CAAA;AACjB,QAAI,KAAO,MAAM;AACf,UAAI,IAAI,IAAM,EAAI;AACd,YAAU,EAAI,MAAM,IACxB,EAAI,MAAM,GACV,EAAI,MAAM,GACV,EAAI,MAAM,GACV,EAAK,GAAA,IAAa;IAAA;EAAA;AAIlB,IAAI,CAAA,IAAa,IAAU,UAC7B,IAAU;AAIZ,WADI,IAAI,GACD,IAAI,IAAU,GAAG,EAAE,EACxB,GAAK,CAAA,EAAG,KAAK,IAAI,GACjB,EAAK,IAAI,CAAA,EAAG,KAAK,GACb,MAAS,EAAK,CAAA,EAAG,MAAM,KAAK,KAAK,EAAK,CAAA,EAAG,GAAA;AAE3C,QAAS,EAAK,CAAA,EAAG,MAAM,KAAK,KAAK,EAAK,CAAA,EAAG,GAAA;AAE7C,MAAI,GAAG,GAAG;AAEV,OAAK,IAAI,GAAG,IAAI,GAAS,EAAE,GAAG;AAC5B,OAAQ,GAAM,GAAG,KAAA;AAEjB,QAAI,IAAM,EAAK,CAAA,EAAG;AAClB,SAAK,IAAI,EAAE,EAAK,CAAA,GAAI,IAAI,MACtB,IAAK,KAAK,GACN,EAAA,EAAM,IAAI,EAAK,CAAA,CAAA,EAAM,OAAO,KAFP,IAAI,EAG7B,GAAK,CAAA,IAAK;AAEZ,MAAK,CAAA,IAAK;EAAA;AAIZ,MAAI,IAAU,IAAU;AACxB,OAAK,IAAI,GAAG,IAAI,KAAW;AAGzB,aAFI,OAEK;AACP,UAAI,IAAK,EAAK,CAAA;AAGd,UAFA,IAAK,EAAK,CAAA,GAEN,EAAG,MAAM,EAAG,OAAO,EAAK,EAAG,EAAA,EAAI,OAAO,EAAG,GAAI;AAC7C,QAAG,OAAO,IACO,IAAK,EAAK,CAAA,IAAK,EAAK,EAAK,CAAA,GAAA,KAE5C,GAAQ,GAAM,GAAI,KAAA,GAClB,EAAG,KAAK;AAGV,UAAI,IAAM,EAAK,CAAA,EAAI;AACnB,WAAK,IAAI,IAAI,IAAK,IAAI,MAAM,EAAK,CAAA,MAC3B,IAAK,EAAK,CAAA,KAAM,EAAK,EAAK,CAAA,CAAA,EAAK,MAAM,EAAK,EAAK,IAAK,CAAA,CAAA,EAAI,OAAK,KAC7D,EAAA,KAAO,EAAM,IAAI,EAAK,CAAA,CAAA,EAAM,OAFG,IAAI,EAGvC,GAAK,CAAA,IAAK;AAEZ,QAAK,CAAA,IAAK;IAAA;AAIZ,QAAI,IAAK,EAAK,EAAG,EAAA,GACb,IAAK,EAAG,KACR,IAAK,EAAG,KACR,IAAI,KAAO,IAAK;AAChB,UAAU,EAAG,KAAK,KAAK,IAAK,EAAG,KAAK,IAAK,EAAG,MAChD,EAAG,KAAK,KAAK,IAAK,EAAG,KAAK,IAAK,EAAG,KAClC,EAAG,KAAK,KAAK,IAAK,EAAG,KAAK,IAAK,EAAG,KAClC,EAAG,KAAK,KAAK,IAAK,EAAG,KAAK,IAAK,EAAG,KAClC,EAAG,OAAO,EAAG,KACb,EAAG,MAAM,EAAE,GAGX,EAAK,EAAG,EAAA,EAAI,KAAK,EAAG,IACpB,EAAK,EAAG,EAAA,EAAI,KAAK,EAAG,IACpB,EAAG,MAAM;EAAA;AAIX,MAAI,IAAU,CAAA;AAGd,MAAI,IAAI;AACR,OAAK,IAAI,KAAK,EAAE,GAAG;AACjB,QAAI,IAAI,EAAM,KAAK,MAAM,EAAK,CAAA,EAAG,EAAA,GAAK,GAAG,GAAA,GACrC,IAAI,EAAM,KAAK,MAAM,EAAK,CAAA,EAAG,EAAA,GAAK,GAAG,GAAA,GACrC,IAAI,EAAM,KAAK,MAAM,EAAK,CAAA,EAAG,EAAA,GAAK,GAAG,GAAA,GAErC,IAAI;AACR,QAAI,GAAU;AAEZ,UADA,IAAI,EAAM,KAAK,MAAM,EAAK,CAAA,EAAG,EAAA,GAAK,GAAG,GAAA,GACjC,GAAa;AACf,YAAM,KAAY,OAAO,KAAgB,WAAW,IAAc;AAClE,YAAI,KAAK,KAAY,IAAO;MAAA;AAE1B,WAAc,KAAK,MACrB,IAAI,IAAI,IAAI,GACZ,IAAI;IAAA;AAIR,QAAM,IAAQ,IAAW,CAAC,GAAG,GAAG,GAAG,CAAA,IAAK,CAAC,GAAG,GAAG,CAAA;AAG/C,QAFe,GAAgB,GAAS,CAAA,KAC3B,EAAQ,KAAK,CAAA,IACrB,IAAI,EAAK,CAAA,EAAG,OAAO,EAAG;EAAA;AAG7B,SAAO;AAAA;AAGT,SAAA,GAAyB,GAAS,GAAO;AACvC,WAAS,IAAI,GAAG,IAAI,EAAQ,QAAQ,KAAK;AACvC,QAAM,IAAI,EAAQ,CAAA,GACd,IACF,EAAE,CAAA,MAAO,EAAM,CAAA,KAAM,EAAE,CAAA,MAAO,EAAM,CAAA,KAAM,EAAE,CAAA,MAAO,EAAM,CAAA,GACvD,IACF,EAAE,UAAU,KAAK,EAAM,UAAU,IAAI,EAAE,CAAA,MAAO,EAAM,CAAA,IAAK;AAC3D,QAAI,KAAc,EAAc,QAAO;EAAA;AAEzC,SAAO;AAAA;ACpQF,SAAA,EAAkC,GAAG,GAAG;AAC7C,MAAI,IAAM,GACN;AACJ,OAAK,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AAC7B,QAAM,IAAK,EAAE,CAAA,IAAK,EAAE,CAAA;AACpB,SAAO,IAAK;EAAA;AAEd,SAAO;AAAA;ACvCT,SAAA,EAAmB,GAAM,GAAM;AAC7B,SAAO,IAAO,IAAI,KAAK,MAAM,IAAO,CAAA,IAAQ,IAAO;AAAA;AAG9C,SAAA,GACL,GACA,EAAE,UAAA,IAAW,GAAG,YAAA,IAAa,IAAI,aAAA,IAAc,KAAA,IAAS,CAAA,GACxD;AACA,MAAM,IAAO,IAAI,YAAY,EAAK,MAAA;AAClC,WAAS,IAAI,GAAG,IAAI,EAAK,QAAQ,KAAK;AACpC,QAAM,IAAQ,EAAK,CAAA,GACf,IAAK,KAAS,KAAM,KACpB,IAAK,KAAS,KAAM,KACpB,IAAK,KAAS,IAAK,KACnB,IAAI,IAAQ;AAGhB,QADA,IAAI,EAAU,GAAG,CAAA,GACb,GAAa;AACf,UAAM,IAAY,OAAO,KAAgB,WAAW,IAAc;AAClE,UAAI,KAAK,IAAY,IAAO;IAAA;AAE9B,QAAI,EAAU,GAAG,CAAA,GACjB,IAAI,EAAU,GAAG,CAAA,GACjB,IAAI,EAAU,GAAG,CAAA,GAEjB,EAAK,CAAA,IAAM,KAAK,KAAO,KAAK,KAAO,KAAK,IAAM,KAAK;EAAA;AAAA;AAIhD,SAAA,GAAsB,GAAM,GAAS,IAAS,UAAU;AAC7D,MAAI,CAAC,KAAQ,CAAC,EAAK,OACjB,OAAM,IAAI,MAAM,0CAAA;AAElB,MAAI,EAAE,aAAgB,eAAe,EAAE,aAAgB,mBACrD,OAAM,IAAI,MAAM,0CAAA;AAElB,MAAI,EAAQ,SAAS,IACnB,OAAM,IAAI,MAAM,mDAAA;AAGlB,MAAM,IAAO,IAAI,YAAY,EAAK,MAAA,GAC5B,IAAS,EAAK,QACd,IAAW,MAAW,WAAW,OAAO,OACxC,IAAQ,IAAI,WAAW,CAAA,GACvB,IAAQ,IAAI,MAAM,CAAA,GAClB,IAAW,MAAW;AAI5B,MAAI,MAAW,WACb,UAAS,IAAI,GAAG,IAAI,GAAQ,KAAK;AAC/B,QAAM,IAAQ,EAAK,CAAA,GACb,IAAK,KAAS,KAAM,KACpB,IAAK,KAAS,KAAM,KACpB,IAAK,KAAS,IAAK,KACnB,IAAI,IAAQ,KACZ,IAAM,EAAqB,GAAG,GAAG,GAAG,CAAA,GACpC,IAAM,KAAO,IAAQ,EAAM,CAAA,IAAQ,EAAM,CAAA,IAAO,GAAsB,GAAG,GAAG,GAAG,GAAG,CAAA;AACxF,MAAM,CAAA,IAAK;EAAA;OAER;AACL,QAAM,IAAgB,MAAW,WAAW,IAAmB;AAC/D,aAAS,IAAI,GAAG,IAAI,GAAQ,KAAK;AAC/B,UAAM,IAAQ,EAAK,CAAA,GACb,IAAK,KAAS,KAAM,KACpB,IAAK,KAAS,IAAK,KACnB,IAAI,IAAQ,KACZ,IAAM,EAAc,GAAG,GAAG,CAAA,GAC1B,IAAM,KAAO,IAAQ,EAAM,CAAA,IAAQ,EAAM,CAAA,IAAO,GAAqB,GAAG,GAAG,GAAG,CAAA;AACpF,QAAM,CAAA,IAAK;IAAA;EAAA;AAIf,SAAO;AAAA;AAGT,SAAA,GAA+B,GAAG,GAAG,GAAG,GAAG,GAAS;AAClD,MAAI,IAAI,GACJ,IAAU;AACd,WAAS,IAAI,GAAG,IAAI,EAAQ,QAAQ,KAAK;AACvC,QAAM,IAAM,EAAQ,CAAA,GACd,IAAK,EAAI,CAAA,GACX,IAAU,EAAI,IAAK,CAAA;AACvB,QAAI,IAAU,EAAS;AACvB,QAAM,IAAK,EAAI,CAAA;AAEf,QADA,KAAW,EAAI,IAAK,CAAA,GAChB,IAAU,EAAS;AACvB,QAAM,IAAK,EAAI,CAAA;AAEf,QADA,KAAW,EAAI,IAAK,CAAA,GAChB,IAAU,EAAS;AACvB,QAAM,IAAK,EAAI,CAAA;AACf,SAAW,EAAI,IAAK,CAAA,GAChB,EAAA,IAAU,OACd,IAAU,GACV,IAAI;EAAA;AAEN,SAAO;AAAA;AAGT,SAAA,GAA8B,GAAG,GAAG,GAAG,GAAS;AAC9C,MAAI,IAAI,GACJ,IAAU;AACd,WAAS,IAAI,GAAG,IAAI,EAAQ,QAAQ,KAAK;AACvC,QAAM,IAAM,EAAQ,CAAA,GACd,IAAK,EAAI,CAAA,GACX,IAAU,EAAI,IAAK,CAAA;AACvB,QAAI,IAAU,EAAS;AACvB,QAAM,IAAK,EAAI,CAAA;AAEf,QADA,KAAW,EAAI,IAAK,CAAA,GAChB,IAAU,EAAS;AACvB,QAAM,IAAK,EAAI,CAAA;AACf,SAAW,EAAI,IAAK,CAAA,GAChB,EAAA,IAAU,OACd,IAAU,GACV,IAAI;EAAA;AAEN,SAAO;AAAA;AAGF,SAAA,GAA6B,GAAS,GAAa,IAAY,GAAG;AACvE,MAAI,CAAC,EAAQ,UAAU,CAAC,EAAY,OAAQ;AAE5C,MAAM,IAAa,EAAQ,IAAK,OAAM,EAAE,MAAM,GAAG,CAAA,CAAA,GAC3C,IAAc,IAAY,GAC1B,IAAM,EAAQ,CAAA,EAAG;AACvB,WAAS,IAAI,GAAG,IAAI,EAAY,QAAQ,KAAK;AAC3C,QAAI,IAAQ,EAAY,CAAA;AACpB,MAAM,SAAS,IAEjB,IAAQ,CAAC,EAAM,CAAA,GAAI,EAAM,CAAA,GAAI,EAAM,CAAA,GAAI,GAAA,IAC9B,EAAM,SAAS,IAExB,IAAQ,EAAM,MAAM,GAAG,CAAA,IAGvB,IAAQ,EAAM,MAAA;AAEhB,QAAM,IAAI,EACR,GACA,EAAM,MAAM,GAAG,CAAA,GACf,CAAA,GAEI,IAAM,EAAE,CAAA,GACR,IAAa,EAAE,CAAA;AACjB,QAAa,KAAK,KAAc,MAClC,EAAQ,CAAA,IAAO;EAAA;AAAA;AAKrB,SAAA,EAAa,GAAG;AACd,SAAO,IAAI;AAAA;AAGN,SAAA,EACL,GACA,GACA,IAAa,GACb;AACA,MAAI,IAAU,UACV,IAAe;AACnB,WAAS,IAAI,GAAG,IAAI,EAAO,QAAQ,KAAK;AACtC,QAAM,IAAe,EAAO,CAAA,GACtB,IAAO,EAAW,GAAO,CAAA;AAC3B,QAAO,MACT,IAAU,GACV,IAAe;EAAA;AAGnB,SAAO;AAAA;AAGF,SAAA,EACL,GACA,GACA,IAAa,GACb;AACA,MAAI,IAAU,UACV,IAAe;AACnB,WAAS,IAAI,GAAG,IAAI,EAAO,QAAQ,KAAK;AACtC,QAAM,IAAe,EAAO,CAAA,GACtB,IAAO,EAAW,GAAO,CAAA;AAC3B,QAAO,MACT,IAAU,GACV,IAAe;EAAA;AAGnB,SAAO,CAAC,GAAc,CAAA;AAAA;AAGjB,SAAA,GACL,GACA,GACA,IAAa,GACb;AACA,SAAO,EAAO,EAAkB,GAAQ,GAAO,CAAA,CAAA;AAAA;AC7LjD,SAAA,GAAoB,IAAM,CAAA,GAAI;AAC5B,MAAM,EAAE,iBAAA,IAAkB,MAAM,MAAA,IAAO,KAAA,IAAS,GAG1C,IAAS,EAAa,CAAA,GAGtB,IAAQ,MACR,IAAQ,IAAI,WAAW,GAAA,GACvB,IAAO,IAAI,WAAW,CAAA,GACtB,IAAU,IAAI,WAAW,CAAA,GAE3B,IAAU;AAEd,SAAO,EACL,QAAQ;AACN,MAAO,MAAA,GACP,IAAU;EAAA,GAEZ,SAAS;AACP,MAAO,UAAU,EAAU,OAAA;EAAA,GAE7B,QAAQ;AACN,WAAO,EAAO,MAAA;EAAA,GAEhB,YAAY;AACV,WAAO,EAAO,UAAA;EAAA,GAAA,IAEZ,SAAS;AACX,WAAO,EAAO;EAAA,GAAA,IAEZ,SAAS;AACX,WAAO;EAAA,GAET,aAAA,GACA,WAAW,GAAO,GAAO,GAAQ,IAAO,CAAA,GAAI;AAC1C,QAAM,EACJ,aAAA,IAAc,OACd,kBAAA,IAAmB,GACnB,OAAA,IAAQ,GACR,SAAA,IAAU,MACV,QAAA,IAAS,GACT,YAAA,IAAa,GACb,SAAA,IAAU,GAAA,IACR,GAEA,IAAQ;AAsBZ,QArBI,IAGG,MAEH,IAAQ,MAIR,EAAA,GACA,IAAU,QAIZ,IAAQ,QAAQ,EAAK,KAAA,GAGvB,IAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,CAAA,CAAA,GAC/B,IAAS,KAAK,IAAI,GAAG,KAAK,MAAM,CAAA,CAAA,GAG5B,GAAO;AACT,UAAI,CAAC,EACH,OAAM,IAAI,MAAM,+CAAA;AAElB,SACE,GACA,GACA,GACA,GACA,CAAA,GAEF,GAAiB,GAAQ,CAAA,GACrB,KAAU,KACZ,GAAkB,GAAQ,CAAA;IAAA;AAI9B,QAAM,IAAY,KAAK,MAAM,IAAQ,EAAA;AACrC,OACE,GACA,GACA,GACA,GACA,CAAA;AAGF,QAAM,IAAqB,QAAQ,CAAA,KAAY,CAAC;AAChD,OACE,GACA,GACA,GACA,IAAqB,IAAU,IAAA,GAE7B,KAAoB,GAAiB,GAAQ,CAAA,GACjD,GACE,GACA,GACA,GACA,GACA,GACA,GACA,GACA,CAAA;EAAA,EAAA;AAKN,WAAA,IAAuB;AACrB,OAAc,GAAQ,QAAA;EAAA;AAAA;AAI1B,SAAA,GACE,GACA,GACA,GACA,GACA,GACA;AACA,IAAO,UAAU,EAAA,GACjB,EAAO,UAAU,GAAA,GACjB,EAAO,UAAU,CAAA,GAEb,IAAmB,MACrB,IAAmB,GACnB,IAAc;AAGhB,MAAI,GAAQ;AACP,OAIH,IAAS,GACT,IAAO,MAJP,IAAS,GACT,IAAO,IAML,KAAW,MACb,IAAO,IAAU,IAGnB,MAAS;AAET,MAAM,IAAY;AAGlB,IAAO,UACL,IACE,IACA,IACA,CAAA,GAGJ,EAAY,GAAQ,CAAA,GACpB,EAAO,UAAU,KAAoB,CAAA,GACrC,EAAO,UAAU,CAAA;AAAA;AAGnB,SAAA,GACE,GACA,GACA,GACA,GACA,IAAa,GACb;AACA,MAAM,IAAuB,GACvB,IAAW,GACX,IAAuB,EAAe,EAAQ,MAAA,IAAU,GACxD,IACH,KAAwB,IACvB,IAAa,KAAM,IACpB,KAAY,IACb,GACI,IAAuB,GACvB,IAAmB;AACzB,IAAY,GAAQ,CAAA,GACpB,EAAY,GAAQ,CAAA,GACpB,EAAO,WAAW,CAAC,GAAQ,GAAsB,CAAA,CAAA;AAAA;AAGnD,SAAA,GAA2B,GAAQ,GAAQ;AACzC,IAAO,UAAU,EAAA,GACjB,EAAO,UAAU,GAAA,GACjB,EAAO,UAAU,EAAA,GACjB,GAAc,GAAQ,aAAA,GACtB,EAAO,UAAU,CAAA,GACjB,EAAO,UAAU,CAAA,GACjB,EAAY,GAAQ,CAAA,GACpB,EAAO,UAAU,CAAA;AAAA;AAGnB,SAAA,GAA0B,GAAQ,GAAS;AACzC,MAAM,IAAmB,KAAK,EAAe,EAAQ,MAAA;AACrD,WAAS,IAAI,GAAG,IAAI,GAAkB,KAAK;AACzC,QAAI,IAAQ,CAAC,GAAG,GAAG,CAAA;AACf,QAAI,EAAQ,WACd,IAAQ,EAAQ,CAAA,IAElB,EAAO,UAAU,EAAM,CAAA,CAAA,GACvB,EAAO,UAAU,EAAM,CAAA,CAAA,GACvB,EAAO,UAAU,EAAM,CAAA,CAAA;EAAA;AAAA;AAI3B,SAAA,GAA+B,GAAQ,GAAO,GAAQ,GAAc;AAQlE,MAPA,EAAO,UAAU,EAAA,GAEjB,EAAY,GAAQ,CAAA,GACpB,EAAY,GAAQ,CAAA,GACpB,EAAY,GAAQ,CAAA,GACpB,EAAY,GAAQ,CAAA,GAEhB,GAAc;AAChB,QAAM,IAAY,GACZ,IAAS,GACT,IAAU,EAAe,EAAa,MAAA,IAAU;AAEtD,MAAO,UACL,MACE,IACA,IACA,IACA,CAAA;EAAA,MAIJ,GAAO,UAAU,CAAA;AAAA;AAIrB,SAAA,GACE,GACA,GACA,GACA,GACA,IAAa,GACb,GACA,GACA,GACA;AACA,IAAU,GAAO,GAAQ,GAAO,GAAY,GAAQ,GAAO,GAAM,CAAA;AAAA;AAKnE,SAAA,EAAqB,GAAQ,GAAO;AAClC,IAAO,UAAU,IAAQ,GAAA,GACzB,EAAO,UAAW,KAAS,IAAK,GAAA;AAAA;AAGlC,SAAA,GAAuB,GAAQ,GAAM;AACnC,WAAS,IAAI,GAAG,IAAI,EAAK,QAAQ,IAC/B,GAAO,UAAU,EAAK,WAAW,CAAA,CAAA;AAAA;AAIrC,SAAA,EAAwB,GAAQ;AAC9B,SAAO,KAAK,IAAI,KAAK,KAAK,KAAK,KAAK,CAAA,CAAA,GAAU,CAAA;AAAA;AAchD,IAAO,KAAQ;;;ACpSR,SAAS,UAAU,UAA0B;AAClD,QAAM,IAAI,KAAK,IAAI,WAAW,KAAK,CAAC;AACpC,SAAO,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC;AAC9B;;;ACHO,SAAS,WAAW,UAA0B;AACnD,UAAQ,KAAK,IAAI,WAAW,KAAK,KAAK,CAAC,IAAI,KAAK;AAClD;;;ACFO,SAAS,gBAAgB,UAA0B;AACxD,SAAO;AACT;;;ACGO,SAAS,cAAc,YAA6B,UAA8B;AACvF,SAAO;AAAA,IACL,WAAW,WAAW,SAAS,MAAM,IAAI,UAAU,QAAQ,IAAI;AAAA,IAC/D,YAAY,WAAW,SAAS,QAAQ,IAAI,WAAW,QAAQ,IAAI;AAAA,IACnE,iBAAiB,WAAW,SAAS,YAAY,IAAI,gBAAgB,QAAQ,IAAI;AAAA,EACnF;AACF;;;AZPA,IAAM,EAAE,YAAY,UAAU,aAAa,IACzC,gBAAgB,qBAAa,qBAA0D;AAQzF,eAAsB,UAAU,MAAoC;AAClE,QAAM,IAAI,OAAO,IAAI;AAErB,QAAM,SAASC,cAAa,EAAE,OAAO,EAAE,MAAM;AAC7C,QAAM,MAAM,OAAO,WAAW,IAAI;AAClC,QAAM,KAAK,KAAK,MAAM,EAAE,QAAQ,SAAS;AACzC,QAAM,KAAK,KAAK,MAAM,EAAE,SAAS,SAAS;AAC1C,QAAM,MAAMA,cAAa,IAAI,EAAE;AAC/B,QAAM,SAAS,IAAI,WAAW,IAAI;AAClC,QAAM,MAAM,WAAW;AAEvB,QAAM,SAAS,KAAK,WAAW,WAAW,IAAI,IAAI;AAKlD,MAAI;AACJ,MAAI,SAAS,GAAG;AACd,UAAM,eAAe,cAAc,KAAK,YAAY,GAAG;AACvD,UAAM,UAAU,KAAK,GAAG,YAAY;AACpC,WAAO,UAAU,QAAQ,GAAG,GAAG,IAAI,EAAE;AACrC,cAAU,SAAS,OAAO,aAAa,GAAG,GAAG,IAAI,EAAE,EAAE,MAAM,GAAG;AAAA,EAChE;AAEA,WAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC/B,UAAM,WAAW,WAAW,IAAI,IAAI,IAAI;AACxC,UAAM,QAAQ,cAAc,KAAK,YAAY,QAAQ;AACrD,UAAM,UAAU,KAAK,GAAG,KAAK;AAC7B,WAAO,UAAU,QAAQ,GAAG,GAAG,IAAI,EAAE;AACrC,UAAM,EAAE,KAAK,IAAI,OAAO,aAAa,GAAG,GAAG,IAAI,EAAE;AACjD,gBAAY,SAAS,MAAM,GAAG;AAC9B,UAAM,QAAQ,aAAa,MAAM,OAAO;AACxC,QAAI,WAAW,OAAO,IAAI,IAAI,EAAE,SAAS,OAAO,aAAa,CAAC;AAAA,EAChE;AACA,MAAI,OAAO;AACX,SAAO,OAAO,KAAK,IAAI,MAAM,CAAC;AAChC;;;AapCO,IAAM,cAAN,MAAkB;AAAA,EACf,OAAoB,EAAE,GAAG,gBAAgB;AAAA,EAEjD,UAAU,QAA0B;AAClC,QAAI,CAAC,QAAQ,MAAM,GAAG;AACpB,YAAM,IAAI;AAAA,QACR,mBAAmB,MAAM,eAAe,OAAO,KAAK,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,MACzE;AAAA,IACF;AACA,SAAK,KAAK,SAAS;AACnB,WAAO;AAAA,EACT;AAAA,EAEA,YAAY,UAAwB;AAClC,SAAK,KAAK,WAAW;AACrB,WAAO;AAAA,EACT;AAAA,EAEA,UAAU,QAA+B;AACvC,SAAK,KAAK,SAAS;AACnB,WAAO;AAAA,EACT;AAAA,EAEA,YAAY,UAAwB;AAClC,SAAK,KAAK,WAAW;AACrB,WAAO;AAAA,EACT;AAAA,EAEA,eAAe,OAAqB;AAClC,SAAK,KAAK,cAAc;AACxB,WAAO;AAAA,EACT;AAAA,EAEA,uBAAuB,UAAqC;AAC1D,SAAK,KAAK,sBAAsB;AAChC,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,YAA0B;AACtC,SAAK,KAAK,aAAa;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,OAAoB;AAC3B,SAAK,KAAK,QAAQ;AAClB,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,MAAyB;AAC/B,SAAK,KAAK,OAAO,EAAE,GAAG,KAAK,KAAK,MAAM,GAAG,KAAK;AAC9C,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,YAAmC;AAC/C,SAAK,KAAK,aAAa;AACvB,WAAO;AAAA,EACT;AAAA,EAEQ,WAAiB;AACvB,QAAI,CAAC,KAAK,KAAK,UAAU;AACvB,YAAM,IAAI,iBAAiB,mEAA8D;AAAA,IAC3F;AAAA,EACF;AAAA,EAEA,MAAM,QAAyB;AAC7B,SAAK,SAAS;AACd,WAAO,UAAU,KAAK,IAAI;AAAA,EAC5B;AAAA,EAEA,MAAM,QAAyB;AAC7B,SAAK,SAAS;AACd,QAAI,KAAK,KAAK,WAAW,WAAW,GAAG;AACrC,cAAQ,KAAK,+EAA0E;AAAA,IACzF;AACA,WAAO,UAAU,KAAK,IAAI;AAAA,EAC5B;AACF;","names":["createCanvas","x","createCanvas","createCanvas","createCanvas"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quitscope/discord-welcomecard",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Render Discord welcome cards as static PNG or animated GIF from one builder.",
5
5
  "license": "MIT",
6
6
  "author": "QuitScope",
@@ -35,8 +35,12 @@
35
35
  "require": "./dist/discord.cjs"
36
36
  }
37
37
  },
38
- "files": ["dist"],
39
- "engines": { "node": ">=18" },
38
+ "files": [
39
+ "dist"
40
+ ],
41
+ "engines": {
42
+ "node": ">=18"
43
+ },
40
44
  "scripts": {
41
45
  "build": "tsup",
42
46
  "test": "vitest run",
@@ -52,7 +56,9 @@
52
56
  "discord.js": "^14.0.0"
53
57
  },
54
58
  "peerDependenciesMeta": {
55
- "discord.js": { "optional": true }
59
+ "discord.js": {
60
+ "optional": true
61
+ }
56
62
  },
57
63
  "devDependencies": {
58
64
  "discord.js": "^14.16.0",