@hadoku/task-ui-components 4.23.8 → 4.23.9
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/components/AvatarBuilder.d.ts +6 -3
- package/dist/components/AvatarBuilder.d.ts.map +1 -1
- package/dist/components/AvatarBuilder.js +41 -21
- package/dist/components/AvatarBuilder.js.map +1 -1
- package/dist/components/AvatarDialog.d.ts +3 -1
- package/dist/components/AvatarDialog.d.ts.map +1 -1
- package/dist/components/AvatarDialog.js +8 -2
- package/dist/components/AvatarDialog.js.map +1 -1
- package/dist/components/ConnectedSettings.d.ts.map +1 -1
- package/dist/components/ConnectedSettings.js +2 -1
- package/dist/components/ConnectedSettings.js.map +1 -1
- package/dist/vendor/wolffm/prefs-client/avatar.js.map +1 -1
- package/dist/vendor/wolffm/prefs-client/cosmetics.js +84 -68
- package/dist/vendor/wolffm/prefs-client/cosmetics.js.map +1 -1
- package/package.json +2 -2
- package/src/components/AvatarBuilder.tsx +52 -25
- package/src/components/AvatarDialog.tsx +10 -2
- package/src/components/ConnectedSettings.tsx +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cosmetics.js","sources":["../../../../../node_modules/.pnpm/@wolffm+prefs-client@1.1.13_react@19.2.8_zod@4.6.7/node_modules/@wolffm/prefs-client/dist/cosmetics.js"],"sourcesContent":["// src/cosmetics-contract.ts\nvar COSMETIC_SLOTS = [\"effect\", \"gradient\", \"font\", \"overlay\", \"message\"];\nvar COSMETIC_ID_PATTERN = /^(effect|gradient|font|overlay|message)\\.[a-z0-9-]{1,32}$/;\nvar item = (slot, name, label, earn, art) => ({ id: `${slot}.${name}`, slot, label, earn, ...art ? { art } : {} });\nvar COSMETICS = [\n item(\"effect\", \"glint\", \"Glint\", \"Win a cardtable match\"),\n item(\"effect\", \"aura\", \"Aura\", \"Attend 10 watchparties\"),\n item(\"effect\", \"hop\", \"Hop\", \"Win 25 bomberman rounds\"),\n item(\"effect\", \"outline\", \"Outline\", \"Finish 3 tournaments\"),\n item(\"effect\", \"twinkle\", \"Twinkle\", \"Top four in a Major\"),\n item(\"gradient\", \"gild\", \"Gilded\", \"Your first win in any game\"),\n item(\"gradient\", \"gloss\", \"Gloss\", \"Win 10 games\"),\n item(\"gradient\", \"split\", \"Split\", \"Finish 5 tournaments\"),\n item(\"gradient\", \"brushed\", \"Brushed\", \"Play 100 games\"),\n item(\"gradient\", \"lumen\", \"Lumen\", \"Host 5 watchparties\"),\n item(\"font\", \"caps\", \"Small caps\", \"Finish a tournament\"),\n item(\"font\", \"wide\", \"Wide\", \"Finish 5 tournaments\"),\n item(\"font\", \"script\", \"Script\", \"Attend 25 watchparties\"),\n item(\"font\", \"surf\", \"Surf\", \"Attend a summer watchparty\"),\n item(\"font\", \"gothic\", \"Gothic\", \"Win an arcane-set game\"),\n item(\"font\", \"runic\", \"Runic\", \"Win a fantasy-set game\"),\n item(\"font\", \"corsair\", \"Corsair\", \"Win 3 matches in one night\"),\n item(\"font\", \"metal\", \"Metal\", \"Win a Major final\"),\n item(\"font\", \"comic\", \"Comic\", \"Win from behind\"),\n item(\"font\", \"circuit\", \"Circuit\", \"Play 25 cyber-set games\"),\n item(\"font\", \"hover\", \"Hover\", \"Win a race\"),\n item(\"font\", \"retro\", \"Retro\", \"Play for a year\"),\n item(\"font\", \"arcade\", \"Arcade\", \"Play 50 bomberman games\"),\n item(\"font\", \"pixel\", \"Pixel\", \"Win 10 bomberman rounds\"),\n item(\"overlay\", \"crown\", \"Crown\", \"Win a Major\", {\n file: \"crown.webp\",\n top: -40,\n width: 70,\n tilt: -8,\n pixel: false,\n visible: [0.027, 0.137, 0.973, 0.863]\n }),\n item(\"overlay\", \"halo\", \"Halo\", \"Help a new player (gift)\", {\n file: \"halo.webp\",\n top: -34,\n width: 76,\n tilt: 0,\n pixel: true,\n visible: [0.033, 0.333, 0.967, 0.667]\n }),\n item(\"overlay\", \"horns\", \"Horns\", \"Win 10 games as the villain\", {\n file: \"horns.webp\",\n top: -26,\n width: 100,\n tilt: 0,\n pixel: true,\n visible: [0.033, 0.133, 0.967, 0.867]\n }),\n item(\"overlay\", \"flowers\", \"Flower crown\", \"The anniversary of joining\", {\n file: \"flowers.webp\",\n top: -22,\n width: 96,\n tilt: 0,\n pixel: false,\n visible: [0.027, 0.258, 0.969, 0.746]\n }),\n item(\"overlay\", \"runes\", \"Runes\", \"Finish a Major\"),\n item(\"overlay\", \"comet\", \"Comet\", \"A 10-game win streak\"),\n item(\"overlay\", \"shine\", \"Shine\", \"Win a cardtable match\"),\n item(\"overlay\", \"glow\", \"Glow\", \"Attend 25 watchparties\"),\n item(\"overlay\", \"petals\", \"Petals\", \"The anniversary of joining\"),\n item(\"message\", \"type\", \"Typewriter\", \"Send 1000 chat messages\"),\n item(\"message\", \"decode\", \"Decode\", \"Win 25 cyber-set games\"),\n item(\"message\", \"cascade\", \"Cascade\", \"Win 3 games in a row\"),\n item(\"message\", \"words\", \"Word by word\", \"Send 100 chat messages\"),\n item(\"message\", \"bubble\", \"Bubble\", \"Host 3 watchparties\"),\n item(\"message\", \"drift\", \"Drift\", \"Attend 20 watchparties\")\n];\nvar COSMETICS_BY_ID = new Map(\n COSMETICS.map((i) => [i.id, i])\n);\nvar PLACEMENT_DEFAULT = { x: 0, y: 0, r: 0, s: 100, flip: false, back: false };\nvar PLACEMENT_LIMITS = {\n x: [-60, 60],\n y: [-60, 100],\n r: [-45, 45],\n s: [70, 140]\n};\nfunction overlayBounds(art, p) {\n const [a, b, c, d] = art.visible;\n const x0 = p.flip ? 1 - c : a;\n const x1 = p.flip ? 1 - a : c;\n const L = 50 - art.width / 2;\n const T = art.top;\n const W = art.width;\n const ox = L + W * 0.5;\n const oy = T + W * 0.6;\n const cx = L + W / 2;\n const cy = T + W / 2;\n const t = art.tilt * Math.PI / 180;\n const r = p.r * Math.PI / 180;\n const sc = p.s / 100;\n const xs = [];\n const ys = [];\n for (const [fx, fy] of [\n [x0, b],\n [x1, b],\n [x0, d],\n [x1, d]\n ]) {\n const px = L + fx * W;\n const py = T + fy * W;\n const tx = cx + (px - cx) * Math.cos(t) - (py - cy) * Math.sin(t);\n const ty = cy + (px - cx) * Math.sin(t) + (py - cy) * Math.cos(t);\n const dx = (tx - ox) * sc;\n const dy = (ty - oy) * sc;\n xs.push(ox + p.x + dx * Math.cos(r) - dy * Math.sin(r));\n ys.push(oy + p.y + dx * Math.sin(r) + dy * Math.cos(r));\n }\n return {\n left: Math.min(...xs),\n top: Math.min(...ys),\n right: Math.max(...xs),\n bottom: Math.max(...ys)\n };\n}\nvar ART_ITEMS = COSMETICS.filter((i) => !!i.art);\nvar PLACEMENT_ZONE = {\n left: -25,\n top: Math.floor(Math.min(...ART_ITEMS.map((i) => overlayBounds(i.art, PLACEMENT_DEFAULT).top))),\n right: 125,\n bottom: 110\n};\nvar clamp = (v, [lo, hi]) => Math.min(hi, Math.max(lo, v));\nfunction fitPlacement(art, raw) {\n const num = (v, fallback) => typeof v === \"number\" && Number.isFinite(v) ? v : fallback;\n const p = {\n x: Math.round(clamp(num(raw.x, 0), PLACEMENT_LIMITS.x)),\n y: Math.round(clamp(num(raw.y, 0), PLACEMENT_LIMITS.y)),\n r: Math.round(clamp(num(raw.r, 0), PLACEMENT_LIMITS.r)),\n s: Math.round(clamp(num(raw.s, 100), PLACEMENT_LIMITS.s)),\n flip: raw.flip === true,\n back: raw.back === true\n };\n const z = PLACEMENT_ZONE;\n let box = overlayBounds(art, p);\n const room = Math.min(\n (z.right - z.left - 2) / (box.right - box.left),\n (z.bottom - z.top - 2) / (box.bottom - box.top)\n );\n if (room < 1) {\n p.s = Math.max(PLACEMENT_LIMITS.s[0], Math.floor(p.s * room));\n box = overlayBounds(art, p);\n }\n p.x += Math.ceil(Math.max(0, z.left - box.left)) - Math.ceil(Math.max(0, box.right - z.right));\n p.y += Math.ceil(Math.max(0, z.top - box.top)) - Math.ceil(Math.max(0, box.bottom - z.bottom));\n return p;\n}\nfunction emptyLoadout() {\n return {\n equipped: { effect: null, gradient: null, font: null, overlay: null, message: null },\n placement: {}\n };\n}\nfunction cleanLoadout(raw, owned) {\n const out = emptyLoadout();\n const src = raw && typeof raw === \"object\" ? raw : {};\n for (const slot of COSMETIC_SLOTS) {\n const id = src.equipped?.[slot];\n if (typeof id === \"string\" && owned.has(id) && COSMETICS_BY_ID.get(id)?.slot === slot) {\n out.equipped[slot] = id;\n }\n }\n for (const [id, p] of Object.entries(src.placement ?? {})) {\n const art = COSMETICS_BY_ID.get(id)?.art;\n if (art && owned.has(id) && p && typeof p === \"object\") {\n out.placement[id] = fitPlacement(art, p);\n }\n }\n return out;\n}\nfunction wornCosmetics(loadout) {\n const worn = {};\n for (const slot of COSMETIC_SLOTS) {\n const id = loadout.equipped[slot];\n if (id) worn[slot] = id;\n }\n const overlay = loadout.equipped.overlay;\n if (overlay && COSMETICS_BY_ID.get(overlay)?.art && loadout.placement[overlay]) {\n worn.placement = loadout.placement[overlay];\n }\n return Object.keys(worn).length ? worn : void 0;\n}\n\n// src/cosmetics.ts\nvar COSMETICS_ASSET_BASE = \"/cosmetics\";\nvar STYLE_ID = \"hadoku-cosmetics\";\nvar esc = (s) => s.replace(\n /[&<>\"']/g,\n (c) => ({ \"&\": \"&\", \"<\": \"<\", \">\": \">\", '\"': \""\", \"'\": \"'\" })[c]\n);\nvar nameOf = (id) => id ? id.slice(id.indexOf(\".\") + 1) : \"none\";\nfunction colourStyle(hex) {\n return hex && /^#[0-9a-f]{6}$/i.test(hex) ? `--hc-base:${hex}` : \"\";\n}\nfunction placementTransform(p) {\n const sx = p.s / 100 * (p.flip ? -1 : 1);\n return `translate(calc(var(--hc-sz) * ${(p.x / 100).toFixed(3)}),calc(var(--hc-sz) * ${(p.y / 100).toFixed(3)})) rotate(${p.r}deg) scale(${sx.toFixed(3)},${(p.s / 100).toFixed(3)})`;\n}\nvar SPLIT_EFFECTS = /* @__PURE__ */ new Set([\"hop\"]);\nfunction nameHtml(text, worn, opts = {}) {\n const fx = nameOf(worn?.effect);\n const gr = nameOf(worn?.gradient);\n const font = nameOf(worn?.font);\n const t = esc(text);\n const split = SPLIT_EFFECTS.has(fx);\n const tx = split ? `<span class=\"hc-tx\">${[...text].map(\n (c, i) => `<span class=\"hc-ch\" style=\"--hc-i:${i}\"><span class=\"hc-c\">${c === \" \" ? \" \" : esc(c)}</span></span>`\n ).join(\"\")}</span>` : `<span class=\"hc-tx\">${t}</span>`;\n const layer = (cls2) => `<span class=\"hc-lyr${cls2}\" aria-hidden=\"true\">${t}</span>`;\n let back = \"\";\n let front = \"\";\n if (fx === \"aura\" || fx === \"outline\") back += layer(\" hc-g\");\n if (fx === \"glint\") front += `<span class=\"hc-win\" aria-hidden=\"true\">${layer(\"\")}</span>`;\n if (fx === \"twinkle\") {\n front += [\n [-6, -25, 0],\n [52, 55, 0.95],\n [94, -15, 1.9]\n ].map(\n ([x, y, d]) => `<i class=\"hc-tw\" aria-hidden=\"true\" style=\"left:${x}%;top:${y}%;animation-delay:${d}s\"></i>`\n ).join(\"\");\n }\n const cls = `hc-name hc-fx-${fx} hc-gr-${gr} hc-font-${font}${split ? \" hc-split\" : \"\"}${opts.large ? \" hc-large\" : \"\"}`;\n return `<span class=\"${cls}\">${back}${tx}${front}</span>`;\n}\nvar RUNES_SVG = (() => {\n let marks = \"\";\n for (let i = 0; i < 12; i++) {\n marks += `<g transform=\"rotate(${i * 30} 50 50)\"><path d=\"M50 3 l2.5 4 -2.5 4 -2.5 -4z\" fill=\"currentColor\" opacity=\"${i % 3 ? 0.55 : 1}\"/></g>`;\n }\n return `<svg viewBox=\"0 0 100 100\" aria-hidden=\"true\"><circle cx=\"50\" cy=\"50\" r=\"44\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1\" stroke-dasharray=\"3 5\" opacity=\".7\"/>${marks}</svg>`;\n})();\nfunction decorHtml(worn, assetBase = COSMETICS_ASSET_BASE) {\n const id = worn?.overlay;\n if (!id) return \"\";\n const art = COSMETICS_BY_ID.get(id)?.art;\n if (art) {\n const p = worn?.placement ?? PLACEMENT_DEFAULT;\n return `<span class=\"hc-ol hc-art${art.pixel ? \" hc-px\" : \"\"}\" data-hc-art=\"${esc(id)}\" style=\"left:${50 - art.width / 2}%;top:${art.top}%;width:${art.width}%;z-index:${p.back ? 0 : 3}\"><span class=\"hc-adj\" style=\"transform:${placementTransform(p)}\"><img alt=\"\" draggable=\"false\" style=\"--hc-tilt:${art.tilt}deg\" src=\"${esc(`${assetBase}/art/${art.file}`)}\"></span></span>`;\n }\n switch (nameOf(id)) {\n case \"runes\":\n return `<span class=\"hc-ol hc-runes\">${RUNES_SVG}</span>`;\n case \"comet\":\n return `<span class=\"hc-ol hc-comet\"></span>`;\n case \"shine\":\n return `<span class=\"hc-ol hc-clip\"><span class=\"hc-band\"></span></span>`;\n case \"glow\":\n return `<span class=\"hc-ol hc-glow\"></span>`;\n case \"petals\":\n return [15, 40, 62, 85].map(\n (l, i) => `<i class=\"hc-ol hc-petal\" style=\"left:${l}%;animation-delay:${(i * 0.85).toFixed(2)}s\"></i>`\n ).join(\"\");\n default:\n return \"\";\n }\n}\nfunction avatarHtml(o) {\n const pic = o.src ? `<img alt=\"\" src=\"${esc(o.src)}\">` : \"\";\n return `<span class=\"hc-av\" style=\"--hc-sz:${o.size}px\"><span class=\"hc-pic\">${pic}</span>${decorHtml(o.worn, o.assetBase)}</span>`;\n}\nvar GLYPHS = \"!<>-_/[]{}=+*^?#%&01\";\nvar LETTER_MODES = /* @__PURE__ */ new Set([\"type\", \"decode\", \"cascade\"]);\nvar REVEAL_MS = 1400;\nvar LETTER_LIMIT = 160;\nfunction messageHtml(text, worn, opts = {}) {\n let mode = nameOf(worn?.message);\n if (mode === \"none\") return `<span class=\"hc-msg\">${esc(text)}</span>`;\n const words = text.split(/\\s+/).filter(Boolean);\n if (LETTER_MODES.has(mode) && text.length > LETTER_LIMIT) mode = \"words\";\n const keep = opts.keep ? \" data-hc-keep\" : \"\";\n let body;\n let step;\n if (LETTER_MODES.has(mode)) {\n step = Math.min(38, REVEAL_MS / Math.max(1, text.length));\n let n = 0;\n const rnd = () => GLYPHS[Math.floor(Math.random() * GLYPHS.length)];\n body = words.map(\n (w) => `<span class=\"hc-w\">${[...w].map((c) => {\n const i = n++;\n return mode === \"decode\" ? `<span class=\"hc-ch\" style=\"--hc-i:${i}\" data-g=\"${esc(rnd())}\" data-h=\"${esc(rnd())}\"><span class=\"hc-r\">${esc(c)}</span></span>` : `<span class=\"hc-ch\" style=\"--hc-i:${i}\">${esc(c)}</span>`;\n }).join(\"\")}</span>`\n ).join(\" \");\n if (mode === \"type\") body += `<span class=\"hc-caret\" style=\"--hc-i:${n}\"></span>`;\n const lastClass = mode === \"type\" ? \"hc-caret\" : mode === \"decode\" ? \"hc-r\" : \"hc-ch\";\n const at = body.lastIndexOf(`<span class=\"${lastClass}\"`);\n body = `${body.slice(0, at)}<span data-hc-last class=\"${lastClass}\"${body.slice(at + `<span class=\"${lastClass}\"`.length)}`;\n } else {\n step = Math.min(90, REVEAL_MS / Math.max(1, words.length));\n body = words.map(\n (w, i) => `<span class=\"hc-w\" style=\"--hc-i:${i}\"${i === words.length - 1 ? \" data-hc-last\" : \"\"}>${esc(w)}</span>`\n ).join(\" \");\n }\n return `<span class=\"hc-msg hc-mt-${mode}\" style=\"--hc-step:${step.toFixed(1)}ms\" data-text=\"${esc(text)}\"${keep}><span class=\"hc-sr\">${esc(text)}</span><span aria-hidden=\"true\">${body}</span></span>`;\n}\nfunction finishReveal(e) {\n const t = e.target;\n if (e.pseudoElement || !t?.hasAttribute?.(\"data-hc-last\")) return;\n const msg = t.closest(\".hc-msg\");\n if (!msg || msg.hasAttribute(\"data-hc-keep\")) return;\n msg.className = \"hc-msg\";\n msg.removeAttribute(\"style\");\n msg.textContent = msg.getAttribute(\"data-text\") ?? \"\";\n}\nvar FONTS = {\n script: {\n file: \"caveat\",\n family: \"Caveat\",\n generic: \"cursive\",\n css: \"font-weight:700;font-size:1.3em;line-height:1\"\n },\n surf: {\n file: \"pacifico\",\n family: \"Pacifico\",\n generic: \"cursive\",\n css: \"font-weight:400;font-size:1.02em;line-height:1.1\"\n },\n gothic: {\n file: \"gothic\",\n family: \"Grenze Gotisch\",\n generic: \"serif\",\n css: \"font-weight:600;font-size:1.15em\"\n },\n runic: { file: \"uncial\", family: \"Uncial Antiqua\", generic: \"serif\", css: \"font-weight:400\" },\n corsair: {\n file: \"pirata\",\n family: \"Pirata One\",\n generic: \"serif\",\n css: \"font-weight:400;font-size:1.12em;letter-spacing:.02em\"\n },\n metal: {\n file: \"metal\",\n family: \"Metal Mania\",\n generic: \"cursive\",\n css: \"font-weight:400;font-size:1.12em;letter-spacing:.02em\"\n },\n comic: {\n file: \"bangers\",\n family: \"Bangers\",\n generic: \"cursive\",\n css: \"font-weight:400;font-size:1.15em;letter-spacing:.05em\"\n },\n circuit: {\n file: \"orbitron\",\n family: \"Orbitron\",\n generic: \"sans-serif\",\n css: \"font-weight:700;letter-spacing:.03em\"\n },\n hover: {\n file: \"audiowide\",\n family: \"Audiowide\",\n generic: \"sans-serif\",\n css: \"font-weight:400;font-size:.92em\"\n },\n retro: { file: \"righteous\", family: \"Righteous\", generic: \"sans-serif\", css: \"font-weight:400\" },\n arcade: {\n file: \"bungee\",\n family: \"Bungee\",\n generic: \"sans-serif\",\n css: \"font-weight:400;font-size:.9em\"\n },\n pixel: {\n file: \"pixel\",\n family: \"Press Start 2P\",\n generic: \"monospace\",\n css: \"font-weight:400;font-size:.62em;line-height:1.6\"\n }\n};\nfunction cosmeticsCss(assetBase = COSMETICS_ASSET_BASE) {\n const fontFaces = Object.entries(FONTS).map(\n ([k, f]) => `@font-face{font-family:\"hc-${k}\";src:url(\"${assetBase}/fonts/${f.file}.woff2\") format(\"woff2\");font-display:swap}`\n ).join(\"\\n\");\n const fontRules = Object.entries(FONTS).map(([k, f]) => `.hc-font-${k}{font-family:\"hc-${k}\",\"${f.family}\",${f.generic};${f.css}}`).join(\"\\n\");\n return `${fontFaces}\n/* Colours: everything derives from the character colour. */\n.hc-name,.hc-av,.hc-msg{--hc-b:var(--hc-base,currentColor);--hc-hi:color-mix(in oklch,var(--hc-b),white 50%);--hc-lo:color-mix(in oklch,var(--hc-b),black 50%);--hc-glow:color-mix(in oklch,var(--hc-b) 75%,transparent)}\n\n/* --- name ---\n Bleed: a gradient is a background clipped to the letters, and a background covers only the box; script\n swashes reach outside it. So the text box and every layer over it get room on all sides, cancelled by a\n negative margin so nothing moves. */\n.hc-name{--hc-bx:.4em;--hc-by:.3em;--hc-grad:none;position:relative;display:inline-block;white-space:nowrap;color:var(--hc-b);font-weight:700;line-height:1.25}\n.hc-name.hc-large{font-size:1.6em}\n.hc-name .hc-tx{position:relative;z-index:1;display:inline-block;padding:var(--hc-by) var(--hc-bx);margin:calc(-1 * var(--hc-by)) calc(-1 * var(--hc-bx))}\n.hc-name .hc-lyr{position:absolute;left:calc(-1 * var(--hc-bx));top:calc(-1 * var(--hc-by));padding:var(--hc-by) var(--hc-bx);pointer-events:none;white-space:nowrap}\n.hc-name .hc-win{position:absolute;inset:calc(-1 * var(--hc-by)) calc(-1 * var(--hc-bx));overflow:hidden}\n.hc-name .hc-win .hc-lyr{left:0;top:0}\n.hc-name .hc-ch,.hc-name .hc-c{display:inline-block}\n.hc-gr-gild{--hc-grad:linear-gradient(180deg,var(--hc-hi) 0%,var(--hc-b) 55%,var(--hc-lo) 100%)}\n.hc-gr-gloss{--hc-grad:linear-gradient(180deg,color-mix(in oklch,var(--hc-hi),white 35%) 0%,var(--hc-hi) 36%,color-mix(in oklch,var(--hc-hi),var(--hc-b)) 48%,var(--hc-b) 60%,var(--hc-lo) 100%)}\n.hc-gr-split{--hc-grad:linear-gradient(180deg,var(--hc-hi) 0 52%,var(--hc-b) 52% 100%)}\n.hc-gr-brushed{--hc-grad:repeating-linear-gradient(90deg,transparent 0 1px,color-mix(in oklch,var(--hc-hi) 40%,transparent) 1px 2px),linear-gradient(180deg,var(--hc-hi),var(--hc-b) 55%,var(--hc-lo))}\n.hc-gr-lumen{--hc-grad:radial-gradient(ellipse 60% 90% at 50% 35%,var(--hc-hi),var(--hc-b) 55%,var(--hc-lo) 100%)}\n.hc-name:not(.hc-gr-none) .hc-tx{background:var(--hc-grad);-webkit-background-clip:text;background-clip:text;color:transparent}\n.hc-name.hc-split:not(.hc-gr-none) .hc-tx{background:none}\n.hc-name.hc-split:not(.hc-gr-none) .hc-tx .hc-c{padding:var(--hc-by) var(--hc-bx);margin:calc(-1 * var(--hc-by)) calc(-1 * var(--hc-bx));background:var(--hc-grad);-webkit-background-clip:text;background-clip:text;color:transparent}\n.hc-fx-glint .hc-win{z-index:3;animation:hc-win-go 4.5s cubic-bezier(.4,0,.2,1) infinite;-webkit-mask-image:linear-gradient(100deg,transparent 35%,#000 50%,transparent 65%);mask-image:linear-gradient(100deg,transparent 35%,#000 50%,transparent 65%)}\n.hc-fx-glint .hc-win .hc-lyr{color:var(--hc-hi);animation:hc-win-back 4.5s cubic-bezier(.4,0,.2,1) infinite}\n@keyframes hc-win-go{0%{transform:translateX(-100%)}55%,100%{transform:translateX(100%)}}\n@keyframes hc-win-back{0%{transform:translateX(100%)}55%,100%{transform:translateX(-100%)}}\n.hc-fx-aura .hc-lyr.hc-g{color:transparent;text-shadow:0 0 6px var(--hc-glow),0 0 14px var(--hc-glow);animation:hc-breathe 3s ease-in-out infinite}\n.hc-fx-outline .hc-lyr.hc-g{color:transparent;-webkit-text-stroke:3px var(--hc-hi);animation:hc-breathe 3.6s ease-in-out infinite}\n@keyframes hc-breathe{0%,100%{opacity:.25}50%{opacity:1}}\n.hc-fx-hop .hc-c{animation:hc-hop 3.6s ease-in-out calc(var(--hc-i) * 45ms) infinite}\n@keyframes hc-hop{0%,14%,100%{transform:none}5%{transform:translateY(-4px)}10%{transform:translateY(.5px)}}\n.hc-fx-twinkle .hc-tw{position:absolute;width:7px;height:7px;z-index:3;pointer-events:none;background:linear-gradient(var(--hc-hi),var(--hc-hi)) center/1.4px 100% no-repeat,linear-gradient(90deg,var(--hc-hi),var(--hc-hi)) center/100% 1.4px no-repeat;animation:hc-star 2.8s ease-in-out infinite both}\n@keyframes hc-star{0%,100%{opacity:0;transform:scale(.3) rotate(0deg)}25%{opacity:1;transform:scale(1) rotate(45deg)}50%{opacity:0;transform:scale(.3) rotate(90deg)}}\n.hc-font-caps{font-variant:small-caps;letter-spacing:.08em}\n.hc-font-wide{letter-spacing:.22em;font-weight:600;text-transform:uppercase;font-size:.82em}\n${fontRules}\n\n/* --- avatar --- */\n.hc-av{--hc-sz:40px;position:relative;display:inline-block;width:var(--hc-sz);height:var(--hc-sz);flex:none;isolation:isolate;vertical-align:middle}\n.hc-av .hc-pic{position:absolute;inset:0;border-radius:50%;overflow:hidden;z-index:1;background:color-mix(in oklch,var(--hc-b) 30%,transparent)}\n.hc-av .hc-pic img{width:100%;height:100%;display:block;object-fit:cover;image-rendering:pixelated}\n.hc-av .hc-ol{position:absolute;pointer-events:none}\n.hc-ol.hc-art{display:block}\n.hc-ol.hc-art .hc-adj{display:block;position:relative;transform-origin:50% 60%}\n.hc-ol.hc-art img{display:block;width:100%;height:auto;filter:drop-shadow(0 1px 1px rgba(0,0,0,.45));animation:hc-art-bob 3.4s ease-in-out infinite;-webkit-user-drag:none;user-select:none}\n.hc-ol.hc-art.hc-px img{image-rendering:pixelated}\n@keyframes hc-art-bob{0%,100%{transform:rotate(var(--hc-tilt,0deg)) translateY(0)}50%{transform:rotate(var(--hc-tilt,0deg)) translateY(-2px)}}\n.hc-ol.hc-runes{inset:-9px;z-index:2;color:var(--hc-hi);animation:hc-turn 14s linear infinite}\n.hc-ol.hc-runes svg{width:100%;height:100%;display:block}\n@keyframes hc-turn{to{transform:rotate(360deg)}}\n.hc-ol.hc-comet{inset:-6px;z-index:2;border-radius:50%;background:conic-gradient(from 0deg,transparent 0 270deg,color-mix(in oklch,var(--hc-hi) 10%,transparent) 300deg,var(--hc-hi) 358deg,transparent 360deg);-webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 3px),#000 calc(100% - 3px));mask:radial-gradient(farthest-side,transparent calc(100% - 3px),#000 calc(100% - 3px));animation:hc-turn 2.4s linear infinite}\n.hc-ol.hc-clip{inset:0;border-radius:50%;overflow:hidden;z-index:2}\n.hc-ol .hc-band{position:absolute;top:-30%;left:0;width:45%;height:160%;background:linear-gradient(90deg,transparent,color-mix(in oklch,var(--hc-hi) 70%,transparent),transparent);transform:translateX(-130%) rotate(20deg);animation:hc-band 5s ease-in-out infinite}\n@keyframes hc-band{0%{transform:translateX(-130%) rotate(20deg)}45%,100%{transform:translateX(260%) rotate(20deg)}}\n.hc-ol.hc-glow{inset:-30%;border-radius:50%;z-index:0;background:radial-gradient(circle,var(--hc-glow) 0,transparent 65%);animation:hc-glowp 3.2s ease-in-out infinite}\n@keyframes hc-glowp{0%,100%{opacity:.35;transform:scale(.92)}50%{opacity:.9;transform:scale(1.04)}}\n.hc-ol.hc-petal{top:-8%;height:100%;width:5px;z-index:2;animation:hc-fall 3.4s linear infinite both}\n.hc-ol.hc-petal::after{content:\"\";position:absolute;left:0;top:0;width:5px;height:7px;border-radius:5px 0;background:#f7b6c8;transform:rotate(35deg)}\n@keyframes hc-fall{0%{transform:translate(0,0);opacity:0}12%{opacity:.9}100%{transform:translate(-6px,100%);opacity:0}}\n\n/* --- message reveal: fill backwards only; the page swaps back to plain text when it ends --- */\n.hc-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}\n.hc-msg .hc-w{display:inline-block;white-space:nowrap}\n.hc-msg .hc-ch{display:inline-block}\n.hc-mt-type .hc-ch{animation:hc-in .01s linear calc(var(--hc-i) * var(--hc-step)) backwards}\n.hc-mt-type .hc-caret{display:inline-block;width:2px;height:1em;margin-left:2px;vertical-align:-2px;background:var(--hc-b);opacity:0;animation:hc-caret 1.5s steps(1) calc(var(--hc-i) * var(--hc-step)) backwards}\n@keyframes hc-caret{0%{opacity:0}1%{opacity:1}20%{opacity:0}40%{opacity:1}60%{opacity:0}80%{opacity:1}100%{opacity:0}}\n.hc-mt-cascade .hc-ch{animation:hc-drop .35s cubic-bezier(.3,1.5,.5,1) calc(var(--hc-i) * var(--hc-step)) backwards}\n.hc-mt-decode .hc-ch{position:relative}\n.hc-mt-decode .hc-ch .hc-r{display:inline-block;animation:hc-in .01s linear calc(var(--hc-i) * var(--hc-step) + 260ms) backwards}\n.hc-mt-decode .hc-ch::before,.hc-mt-decode .hc-ch::after{position:absolute;left:0;top:0;color:var(--hc-b);opacity:0;animation:hc-dec-a .26s steps(1) calc(var(--hc-i) * var(--hc-step)) backwards}\n.hc-mt-decode .hc-ch::before{content:attr(data-g)}\n.hc-mt-decode .hc-ch::after{content:attr(data-h);animation-name:hc-dec-b}\n@keyframes hc-dec-a{0%{opacity:.85}50%,100%{opacity:0}}\n@keyframes hc-dec-b{0%{opacity:0}50%{opacity:.85}100%{opacity:0}}\n.hc-mt-words .hc-w{animation:hc-rise .4s ease-out calc(var(--hc-i) * var(--hc-step)) backwards}\n.hc-mt-bubble .hc-w{animation:hc-pop .35s cubic-bezier(.3,1.6,.5,1) calc(var(--hc-i) * var(--hc-step)) backwards}\n.hc-mt-drift .hc-w{animation:hc-slide .45s cubic-bezier(.2,.8,.2,1) calc(var(--hc-i) * var(--hc-step)) backwards}\n@keyframes hc-in{from{opacity:0}to{opacity:1}}\n@keyframes hc-drop{0%{transform:translateY(-10px);opacity:0}100%{transform:none;opacity:1}}\n@keyframes hc-rise{0%{transform:translateY(10px);opacity:0}100%{transform:none;opacity:1}}\n@keyframes hc-pop{0%{transform:scale(.6);opacity:0}100%{transform:scale(1);opacity:1}}\n@keyframes hc-slide{0%{transform:translateX(-18px);opacity:0}100%{transform:none;opacity:1}}\n\n.hc-idle .hc-name,.hc-idle .hc-name *,.hc-idle .hc-av *,.hc-idle .hc-av *::after{animation-play-state:paused!important}\n@media (prefers-reduced-motion:reduce){.hc-name *,.hc-av *,.hc-av *::after,.hc-msg *,.hc-msg *::before,.hc-msg *::after{animation:none!important}}\n`;\n}\nfunction ensureCosmeticsStyles(doc = document, assetBase = COSMETICS_ASSET_BASE) {\n if (doc.getElementById(STYLE_ID)) return;\n const style = doc.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = cosmeticsCss(assetBase);\n doc.head.appendChild(style);\n doc.addEventListener(\"animationend\", finishReveal);\n}\nexport {\n COSMETICS,\n COSMETICS_ASSET_BASE,\n COSMETICS_BY_ID,\n COSMETIC_ID_PATTERN,\n COSMETIC_SLOTS,\n PLACEMENT_DEFAULT,\n PLACEMENT_LIMITS,\n PLACEMENT_ZONE,\n avatarHtml,\n cleanLoadout,\n colourStyle,\n cosmeticsCss,\n decorHtml,\n emptyLoadout,\n ensureCosmeticsStyles,\n fitPlacement,\n messageHtml,\n nameHtml,\n overlayBounds,\n placementTransform,\n wornCosmetics\n};\n"],"names":[],"mappings":"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","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"cosmetics.js","sources":["../../../../../node_modules/.pnpm/@wolffm+prefs-client@1.1.15_react@19.2.8_zod@4.6.7/node_modules/@wolffm/prefs-client/dist/cosmetics.js"],"sourcesContent":["// src/cosmetics-contract.ts\nvar COSMETIC_SLOTS = [\"effect\", \"gradient\", \"font\", \"overlay\", \"message\"];\nvar COSMETIC_ID_PATTERN = /^(effect|gradient|font|overlay|message)\\.[a-z0-9-]{1,32}$/;\nvar item = (slot, name, label, opts = {}) => ({ id: `${slot}.${name}`, slot, label, ...opts });\nvar archived = { hidden: true };\nvar COSMETICS = [\n item(\"effect\", \"glint\", \"Glint\"),\n item(\"effect\", \"aura\", \"Aura\"),\n item(\"effect\", \"hop\", \"Hop\"),\n item(\"effect\", \"outline\", \"Outline\"),\n item(\"effect\", \"twinkle\", \"Twinkle\", { earn: \"Bronze or better in a Major\" }),\n item(\"gradient\", \"gild\", \"Gilded\"),\n item(\"gradient\", \"gloss\", \"Gloss\"),\n item(\"gradient\", \"split\", \"Split\"),\n item(\"gradient\", \"brushed\", \"Brushed\"),\n item(\"gradient\", \"lumen\", \"Lumen\"),\n item(\"font\", \"script\", \"Script\"),\n item(\"font\", \"surf\", \"Surf\"),\n item(\"font\", \"gothic\", \"Gothic\"),\n item(\"font\", \"runic\", \"Runic\"),\n item(\"font\", \"arcade\", \"Arcade\"),\n item(\"font\", \"caps\", \"Small caps\", archived),\n item(\"font\", \"wide\", \"Wide\", archived),\n item(\"font\", \"corsair\", \"Corsair\", archived),\n item(\"font\", \"metal\", \"Metal\", archived),\n item(\"font\", \"comic\", \"Comic\", archived),\n item(\"font\", \"circuit\", \"Circuit\", archived),\n item(\"font\", \"hover\", \"Hover\", archived),\n item(\"font\", \"retro\", \"Retro\", archived),\n item(\"font\", \"pixel\", \"Pixel\", archived),\n item(\"overlay\", \"crown\", \"Crown\", {\n earn: \"Win a Major\",\n art: {\n file: \"crown.webp\",\n top: -40,\n width: 70,\n tilt: -8,\n pixel: false,\n visible: [0.027, 0.137, 0.973, 0.863]\n }\n }),\n item(\"overlay\", \"halo\", \"Halo\", {\n art: {\n file: \"halo.webp\",\n top: -34,\n width: 76,\n tilt: 0,\n pixel: true,\n visible: [0.033, 0.333, 0.967, 0.667]\n }\n }),\n item(\"overlay\", \"flowers\", \"Flower crown\", {\n art: {\n file: \"flowers.webp\",\n top: -22,\n width: 96,\n tilt: 0,\n pixel: false,\n visible: [0.027, 0.258, 0.969, 0.746]\n }\n }),\n item(\"overlay\", \"petals\", \"Petals\"),\n item(\"overlay\", \"horns\", \"Horns\", {\n ...archived,\n art: {\n file: \"horns.webp\",\n top: -26,\n width: 100,\n tilt: 0,\n pixel: true,\n visible: [0.033, 0.133, 0.967, 0.867]\n }\n }),\n item(\"overlay\", \"runes\", \"Runes\", archived),\n item(\"overlay\", \"comet\", \"Comet\", archived),\n item(\"overlay\", \"shine\", \"Shine\", archived),\n item(\"overlay\", \"glow\", \"Glow\", archived),\n item(\"message\", \"type\", \"Typewriter\"),\n item(\"message\", \"decode\", \"Decode\", { earn: \"Silver or better in a Major\" }),\n item(\"message\", \"cascade\", \"Cascade\"),\n item(\"message\", \"words\", \"Word by word\"),\n item(\"message\", \"bubble\", \"Bubble\", archived),\n item(\"message\", \"drift\", \"Drift\")\n];\nvar COSMETICS_BY_ID = new Map(\n COSMETICS.map((i) => [i.id, i])\n);\nvar EARNED_COSMETICS = COSMETICS.filter(\n (i) => i.earn !== void 0 && !i.hidden\n);\nfunction ownedFrom(granted) {\n const out = new Set(COSMETICS.filter((i) => !i.hidden && i.earn === void 0).map((i) => i.id));\n for (const id of granted) {\n const it = COSMETICS_BY_ID.get(id);\n if (it && !it.hidden) out.add(id);\n }\n return out;\n}\nvar PLACEMENT_DEFAULT = { x: 0, y: 0, r: 0, s: 100, flip: false, back: false };\nvar PLACEMENT_LIMITS = {\n x: [-60, 60],\n y: [-60, 100],\n r: [-45, 45],\n s: [70, 140]\n};\nfunction overlayBounds(art, p) {\n const [a, b, c, d] = art.visible;\n const x0 = p.flip ? 1 - c : a;\n const x1 = p.flip ? 1 - a : c;\n const L = 50 - art.width / 2;\n const T = art.top;\n const W = art.width;\n const ox = L + W * 0.5;\n const oy = T + W * 0.6;\n const cx = L + W / 2;\n const cy = T + W / 2;\n const t = art.tilt * Math.PI / 180;\n const r = p.r * Math.PI / 180;\n const sc = p.s / 100;\n const xs = [];\n const ys = [];\n for (const [fx, fy] of [\n [x0, b],\n [x1, b],\n [x0, d],\n [x1, d]\n ]) {\n const px = L + fx * W;\n const py = T + fy * W;\n const tx = cx + (px - cx) * Math.cos(t) - (py - cy) * Math.sin(t);\n const ty = cy + (px - cx) * Math.sin(t) + (py - cy) * Math.cos(t);\n const dx = (tx - ox) * sc;\n const dy = (ty - oy) * sc;\n xs.push(ox + p.x + dx * Math.cos(r) - dy * Math.sin(r));\n ys.push(oy + p.y + dx * Math.sin(r) + dy * Math.cos(r));\n }\n return {\n left: Math.min(...xs),\n top: Math.min(...ys),\n right: Math.max(...xs),\n bottom: Math.max(...ys)\n };\n}\nvar ART_ITEMS = COSMETICS.filter((i) => !!i.art);\nvar PLACEMENT_ZONE = {\n left: -25,\n top: Math.floor(Math.min(...ART_ITEMS.map((i) => overlayBounds(i.art, PLACEMENT_DEFAULT).top))),\n right: 125,\n bottom: 110\n};\nvar clamp = (v, [lo, hi]) => Math.min(hi, Math.max(lo, v));\nfunction fitPlacement(art, raw) {\n const num = (v, fallback) => typeof v === \"number\" && Number.isFinite(v) ? v : fallback;\n const p = {\n x: Math.round(clamp(num(raw.x, 0), PLACEMENT_LIMITS.x)),\n y: Math.round(clamp(num(raw.y, 0), PLACEMENT_LIMITS.y)),\n r: Math.round(clamp(num(raw.r, 0), PLACEMENT_LIMITS.r)),\n s: Math.round(clamp(num(raw.s, 100), PLACEMENT_LIMITS.s)),\n flip: raw.flip === true,\n back: raw.back === true\n };\n const z = PLACEMENT_ZONE;\n let box = overlayBounds(art, p);\n const room = Math.min(\n (z.right - z.left - 2) / (box.right - box.left),\n (z.bottom - z.top - 2) / (box.bottom - box.top)\n );\n if (room < 1) {\n p.s = Math.max(PLACEMENT_LIMITS.s[0], Math.floor(p.s * room));\n box = overlayBounds(art, p);\n }\n p.x += Math.ceil(Math.max(0, z.left - box.left)) - Math.ceil(Math.max(0, box.right - z.right));\n p.y += Math.ceil(Math.max(0, z.top - box.top)) - Math.ceil(Math.max(0, box.bottom - z.bottom));\n return p;\n}\nfunction emptyLoadout() {\n return {\n equipped: { effect: null, gradient: null, font: null, overlay: null, message: null },\n placement: {}\n };\n}\nfunction cleanWorn(raw) {\n if (!raw || typeof raw !== \"object\") return void 0;\n const src = raw;\n const worn = {};\n for (const slot of COSMETIC_SLOTS) {\n const id = src[slot];\n const it = typeof id === \"string\" ? COSMETICS_BY_ID.get(id) : void 0;\n if (it && !it.hidden && it.slot === slot) worn[slot] = it.id;\n }\n const art = worn.overlay ? COSMETICS_BY_ID.get(worn.overlay)?.art : void 0;\n if (art && src.placement && typeof src.placement === \"object\") {\n worn.placement = fitPlacement(art, src.placement);\n }\n return Object.keys(worn).length ? worn : void 0;\n}\nfunction cleanLoadout(raw, owned) {\n const out = emptyLoadout();\n const src = raw && typeof raw === \"object\" ? raw : {};\n for (const slot of COSMETIC_SLOTS) {\n const id = src.equipped?.[slot];\n const it = typeof id === \"string\" ? COSMETICS_BY_ID.get(id) : void 0;\n if (it && !it.hidden && owned.has(it.id) && it.slot === slot) {\n out.equipped[slot] = it.id;\n }\n }\n for (const [id, p] of Object.entries(src.placement ?? {})) {\n const it = COSMETICS_BY_ID.get(id);\n const art = it?.art;\n if (art && !it.hidden && owned.has(id) && p && typeof p === \"object\") {\n out.placement[id] = fitPlacement(art, p);\n }\n }\n return out;\n}\nfunction wornCosmetics(loadout) {\n const worn = {};\n for (const slot of COSMETIC_SLOTS) {\n const id = loadout.equipped[slot];\n if (id) worn[slot] = id;\n }\n const overlay = loadout.equipped.overlay;\n if (overlay && COSMETICS_BY_ID.get(overlay)?.art && loadout.placement[overlay]) {\n worn.placement = loadout.placement[overlay];\n }\n return Object.keys(worn).length ? worn : void 0;\n}\n\n// src/cosmetics.ts\nvar COSMETICS_ASSET_BASE = \"/cosmetics\";\nvar STYLE_ID = \"hadoku-cosmetics\";\nvar esc = (s) => s.replace(\n /[&<>\"']/g,\n (c) => ({ \"&\": \"&\", \"<\": \"<\", \">\": \">\", '\"': \""\", \"'\": \"'\" })[c]\n);\nvar nameOf = (id) => id ? id.slice(id.indexOf(\".\") + 1) : \"none\";\nfunction colourStyle(hex) {\n return hex && /^#[0-9a-f]{6}$/i.test(hex) ? `--hc-base:${hex}` : \"\";\n}\nfunction placementTransform(p) {\n const sx = p.s / 100 * (p.flip ? -1 : 1);\n return `translate(calc(var(--hc-sz) * ${(p.x / 100).toFixed(3)}),calc(var(--hc-sz) * ${(p.y / 100).toFixed(3)})) rotate(${p.r}deg) scale(${sx.toFixed(3)},${(p.s / 100).toFixed(3)})`;\n}\nvar SPLIT_EFFECTS = /* @__PURE__ */ new Set([\"hop\"]);\nfunction nameHtml(text, worn, opts = {}) {\n const fx = nameOf(worn?.effect);\n const gr = nameOf(worn?.gradient);\n const font = nameOf(worn?.font);\n const t = esc(text);\n const split = SPLIT_EFFECTS.has(fx);\n const tx = split ? `<span class=\"hc-tx\">${[...text].map(\n (c, i) => `<span class=\"hc-ch\" style=\"--hc-i:${i}\"><span class=\"hc-c\">${c === \" \" ? \" \" : esc(c)}</span></span>`\n ).join(\"\")}</span>` : `<span class=\"hc-tx\">${t}</span>`;\n const layer = (cls2) => `<span class=\"hc-lyr${cls2}\" aria-hidden=\"true\">${t}</span>`;\n let back = \"\";\n let front = \"\";\n if (fx === \"aura\" || fx === \"outline\") back += layer(\" hc-g\");\n if (fx === \"glint\") front += `<span class=\"hc-win\" aria-hidden=\"true\">${layer(\"\")}</span>`;\n if (fx === \"twinkle\") {\n front += [\n [-6, -25, 0],\n [52, 55, 0.95],\n [94, -15, 1.9]\n ].map(\n ([x, y, d]) => `<i class=\"hc-tw\" aria-hidden=\"true\" style=\"left:${x}%;top:${y}%;animation-delay:${d}s\"></i>`\n ).join(\"\");\n }\n const cls = `hc-name hc-fx-${fx} hc-gr-${gr} hc-font-${font}${split ? \" hc-split\" : \"\"}${opts.large ? \" hc-large\" : \"\"}`;\n return `<span class=\"${cls}\">${back}${tx}${front}</span>`;\n}\nvar RUNES_SVG = (() => {\n let marks = \"\";\n for (let i = 0; i < 12; i++) {\n marks += `<g transform=\"rotate(${i * 30} 50 50)\"><path d=\"M50 3 l2.5 4 -2.5 4 -2.5 -4z\" fill=\"currentColor\" opacity=\"${i % 3 ? 0.55 : 1}\"/></g>`;\n }\n return `<svg viewBox=\"0 0 100 100\" aria-hidden=\"true\"><circle cx=\"50\" cy=\"50\" r=\"44\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1\" stroke-dasharray=\"3 5\" opacity=\".7\"/>${marks}</svg>`;\n})();\nfunction decorHtml(worn, assetBase = COSMETICS_ASSET_BASE) {\n const id = worn?.overlay;\n if (!id) return \"\";\n const art = COSMETICS_BY_ID.get(id)?.art;\n if (art) {\n const p = worn?.placement ?? PLACEMENT_DEFAULT;\n return `<span class=\"hc-ol hc-art${art.pixel ? \" hc-px\" : \"\"}\" data-hc-art=\"${esc(id)}\" style=\"left:${50 - art.width / 2}%;top:${art.top}%;width:${art.width}%;z-index:${p.back ? 0 : 3}\"><span class=\"hc-adj\" style=\"transform:${placementTransform(p)}\"><img alt=\"\" draggable=\"false\" style=\"--hc-tilt:${art.tilt}deg\" src=\"${esc(`${assetBase}/art/${art.file}`)}\"></span></span>`;\n }\n switch (nameOf(id)) {\n case \"runes\":\n return `<span class=\"hc-ol hc-runes\">${RUNES_SVG}</span>`;\n case \"comet\":\n return `<span class=\"hc-ol hc-comet\"></span>`;\n case \"shine\":\n return `<span class=\"hc-ol hc-clip\"><span class=\"hc-band\"></span></span>`;\n case \"glow\":\n return `<span class=\"hc-ol hc-glow\"></span>`;\n case \"petals\":\n return [15, 40, 62, 85].map(\n (l, i) => `<i class=\"hc-ol hc-petal\" style=\"left:${l}%;animation-delay:${(i * 0.85).toFixed(2)}s\"></i>`\n ).join(\"\");\n default:\n return \"\";\n }\n}\nfunction avatarHtml(o) {\n const pic = o.src ? `<img alt=\"\" src=\"${esc(o.src)}\">` : \"\";\n return `<span class=\"hc-av\" style=\"--hc-sz:${o.size}px\"><span class=\"hc-pic\">${pic}</span>${decorHtml(o.worn, o.assetBase)}</span>`;\n}\nvar GLYPHS = \"!<>-_/[]{}=+*^?#%&01\";\nvar LETTER_MODES = /* @__PURE__ */ new Set([\"type\", \"decode\", \"cascade\"]);\nvar REVEAL_MS = 1400;\nvar LETTER_LIMIT = 160;\nfunction messageHtml(text, worn, opts = {}) {\n let mode = nameOf(worn?.message);\n if (mode === \"none\") return `<span class=\"hc-msg\">${esc(text)}</span>`;\n const words = text.split(/\\s+/).filter(Boolean);\n if (LETTER_MODES.has(mode) && text.length > LETTER_LIMIT) mode = \"words\";\n const keep = opts.keep ? \" data-hc-keep\" : \"\";\n let body;\n let step;\n if (LETTER_MODES.has(mode)) {\n step = Math.min(38, REVEAL_MS / Math.max(1, text.length));\n let n = 0;\n const rnd = () => GLYPHS[Math.floor(Math.random() * GLYPHS.length)];\n body = words.map(\n (w) => `<span class=\"hc-w\">${[...w].map((c) => {\n const i = n++;\n return mode === \"decode\" ? `<span class=\"hc-ch\" style=\"--hc-i:${i}\" data-g=\"${esc(rnd())}\" data-h=\"${esc(rnd())}\"><span class=\"hc-r\">${esc(c)}</span></span>` : `<span class=\"hc-ch\" style=\"--hc-i:${i}\">${esc(c)}</span>`;\n }).join(\"\")}</span>`\n ).join(\" \");\n if (mode === \"type\") body += `<span class=\"hc-caret\" style=\"--hc-i:${n}\"></span>`;\n const lastClass = mode === \"type\" ? \"hc-caret\" : mode === \"decode\" ? \"hc-r\" : \"hc-ch\";\n const at = body.lastIndexOf(`<span class=\"${lastClass}\"`);\n body = `${body.slice(0, at)}<span data-hc-last class=\"${lastClass}\"${body.slice(at + `<span class=\"${lastClass}\"`.length)}`;\n } else {\n step = Math.min(90, REVEAL_MS / Math.max(1, words.length));\n body = words.map(\n (w, i) => `<span class=\"hc-w\" style=\"--hc-i:${i}\"${i === words.length - 1 ? \" data-hc-last\" : \"\"}>${esc(w)}</span>`\n ).join(\" \");\n }\n return `<span class=\"hc-msg hc-mt-${mode}\" style=\"--hc-step:${step.toFixed(1)}ms\" data-text=\"${esc(text)}\"${keep}><span class=\"hc-sr\">${esc(text)}</span><span aria-hidden=\"true\">${body}</span></span>`;\n}\nfunction finishReveal(e) {\n const t = e.target;\n if (e.pseudoElement || !t?.hasAttribute?.(\"data-hc-last\")) return;\n const msg = t.closest(\".hc-msg\");\n if (!msg || msg.hasAttribute(\"data-hc-keep\")) return;\n msg.className = \"hc-msg\";\n msg.removeAttribute(\"style\");\n msg.textContent = msg.getAttribute(\"data-text\") ?? \"\";\n}\nvar FONTS = {\n script: {\n file: \"caveat\",\n family: \"Caveat\",\n generic: \"cursive\",\n css: \"font-weight:700;font-size:1.3em;line-height:1\"\n },\n surf: {\n file: \"pacifico\",\n family: \"Pacifico\",\n generic: \"cursive\",\n css: \"font-weight:400;font-size:1.02em;line-height:1.1\"\n },\n gothic: {\n file: \"gothic\",\n family: \"Grenze Gotisch\",\n generic: \"serif\",\n css: \"font-weight:600;font-size:1.15em\"\n },\n runic: { file: \"uncial\", family: \"Uncial Antiqua\", generic: \"serif\", css: \"font-weight:400\" },\n corsair: {\n file: \"pirata\",\n family: \"Pirata One\",\n generic: \"serif\",\n css: \"font-weight:400;font-size:1.12em;letter-spacing:.02em\"\n },\n metal: {\n file: \"metal\",\n family: \"Metal Mania\",\n generic: \"cursive\",\n css: \"font-weight:400;font-size:1.12em;letter-spacing:.02em\"\n },\n comic: {\n file: \"bangers\",\n family: \"Bangers\",\n generic: \"cursive\",\n css: \"font-weight:400;font-size:1.15em;letter-spacing:.05em\"\n },\n circuit: {\n file: \"orbitron\",\n family: \"Orbitron\",\n generic: \"sans-serif\",\n css: \"font-weight:700;letter-spacing:.03em\"\n },\n hover: {\n file: \"audiowide\",\n family: \"Audiowide\",\n generic: \"sans-serif\",\n css: \"font-weight:400;font-size:.92em\"\n },\n retro: { file: \"righteous\", family: \"Righteous\", generic: \"sans-serif\", css: \"font-weight:400\" },\n arcade: {\n file: \"bungee\",\n family: \"Bungee\",\n generic: \"sans-serif\",\n css: \"font-weight:400;font-size:.9em\"\n },\n pixel: {\n file: \"pixel\",\n family: \"Press Start 2P\",\n generic: \"monospace\",\n css: \"font-weight:400;font-size:.62em;line-height:1.6\"\n }\n};\nfunction cosmeticsCss(assetBase = COSMETICS_ASSET_BASE) {\n const fontFaces = Object.entries(FONTS).map(\n ([k, f]) => `@font-face{font-family:\"hc-${k}\";src:url(\"${assetBase}/fonts/${f.file}.woff2\") format(\"woff2\");font-display:swap}`\n ).join(\"\\n\");\n const fontRules = Object.entries(FONTS).map(([k, f]) => `.hc-font-${k}{font-family:\"hc-${k}\",\"${f.family}\",${f.generic};${f.css}}`).join(\"\\n\");\n return `${fontFaces}\n/* Colours: everything derives from the character colour. */\n.hc-name,.hc-av,.hc-msg{--hc-b:var(--hc-base,currentColor);--hc-hi:color-mix(in oklch,var(--hc-b),white 50%);--hc-lo:color-mix(in oklch,var(--hc-b),black 50%);--hc-glow:color-mix(in oklch,var(--hc-b) 75%,transparent)}\n\n/* --- name ---\n Bleed: a gradient is a background clipped to the letters, and a background covers only the box; script\n swashes reach outside it. So the text box and every layer over it get room on all sides, cancelled by a\n negative margin so nothing moves. */\n.hc-name{--hc-bx:.4em;--hc-by:.3em;--hc-grad:none;position:relative;display:inline-block;white-space:nowrap;color:var(--hc-b);font-weight:700;line-height:1.25}\n.hc-name.hc-large{font-size:1.6em}\n.hc-name .hc-tx{position:relative;z-index:1;display:inline-block;padding:var(--hc-by) var(--hc-bx);margin:calc(-1 * var(--hc-by)) calc(-1 * var(--hc-bx))}\n.hc-name .hc-lyr{position:absolute;left:calc(-1 * var(--hc-bx));top:calc(-1 * var(--hc-by));padding:var(--hc-by) var(--hc-bx);pointer-events:none;white-space:nowrap}\n.hc-name .hc-win{position:absolute;inset:calc(-1 * var(--hc-by)) calc(-1 * var(--hc-bx));overflow:hidden}\n.hc-name .hc-win .hc-lyr{left:0;top:0}\n.hc-name .hc-ch,.hc-name .hc-c{display:inline-block}\n.hc-gr-gild{--hc-grad:linear-gradient(180deg,var(--hc-hi) 0%,var(--hc-b) 55%,var(--hc-lo) 100%)}\n.hc-gr-gloss{--hc-grad:linear-gradient(180deg,color-mix(in oklch,var(--hc-hi),white 35%) 0%,var(--hc-hi) 36%,color-mix(in oklch,var(--hc-hi),var(--hc-b)) 48%,var(--hc-b) 60%,var(--hc-lo) 100%)}\n.hc-gr-split{--hc-grad:linear-gradient(180deg,var(--hc-hi) 0 52%,var(--hc-b) 52% 100%)}\n.hc-gr-brushed{--hc-grad:repeating-linear-gradient(90deg,transparent 0 1px,color-mix(in oklch,var(--hc-hi) 40%,transparent) 1px 2px),linear-gradient(180deg,var(--hc-hi),var(--hc-b) 55%,var(--hc-lo))}\n.hc-gr-lumen{--hc-grad:radial-gradient(ellipse 60% 90% at 50% 35%,var(--hc-hi),var(--hc-b) 55%,var(--hc-lo) 100%)}\n.hc-name:not(.hc-gr-none) .hc-tx{background:var(--hc-grad);-webkit-background-clip:text;background-clip:text;color:transparent}\n.hc-name.hc-split:not(.hc-gr-none) .hc-tx{background:none}\n.hc-name.hc-split:not(.hc-gr-none) .hc-tx .hc-c{padding:var(--hc-by) var(--hc-bx);margin:calc(-1 * var(--hc-by)) calc(-1 * var(--hc-bx));background:var(--hc-grad);-webkit-background-clip:text;background-clip:text;color:transparent}\n.hc-fx-glint .hc-win{z-index:3;animation:hc-win-go 4.5s cubic-bezier(.4,0,.2,1) infinite;-webkit-mask-image:linear-gradient(100deg,transparent 35%,#000 50%,transparent 65%);mask-image:linear-gradient(100deg,transparent 35%,#000 50%,transparent 65%)}\n.hc-fx-glint .hc-win .hc-lyr{color:var(--hc-hi);animation:hc-win-back 4.5s cubic-bezier(.4,0,.2,1) infinite}\n@keyframes hc-win-go{0%{transform:translateX(-100%)}55%,100%{transform:translateX(100%)}}\n@keyframes hc-win-back{0%{transform:translateX(100%)}55%,100%{transform:translateX(-100%)}}\n.hc-fx-aura .hc-lyr.hc-g{color:transparent;text-shadow:0 0 6px var(--hc-glow),0 0 14px var(--hc-glow);animation:hc-breathe 3s ease-in-out infinite}\n.hc-fx-outline .hc-lyr.hc-g{color:transparent;-webkit-text-stroke:3px var(--hc-hi);animation:hc-breathe 3.6s ease-in-out infinite}\n@keyframes hc-breathe{0%,100%{opacity:.25}50%{opacity:1}}\n.hc-fx-hop .hc-c{animation:hc-hop 3.6s ease-in-out calc(var(--hc-i) * 45ms) infinite}\n@keyframes hc-hop{0%,14%,100%{transform:none}5%{transform:translateY(-4px)}10%{transform:translateY(.5px)}}\n.hc-fx-twinkle .hc-tw{position:absolute;width:7px;height:7px;z-index:3;pointer-events:none;background:linear-gradient(var(--hc-hi),var(--hc-hi)) center/1.4px 100% no-repeat,linear-gradient(90deg,var(--hc-hi),var(--hc-hi)) center/100% 1.4px no-repeat;animation:hc-star 2.8s ease-in-out infinite both}\n@keyframes hc-star{0%,100%{opacity:0;transform:scale(.3) rotate(0deg)}25%{opacity:1;transform:scale(1) rotate(45deg)}50%{opacity:0;transform:scale(.3) rotate(90deg)}}\n.hc-font-caps{font-variant:small-caps;letter-spacing:.08em}\n.hc-font-wide{letter-spacing:.22em;font-weight:600;text-transform:uppercase;font-size:.82em}\n${fontRules}\n\n/* --- avatar --- */\n.hc-av{--hc-sz:40px;position:relative;display:inline-block;width:var(--hc-sz);height:var(--hc-sz);flex:none;isolation:isolate;vertical-align:middle}\n.hc-av .hc-pic{position:absolute;inset:0;border-radius:50%;overflow:hidden;z-index:1;background:color-mix(in oklch,var(--hc-b) 30%,transparent)}\n.hc-av .hc-pic img{width:100%;height:100%;display:block;object-fit:cover;image-rendering:pixelated}\n.hc-av .hc-ol{position:absolute;pointer-events:none}\n.hc-ol.hc-art{display:block}\n.hc-ol.hc-art .hc-adj{display:block;position:relative;transform-origin:50% 60%}\n.hc-ol.hc-art img{display:block;width:100%;height:auto;filter:drop-shadow(0 1px 1px rgba(0,0,0,.45));animation:hc-art-bob 3.4s ease-in-out infinite;-webkit-user-drag:none;user-select:none}\n.hc-ol.hc-art.hc-px img{image-rendering:pixelated}\n@keyframes hc-art-bob{0%,100%{transform:rotate(var(--hc-tilt,0deg)) translateY(0)}50%{transform:rotate(var(--hc-tilt,0deg)) translateY(-2px)}}\n.hc-ol.hc-runes{inset:-9px;z-index:2;color:var(--hc-hi);animation:hc-turn 14s linear infinite}\n.hc-ol.hc-runes svg{width:100%;height:100%;display:block}\n@keyframes hc-turn{to{transform:rotate(360deg)}}\n.hc-ol.hc-comet{inset:-6px;z-index:2;border-radius:50%;background:conic-gradient(from 0deg,transparent 0 270deg,color-mix(in oklch,var(--hc-hi) 10%,transparent) 300deg,var(--hc-hi) 358deg,transparent 360deg);-webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 3px),#000 calc(100% - 3px));mask:radial-gradient(farthest-side,transparent calc(100% - 3px),#000 calc(100% - 3px));animation:hc-turn 2.4s linear infinite}\n.hc-ol.hc-clip{inset:0;border-radius:50%;overflow:hidden;z-index:2}\n.hc-ol .hc-band{position:absolute;top:-30%;left:0;width:45%;height:160%;background:linear-gradient(90deg,transparent,color-mix(in oklch,var(--hc-hi) 70%,transparent),transparent);transform:translateX(-130%) rotate(20deg);animation:hc-band 5s ease-in-out infinite}\n@keyframes hc-band{0%{transform:translateX(-130%) rotate(20deg)}45%,100%{transform:translateX(260%) rotate(20deg)}}\n.hc-ol.hc-glow{inset:-30%;border-radius:50%;z-index:0;background:radial-gradient(circle,var(--hc-glow) 0,transparent 65%);animation:hc-glowp 3.2s ease-in-out infinite}\n@keyframes hc-glowp{0%,100%{opacity:.35;transform:scale(.92)}50%{opacity:.9;transform:scale(1.04)}}\n.hc-ol.hc-petal{top:-8%;height:100%;width:5px;z-index:2;animation:hc-fall 3.4s linear infinite both}\n.hc-ol.hc-petal::after{content:\"\";position:absolute;left:0;top:0;width:5px;height:7px;border-radius:5px 0;background:#f7b6c8;transform:rotate(35deg)}\n@keyframes hc-fall{0%{transform:translate(0,0);opacity:0}12%{opacity:.9}100%{transform:translate(-6px,100%);opacity:0}}\n\n/* --- message reveal: fill backwards only; the page swaps back to plain text when it ends --- */\n.hc-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}\n.hc-msg .hc-w{display:inline-block;white-space:nowrap}\n.hc-msg .hc-ch{display:inline-block}\n.hc-mt-type .hc-ch{animation:hc-in .01s linear calc(var(--hc-i) * var(--hc-step)) backwards}\n.hc-mt-type .hc-caret{display:inline-block;width:2px;height:1em;margin-left:2px;vertical-align:-2px;background:var(--hc-b);opacity:0;animation:hc-caret 1.5s steps(1) calc(var(--hc-i) * var(--hc-step)) backwards}\n@keyframes hc-caret{0%{opacity:0}1%{opacity:1}20%{opacity:0}40%{opacity:1}60%{opacity:0}80%{opacity:1}100%{opacity:0}}\n.hc-mt-cascade .hc-ch{animation:hc-drop .35s cubic-bezier(.3,1.5,.5,1) calc(var(--hc-i) * var(--hc-step)) backwards}\n.hc-mt-decode .hc-ch{position:relative}\n.hc-mt-decode .hc-ch .hc-r{display:inline-block;animation:hc-in .01s linear calc(var(--hc-i) * var(--hc-step) + 260ms) backwards}\n.hc-mt-decode .hc-ch::before,.hc-mt-decode .hc-ch::after{position:absolute;left:0;top:0;color:var(--hc-b);opacity:0;animation:hc-dec-a .26s steps(1) calc(var(--hc-i) * var(--hc-step)) backwards}\n.hc-mt-decode .hc-ch::before{content:attr(data-g)}\n.hc-mt-decode .hc-ch::after{content:attr(data-h);animation-name:hc-dec-b}\n@keyframes hc-dec-a{0%{opacity:.85}50%,100%{opacity:0}}\n@keyframes hc-dec-b{0%{opacity:0}50%{opacity:.85}100%{opacity:0}}\n.hc-mt-words .hc-w{animation:hc-rise .4s ease-out calc(var(--hc-i) * var(--hc-step)) backwards}\n.hc-mt-bubble .hc-w{animation:hc-pop .35s cubic-bezier(.3,1.6,.5,1) calc(var(--hc-i) * var(--hc-step)) backwards}\n.hc-mt-drift .hc-w{animation:hc-slide .45s cubic-bezier(.2,.8,.2,1) calc(var(--hc-i) * var(--hc-step)) backwards}\n@keyframes hc-in{from{opacity:0}to{opacity:1}}\n@keyframes hc-drop{0%{transform:translateY(-10px);opacity:0}100%{transform:none;opacity:1}}\n@keyframes hc-rise{0%{transform:translateY(10px);opacity:0}100%{transform:none;opacity:1}}\n@keyframes hc-pop{0%{transform:scale(.6);opacity:0}100%{transform:scale(1);opacity:1}}\n@keyframes hc-slide{0%{transform:translateX(-18px);opacity:0}100%{transform:none;opacity:1}}\n\n.hc-idle .hc-name,.hc-idle .hc-name *,.hc-idle .hc-av *,.hc-idle .hc-av *::after{animation-play-state:paused!important}\n@media (prefers-reduced-motion:reduce){.hc-name *,.hc-av *,.hc-av *::after,.hc-msg *,.hc-msg *::before,.hc-msg *::after{animation:none!important}}\n`;\n}\nfunction ensureCosmeticsStyles(doc = document, assetBase = COSMETICS_ASSET_BASE) {\n if (doc.getElementById(STYLE_ID)) return;\n const style = doc.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = cosmeticsCss(assetBase);\n doc.head.appendChild(style);\n doc.addEventListener(\"animationend\", finishReveal);\n}\nexport {\n COSMETICS,\n COSMETICS_ASSET_BASE,\n COSMETICS_BY_ID,\n COSMETIC_ID_PATTERN,\n COSMETIC_SLOTS,\n EARNED_COSMETICS,\n PLACEMENT_DEFAULT,\n PLACEMENT_LIMITS,\n PLACEMENT_ZONE,\n avatarHtml,\n cleanLoadout,\n cleanWorn,\n colourStyle,\n cosmeticsCss,\n decorHtml,\n emptyLoadout,\n ensureCosmeticsStyles,\n fitPlacement,\n messageHtml,\n nameHtml,\n overlayBounds,\n ownedFrom,\n placementTransform,\n wornCosmetics\n};\n"],"names":[],"mappings":"AACG,IAAC,iBAAiB,CAAC,UAAU,YAAY,QAAQ,WAAW,SAAS;AAExE,IAAI,OAAO,CAAC,MAAM,MAAM,OAAO,OAAO,CAAA,OAAQ,EAAE,IAAI,GAAG,IAAI,IAAI,IAAI,IAAI,MAAM,OAAO,GAAG;AACvF,IAAI,WAAW,EAAE,QAAQ,KAAI;AAC1B,IAAC,YAAY;AAAA,EACd,KAAK,UAAU,SAAS,OAAO;AAAA,EAC/B,KAAK,UAAU,QAAQ,MAAM;AAAA,EAC7B,KAAK,UAAU,OAAO,KAAK;AAAA,EAC3B,KAAK,UAAU,WAAW,SAAS;AAAA,EACnC,KAAK,UAAU,WAAW,WAAW,EAAE,MAAM,+BAA+B;AAAA,EAC5E,KAAK,YAAY,QAAQ,QAAQ;AAAA,EACjC,KAAK,YAAY,SAAS,OAAO;AAAA,EACjC,KAAK,YAAY,SAAS,OAAO;AAAA,EACjC,KAAK,YAAY,WAAW,SAAS;AAAA,EACrC,KAAK,YAAY,SAAS,OAAO;AAAA,EACjC,KAAK,QAAQ,UAAU,QAAQ;AAAA,EAC/B,KAAK,QAAQ,QAAQ,MAAM;AAAA,EAC3B,KAAK,QAAQ,UAAU,QAAQ;AAAA,EAC/B,KAAK,QAAQ,SAAS,OAAO;AAAA,EAC7B,KAAK,QAAQ,UAAU,QAAQ;AAAA,EAC/B,KAAK,QAAQ,QAAQ,cAAc,QAAQ;AAAA,EAC3C,KAAK,QAAQ,QAAQ,QAAQ,QAAQ;AAAA,EACrC,KAAK,QAAQ,WAAW,WAAW,QAAQ;AAAA,EAC3C,KAAK,QAAQ,SAAS,SAAS,QAAQ;AAAA,EACvC,KAAK,QAAQ,SAAS,SAAS,QAAQ;AAAA,EACvC,KAAK,QAAQ,WAAW,WAAW,QAAQ;AAAA,EAC3C,KAAK,QAAQ,SAAS,SAAS,QAAQ;AAAA,EACvC,KAAK,QAAQ,SAAS,SAAS,QAAQ;AAAA,EACvC,KAAK,QAAQ,SAAS,SAAS,QAAQ;AAAA,EACvC,KAAK,WAAW,SAAS,SAAS;AAAA,IAChC,MAAM;AAAA,IACN,KAAK;AAAA,MACH,MAAM;AAAA,MACN,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,OAAO;AAAA,MACP,SAAS,CAAC,OAAO,OAAO,OAAO,KAAK;AAAA,IAC1C;AAAA,EACA,CAAG;AAAA,EACD,KAAK,WAAW,QAAQ,QAAQ;AAAA,IAC9B,KAAK;AAAA,MACH,MAAM;AAAA,MACN,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,OAAO;AAAA,MACP,SAAS,CAAC,OAAO,OAAO,OAAO,KAAK;AAAA,IAC1C;AAAA,EACA,CAAG;AAAA,EACD,KAAK,WAAW,WAAW,gBAAgB;AAAA,IACzC,KAAK;AAAA,MACH,MAAM;AAAA,MACN,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,OAAO;AAAA,MACP,SAAS,CAAC,OAAO,OAAO,OAAO,KAAK;AAAA,IAC1C;AAAA,EACA,CAAG;AAAA,EACD,KAAK,WAAW,UAAU,QAAQ;AAAA,EAClC,KAAK,WAAW,SAAS,SAAS;AAAA,IAChC,GAAG;AAAA,IACH,KAAK;AAAA,MACH,MAAM;AAAA,MACN,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,OAAO;AAAA,MACP,SAAS,CAAC,OAAO,OAAO,OAAO,KAAK;AAAA,IAC1C;AAAA,EACA,CAAG;AAAA,EACD,KAAK,WAAW,SAAS,SAAS,QAAQ;AAAA,EAC1C,KAAK,WAAW,SAAS,SAAS,QAAQ;AAAA,EAC1C,KAAK,WAAW,SAAS,SAAS,QAAQ;AAAA,EAC1C,KAAK,WAAW,QAAQ,QAAQ,QAAQ;AAAA,EACxC,KAAK,WAAW,QAAQ,YAAY;AAAA,EACpC,KAAK,WAAW,UAAU,UAAU,EAAE,MAAM,+BAA+B;AAAA,EAC3E,KAAK,WAAW,WAAW,SAAS;AAAA,EACpC,KAAK,WAAW,SAAS,cAAc;AAAA,EACvC,KAAK,WAAW,UAAU,UAAU,QAAQ;AAAA,EAC5C,KAAK,WAAW,SAAS,OAAO;AAClC;AACG,IAAC,kBAAkB,IAAI;AAAA,EACxB,UAAU,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;AAChC;AACuB,UAAU;AAAA,EAC/B,CAAC,MAAM,EAAE,SAAS,UAAU,CAAC,EAAE;AACjC;AASG,IAAC,oBAAoB,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,KAAK,MAAM,OAAO,MAAM,MAAK;AACzE,IAAC,mBAAmB;AAAA,EACrB,GAAG,CAAC,KAAK,EAAE;AAAA,EACX,GAAG,CAAC,KAAK,GAAG;AAAA,EACZ,GAAG,CAAC,KAAK,EAAE;AAAA,EACX,GAAG,CAAC,IAAI,GAAG;AACb;AACA,SAAS,cAAc,KAAK,GAAG;AAC7B,QAAM,CAAC,GAAG,GAAG,GAAG,CAAC,IAAI,IAAI;AACzB,QAAM,KAAK,EAAE,OAAO,IAAI,IAAI;AAC5B,QAAM,KAAK,EAAE,OAAO,IAAI,IAAI;AAC5B,QAAM,IAAI,KAAK,IAAI,QAAQ;AAC3B,QAAM,IAAI,IAAI;AACd,QAAM,IAAI,IAAI;AACd,QAAM,KAAK,IAAI,IAAI;AACnB,QAAM,KAAK,IAAI,IAAI;AACnB,QAAM,KAAK,IAAI,IAAI;AACnB,QAAM,KAAK,IAAI,IAAI;AACnB,QAAM,IAAI,IAAI,OAAO,KAAK,KAAK;AAC/B,QAAM,IAAI,EAAE,IAAI,KAAK,KAAK;AAC1B,QAAM,KAAK,EAAE,IAAI;AACjB,QAAM,KAAK,CAAA;AACX,QAAM,KAAK,CAAA;AACX,aAAW,CAAC,IAAI,EAAE,KAAK;AAAA,IACrB,CAAC,IAAI,CAAC;AAAA,IACN,CAAC,IAAI,CAAC;AAAA,IACN,CAAC,IAAI,CAAC;AAAA,IACN,CAAC,IAAI,CAAC;AAAA,EACV,GAAK;AACD,UAAM,KAAK,IAAI,KAAK;AACpB,UAAM,KAAK,IAAI,KAAK;AACpB,UAAM,KAAK,MAAM,KAAK,MAAM,KAAK,IAAI,CAAC,KAAK,KAAK,MAAM,KAAK,IAAI,CAAC;AAChE,UAAM,KAAK,MAAM,KAAK,MAAM,KAAK,IAAI,CAAC,KAAK,KAAK,MAAM,KAAK,IAAI,CAAC;AAChE,UAAM,MAAM,KAAK,MAAM;AACvB,UAAM,MAAM,KAAK,MAAM;AACvB,OAAG,KAAK,KAAK,EAAE,IAAI,KAAK,KAAK,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC;AACtD,OAAG,KAAK,KAAK,EAAE,IAAI,KAAK,KAAK,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC;AAAA,EACxD;AACA,SAAO;AAAA,IACL,MAAM,KAAK,IAAI,GAAG,EAAE;AAAA,IACpB,KAAK,KAAK,IAAI,GAAG,EAAE;AAAA,IACnB,OAAO,KAAK,IAAI,GAAG,EAAE;AAAA,IACrB,QAAQ,KAAK,IAAI,GAAG,EAAE;AAAA,EAC1B;AACA;AACA,IAAI,YAAY,UAAU,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG;AAC5C,IAAC,iBAAiB;AAAA,EACnB,MAAM;AAAA,EACN,KAAK,KAAK,MAAM,KAAK,IAAI,GAAG,UAAU,IAAI,CAAC,MAAM,cAAc,EAAE,KAAK,iBAAiB,EAAE,GAAG,CAAC,CAAC;AAAA,EAC9F,OAAO;AAAA,EACP,QAAQ;AACV;AACA,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC;AACzD,SAAS,aAAa,KAAK,KAAK;AAC9B,QAAM,MAAM,CAAC,GAAG,aAAa,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC,IAAI,IAAI;AAC/E,QAAM,IAAI;AAAA,IACR,GAAG,KAAK,MAAM,MAAM,IAAI,IAAI,GAAG,CAAC,GAAG,iBAAiB,CAAC,CAAC;AAAA,IACtD,GAAG,KAAK,MAAM,MAAM,IAAI,IAAI,GAAG,CAAC,GAAG,iBAAiB,CAAC,CAAC;AAAA,IACtD,GAAG,KAAK,MAAM,MAAM,IAAI,IAAI,GAAG,CAAC,GAAG,iBAAiB,CAAC,CAAC;AAAA,IACtD,GAAG,KAAK,MAAM,MAAM,IAAI,IAAI,GAAG,GAAG,GAAG,iBAAiB,CAAC,CAAC;AAAA,IACxD,MAAM,IAAI,SAAS;AAAA,IACnB,MAAM,IAAI,SAAS;AAAA,EACvB;AACE,QAAM,IAAI;AACV,MAAI,MAAM,cAAc,KAAK,CAAC;AAC9B,QAAM,OAAO,KAAK;AAAA,KACf,EAAE,QAAQ,EAAE,OAAO,MAAM,IAAI,QAAQ,IAAI;AAAA,KACzC,EAAE,SAAS,EAAE,MAAM,MAAM,IAAI,SAAS,IAAI;AAAA,EAC/C;AACE,MAAI,OAAO,GAAG;AACZ,MAAE,IAAI,KAAK,IAAI,iBAAiB,EAAE,CAAC,GAAG,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC;AAC5D,UAAM,cAAc,KAAK,CAAC;AAAA,EAC5B;AACA,IAAE,KAAK,KAAK,KAAK,KAAK,IAAI,GAAG,EAAE,OAAO,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,KAAK,IAAI,GAAG,IAAI,QAAQ,EAAE,KAAK,CAAC;AAC7F,IAAE,KAAK,KAAK,KAAK,KAAK,IAAI,GAAG,EAAE,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK,KAAK,IAAI,GAAG,IAAI,SAAS,EAAE,MAAM,CAAC;AAC7F,SAAO;AACT;AACA,SAAS,eAAe;AACtB,SAAO;AAAA,IACL,UAAU,EAAE,QAAQ,MAAM,UAAU,MAAM,MAAM,MAAM,SAAS,MAAM,SAAS,KAAI;AAAA,IAClF,WAAW,CAAA;AAAA,EACf;AACA;AAgBA,SAAS,aAAa,KAAK,OAAO;AAChC,QAAM,MAAM,aAAY;AACxB,QAAM,MAAM,OAAO,OAAO,QAAQ,WAAW,MAAM,CAAA;AACnD,aAAW,QAAQ,gBAAgB;AACjC,UAAM,KAAK,IAAI,WAAW,IAAI;AAC9B,UAAM,KAAK,OAAO,OAAO,WAAW,gBAAgB,IAAI,EAAE,IAAI;AAC9D,QAAI,MAAM,CAAC,GAAG,UAAU,MAAM,IAAI,GAAG,EAAE,KAAK,GAAG,SAAS,MAAM;AAC5D,UAAI,SAAS,IAAI,IAAI,GAAG;AAAA,IAC1B;AAAA,EACF;AACA,aAAW,CAAC,IAAI,CAAC,KAAK,OAAO,QAAQ,IAAI,aAAa,CAAA,CAAE,GAAG;AACzD,UAAM,KAAK,gBAAgB,IAAI,EAAE;AACjC,UAAM,MAAM,IAAI;AAChB,QAAI,OAAO,CAAC,GAAG,UAAU,MAAM,IAAI,EAAE,KAAK,KAAK,OAAO,MAAM,UAAU;AACpE,UAAI,UAAU,EAAE,IAAI,aAAa,KAAK,CAAC;AAAA,IACzC;AAAA,EACF;AACA,SAAO;AACT;AACA,SAAS,cAAc,SAAS;AAC9B,QAAM,OAAO,CAAA;AACb,aAAW,QAAQ,gBAAgB;AACjC,UAAM,KAAK,QAAQ,SAAS,IAAI;AAChC,QAAI,GAAI,MAAK,IAAI,IAAI;AAAA,EACvB;AACA,QAAM,UAAU,QAAQ,SAAS;AACjC,MAAI,WAAW,gBAAgB,IAAI,OAAO,GAAG,OAAO,QAAQ,UAAU,OAAO,GAAG;AAC9E,SAAK,YAAY,QAAQ,UAAU,OAAO;AAAA,EAC5C;AACA,SAAO,OAAO,KAAK,IAAI,EAAE,SAAS,OAAO;AAC3C;AAGG,IAAC,uBAAuB;AAC3B,IAAI,WAAW;AACf,IAAI,MAAM,CAAC,MAAM,EAAE;AAAA,EACjB;AAAA,EACA,CAAC,OAAO,EAAE,KAAK,SAAS,KAAK,QAAQ,KAAK,QAAQ,KAAK,UAAU,KAAK,QAAO,GAAI,CAAC;AACpF;AACA,IAAI,SAAS,CAAC,OAAO,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC,IAAI;AAI1D,SAAS,mBAAmB,GAAG;AAC7B,QAAM,KAAK,EAAE,IAAI,OAAO,EAAE,OAAO,KAAK;AACtC,SAAO,kCAAkC,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,0BAA0B,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,aAAa,EAAE,CAAC,cAAc,GAAG,QAAQ,CAAC,CAAC,KAAK,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC;AACpL;AACA,IAAI,gBAAgC,oBAAI,IAAI,CAAC,KAAK,CAAC;AACnD,SAAS,SAAS,MAAM,MAAM,OAAO,CAAA,GAAI;AACvC,QAAM,KAAK,OAAO,MAAM,MAAM;AAC9B,QAAM,KAAK,OAAO,MAAM,QAAQ;AAChC,QAAM,OAAO,OAAO,MAAM,IAAI;AAC9B,QAAM,IAAI,IAAI,IAAI;AAClB,QAAM,QAAQ,cAAc,IAAI,EAAE;AAClC,QAAM,KAAK,QAAQ,uBAAuB,CAAC,GAAG,IAAI,EAAE;AAAA,IAClD,CAAC,GAAG,MAAM,qCAAqC,CAAC,wBAAwB,MAAM,MAAM,WAAW,IAAI,CAAC,CAAC;AAAA,EACzG,EAAI,KAAK,EAAE,CAAC,YAAY,uBAAuB,CAAC;AAC9C,QAAM,QAAQ,CAAC,SAAS,sBAAsB,IAAI,wBAAwB,CAAC;AAC3E,MAAI,OAAO;AACX,MAAI,QAAQ;AACZ,MAAI,OAAO,UAAU,OAAO,UAAW,SAAQ,MAAM,OAAO;AAC5D,MAAI,OAAO,QAAS,UAAS,2CAA2C,MAAM,EAAE,CAAC;AACjF,MAAI,OAAO,WAAW;AACpB,aAAS;AAAA,MACP,CAAC,IAAI,KAAK,CAAC;AAAA,MACX,CAAC,IAAI,IAAI,IAAI;AAAA,MACb,CAAC,IAAI,KAAK,GAAG;AAAA,IACnB,EAAM;AAAA,MACA,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,mDAAmD,CAAC,SAAS,CAAC,qBAAqB,CAAC;AAAA,IACzG,EAAM,KAAK,EAAE;AAAA,EACX;AACA,QAAM,MAAM,iBAAiB,EAAE,UAAU,EAAE,YAAY,IAAI,GAAG,QAAQ,cAAc,EAAE,GAAG,KAAK,QAAQ,cAAc,EAAE;AACtH,SAAO,gBAAgB,GAAG,KAAK,IAAI,GAAG,EAAE,GAAG,KAAK;AAClD;AACA,IAAI,aAAa,MAAM;AACrB,MAAI,QAAQ;AACZ,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,aAAS,wBAAwB,IAAI,EAAE,gFAAgF,IAAI,IAAI,OAAO,CAAC;AAAA,EACzI;AACA,SAAO,wKAAwK,KAAK;AACtL,GAAC;AACD,SAAS,UAAU,MAAM,YAAY,sBAAsB;AACzD,QAAM,KAAK,MAAM;AACjB,MAAI,CAAC,GAAI,QAAO;AAChB,QAAM,MAAM,gBAAgB,IAAI,EAAE,GAAG;AACrC,MAAI,KAAK;AACP,UAAM,IAAI,MAAM,aAAa;AAC7B,WAAO,4BAA4B,IAAI,QAAQ,WAAW,EAAE,kBAAkB,IAAI,EAAE,CAAC,iBAAiB,KAAK,IAAI,QAAQ,CAAC,SAAS,IAAI,GAAG,WAAW,IAAI,KAAK,aAAa,EAAE,OAAO,IAAI,CAAC,2CAA2C,mBAAmB,CAAC,CAAC,oDAAoD,IAAI,IAAI,aAAa,IAAI,GAAG,SAAS,QAAQ,IAAI,IAAI,EAAE,CAAC;AAAA,EACrW;AACA,UAAQ,OAAO,EAAE,GAAC;AAAA,IAChB,KAAK;AACH,aAAO,gCAAgC,SAAS;AAAA,IAClD,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,CAAC,IAAI,IAAI,IAAI,EAAE,EAAE;AAAA,QACtB,CAAC,GAAG,MAAM,yCAAyC,CAAC,sBAAsB,IAAI,MAAM,QAAQ,CAAC,CAAC;AAAA,MACtG,EAAQ,KAAK,EAAE;AAAA,IACX;AACE,aAAO;AAAA,EACb;AACA;AACA,SAAS,WAAW,GAAG;AACrB,QAAM,MAAM,EAAE,MAAM,oBAAoB,IAAI,EAAE,GAAG,CAAC,OAAO;AACzD,SAAO,sCAAsC,EAAE,IAAI,4BAA4B,GAAG,UAAU,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC;AAC5H;AACA,IAAI,SAAS;AACb,IAAI,eAA+B,oBAAI,IAAI,CAAC,QAAQ,UAAU,SAAS,CAAC;AACxE,IAAI,YAAY;AAChB,IAAI,eAAe;AACnB,SAAS,YAAY,MAAM,MAAM,OAAO,CAAA,GAAI;AAC1C,MAAI,OAAO,OAAO,MAAM,OAAO;AAC/B,MAAI,SAAS,OAAQ,QAAO,wBAAwB,IAAI,IAAI,CAAC;AAC7D,QAAM,QAAQ,KAAK,MAAM,KAAK,EAAE,OAAO,OAAO;AAC9C,MAAI,aAAa,IAAI,IAAI,KAAK,KAAK,SAAS,aAAc,QAAO;AACjE,QAAM,OAAO,KAAK,OAAO,kBAAkB;AAC3C,MAAI;AACJ,MAAI;AACJ,MAAI,aAAa,IAAI,IAAI,GAAG;AAC1B,WAAO,KAAK,IAAI,IAAI,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,CAAC;AACxD,QAAI,IAAI;AACR,UAAM,MAAM,MAAM,OAAO,KAAK,MAAM,KAAK,OAAM,IAAK,OAAO,MAAM,CAAC;AAClE,WAAO,MAAM;AAAA,MACX,CAAC,MAAM,sBAAsB,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM;AAC7C,cAAM,IAAI;AACV,eAAO,SAAS,WAAW,qCAAqC,CAAC,aAAa,IAAI,IAAG,CAAE,CAAC,aAAa,IAAI,IAAG,CAAE,CAAC,wBAAwB,IAAI,CAAC,CAAC,mBAAmB,qCAAqC,CAAC,KAAK,IAAI,CAAC,CAAC;AAAA,MACnN,CAAC,EAAE,KAAK,EAAE,CAAC;AAAA,IACjB,EAAM,KAAK,GAAG;AACV,QAAI,SAAS,OAAQ,SAAQ,wCAAwC,CAAC;AACtE,UAAM,YAAY,SAAS,SAAS,aAAa,SAAS,WAAW,SAAS;AAC9E,UAAM,KAAK,KAAK,YAAY,gBAAgB,SAAS,GAAG;AACxD,WAAO,GAAG,KAAK,MAAM,GAAG,EAAE,CAAC,6BAA6B,SAAS,IAAI,KAAK,MAAM,KAAK,gBAAgB,SAAS,IAAI,MAAM,CAAC;AAAA,EAC3H,OAAO;AACL,WAAO,KAAK,IAAI,IAAI,YAAY,KAAK,IAAI,GAAG,MAAM,MAAM,CAAC;AACzD,WAAO,MAAM;AAAA,MACX,CAAC,GAAG,MAAM,oCAAoC,CAAC,IAAI,MAAM,MAAM,SAAS,IAAI,kBAAkB,EAAE,IAAI,IAAI,CAAC,CAAC;AAAA,IAChH,EAAM,KAAK,GAAG;AAAA,EACZ;AACA,SAAO,6BAA6B,IAAI,sBAAsB,KAAK,QAAQ,CAAC,CAAC,kBAAkB,IAAI,IAAI,CAAC,IAAI,IAAI,wBAAwB,IAAI,IAAI,CAAC,mCAAmC,IAAI;AAC1L;AACA,SAAS,aAAa,GAAG;AACvB,QAAM,IAAI,EAAE;AACZ,MAAI,EAAE,iBAAiB,CAAC,GAAG,eAAe,cAAc,EAAG;AAC3D,QAAM,MAAM,EAAE,QAAQ,SAAS;AAC/B,MAAI,CAAC,OAAO,IAAI,aAAa,cAAc,EAAG;AAC9C,MAAI,YAAY;AAChB,MAAI,gBAAgB,OAAO;AAC3B,MAAI,cAAc,IAAI,aAAa,WAAW,KAAK;AACrD;AACA,IAAI,QAAQ;AAAA,EACV,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,KAAK;AAAA,EACT;AAAA,EACE,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,KAAK;AAAA,EACT;AAAA,EACE,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,KAAK;AAAA,EACT;AAAA,EACE,OAAO,EAAE,MAAM,UAAU,QAAQ,kBAAkB,SAAS,SAAS,KAAK,kBAAiB;AAAA,EAC3F,SAAS;AAAA,IACP,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,KAAK;AAAA,EACT;AAAA,EACE,OAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,KAAK;AAAA,EACT;AAAA,EACE,OAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,KAAK;AAAA,EACT;AAAA,EACE,SAAS;AAAA,IACP,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,KAAK;AAAA,EACT;AAAA,EACE,OAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,KAAK;AAAA,EACT;AAAA,EACE,OAAO,EAAE,MAAM,aAAa,QAAQ,aAAa,SAAS,cAAc,KAAK,kBAAiB;AAAA,EAC9F,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,KAAK;AAAA,EACT;AAAA,EACE,OAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,KAAK;AAAA,EACT;AACA;AACA,SAAS,aAAa,YAAY,sBAAsB;AACtD,QAAM,YAAY,OAAO,QAAQ,KAAK,EAAE;AAAA,IACtC,CAAC,CAAC,GAAG,CAAC,MAAM,8BAA8B,CAAC,cAAc,SAAS,UAAU,EAAE,IAAI;AAAA,EACtF,EAAI,KAAK,IAAI;AACX,QAAM,YAAY,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,YAAY,CAAC,oBAAoB,CAAC,MAAM,EAAE,MAAM,KAAK,EAAE,OAAO,IAAI,EAAE,GAAG,GAAG,EAAE,KAAK,IAAI;AAC7I,SAAO,GAAG,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoCnB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoDX;AACA,SAAS,sBAAsB,MAAM,UAAU,YAAY,sBAAsB;AAC/E,MAAI,IAAI,eAAe,QAAQ,EAAG;AAClC,QAAM,QAAQ,IAAI,cAAc,OAAO;AACvC,QAAM,KAAK;AACX,QAAM,cAAc,aAAa,SAAS;AAC1C,MAAI,KAAK,YAAY,KAAK;AAC1B,MAAI,iBAAiB,gBAAgB,YAAY;AACnD;","x_google_ignoreList":[0]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hadoku/task-ui-components",
|
|
3
|
-
"version": "4.23.
|
|
4
|
-
"gitHead": "
|
|
3
|
+
"version": "4.23.9",
|
|
4
|
+
"gitHead": "6e3d23d31054eda3d8d332c8ed41660e43e2e9c8",
|
|
5
5
|
"description": "Reusable UI components with Bento grid and metallic gradient support",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
* screens stack the two.
|
|
9
9
|
*
|
|
10
10
|
* Cosmetics (`@wolffm/prefs-client/cosmetics`, bundled at build like the avatar
|
|
11
|
-
* client):
|
|
12
|
-
*
|
|
11
|
+
* client): what the person owns equips on click (every shown item is free but
|
|
12
|
+
* three earned in a Major); an earned item not yet earned shows how to earn
|
|
13
|
+
* it and can be tried on in the preview, which saves nothing. An overlay
|
|
13
14
|
* image can be placed: drag it on the big preview, turn it with the top handle,
|
|
14
15
|
* resize it with the corner handle, or use the sliders. Every move goes through
|
|
15
16
|
* `fitPlacement`, the same function prefs-api runs before it stores one, so the
|
|
@@ -180,7 +181,6 @@ const S = {
|
|
|
180
181
|
color: 'var(--color-text-muted)'
|
|
181
182
|
},
|
|
182
183
|
tabOn: { color: 'var(--color-text)', borderBottomColor: 'var(--color-primary)' },
|
|
183
|
-
count: { fontSize: '0.68rem', marginLeft: 4, opacity: 0.8, fontVariantNumeric: 'tabular-nums' },
|
|
184
184
|
pane: { display: 'flex', flexDirection: 'column', gap: 10, paddingTop: 10 },
|
|
185
185
|
grid: { display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(112px, 1fr))', gap: 8 },
|
|
186
186
|
tile: {
|
|
@@ -347,9 +347,11 @@ function useDragScroll<T extends HTMLElement>() {
|
|
|
347
347
|
export interface AvatarBuilderProps {
|
|
348
348
|
/** The person's display name, for the preview. */
|
|
349
349
|
name: string | null
|
|
350
|
+
/** Admins also see archived items (greyed; nobody can select one). */
|
|
351
|
+
isAdmin?: boolean
|
|
350
352
|
}
|
|
351
353
|
|
|
352
|
-
export function AvatarBuilder({ name }: AvatarBuilderProps) {
|
|
354
|
+
export function AvatarBuilder({ name, isAdmin = false }: AvatarBuilderProps) {
|
|
353
355
|
const [settings, setSettings] = useState<AvatarSettings | null>(null)
|
|
354
356
|
const [sets, setSets] = useState<CharacterSet[] | null>(null)
|
|
355
357
|
const [busy, setBusy] = useState(false)
|
|
@@ -617,7 +619,6 @@ export function AvatarBuilder({ name }: AvatarBuilderProps) {
|
|
|
617
619
|
<div style={{ minWidth: 0 }}>
|
|
618
620
|
<div ref={tabStrip} style={S.tabs} role="tablist" aria-label="Avatar">
|
|
619
621
|
{tabs.map(t => {
|
|
620
|
-
const items = t === 'picture' ? [] : COSMETICS.filter(i => i.slot === t)
|
|
621
622
|
return (
|
|
622
623
|
<button
|
|
623
624
|
key={t}
|
|
@@ -628,15 +629,20 @@ export function AvatarBuilder({ name }: AvatarBuilderProps) {
|
|
|
628
629
|
onClick={e => {
|
|
629
630
|
setTab(t)
|
|
630
631
|
setTryOn(null)
|
|
631
|
-
|
|
632
|
+
// Where the strip overflows (narrow screens), a tab in its
|
|
633
|
+
// right half shifts the strip to the end and one in its left
|
|
634
|
+
// half to the start, so the tabs past the chosen one show.
|
|
635
|
+
const strip = e.currentTarget.parentElement
|
|
636
|
+
if (strip && strip.scrollWidth > strip.clientWidth) {
|
|
637
|
+
const right = tabs.indexOf(t) >= tabs.length / 2
|
|
638
|
+
strip.scrollTo({
|
|
639
|
+
left: right ? strip.scrollWidth - strip.clientWidth : 0,
|
|
640
|
+
behavior: 'smooth'
|
|
641
|
+
})
|
|
642
|
+
}
|
|
632
643
|
}}
|
|
633
644
|
>
|
|
634
645
|
{tabLabel(t)}
|
|
635
|
-
{t !== 'picture' && (
|
|
636
|
-
<span style={S.count}>
|
|
637
|
-
{items.filter(i => owned.has(i.id)).length}/{items.length}
|
|
638
|
-
</span>
|
|
639
|
-
)}
|
|
640
646
|
</button>
|
|
641
647
|
)
|
|
642
648
|
})}
|
|
@@ -652,6 +658,7 @@ export function AvatarBuilder({ name }: AvatarBuilderProps) {
|
|
|
652
658
|
tryOn={tryOn}
|
|
653
659
|
showLocked={showLocked}
|
|
654
660
|
onShowLocked={setShowLocked}
|
|
661
|
+
isAdmin={isAdmin}
|
|
655
662
|
preview={id => {
|
|
656
663
|
const only: AvatarCosmetics = { [tab]: id ?? undefined }
|
|
657
664
|
if (tab === 'overlay') return avatarHtml({ src: picture, size: 40, worn: only })
|
|
@@ -812,13 +819,18 @@ interface SlotGridProps {
|
|
|
812
819
|
tryOn: { slot: CosmeticSlot; id: string } | null
|
|
813
820
|
showLocked: boolean
|
|
814
821
|
onShowLocked: (on: boolean) => void
|
|
822
|
+
/** Admins see archived items, greyed and not selectable. */
|
|
823
|
+
isAdmin: boolean
|
|
815
824
|
preview: (id: string | null) => string
|
|
816
825
|
colour: React.CSSProperties
|
|
817
826
|
onEquip: (id: string | null) => void
|
|
818
827
|
onTry: (id: string) => void
|
|
819
828
|
}
|
|
820
829
|
|
|
821
|
-
/**
|
|
830
|
+
/**
|
|
831
|
+
* One slot's items: None, then the shown items, free or earned. Archived items
|
|
832
|
+
* show only to admins, greyed and not selectable; nobody can wear one.
|
|
833
|
+
*/
|
|
822
834
|
function SlotGrid({
|
|
823
835
|
slot,
|
|
824
836
|
owned,
|
|
@@ -826,14 +838,15 @@ function SlotGrid({
|
|
|
826
838
|
tryOn,
|
|
827
839
|
showLocked,
|
|
828
840
|
onShowLocked,
|
|
841
|
+
isAdmin,
|
|
829
842
|
preview,
|
|
830
843
|
colour,
|
|
831
844
|
onEquip,
|
|
832
845
|
onTry
|
|
833
846
|
}: SlotGridProps) {
|
|
834
|
-
const items = COSMETICS.filter(i => i.slot === slot)
|
|
835
|
-
const locked = items.filter(i => !owned.has(i.id))
|
|
836
|
-
const shown = showLocked ? items : items.filter(i => owned.has(i.id))
|
|
847
|
+
const items = COSMETICS.filter(i => i.slot === slot && (!i.hidden || isAdmin))
|
|
848
|
+
const locked = items.filter(i => !i.hidden && !owned.has(i.id))
|
|
849
|
+
const shown = showLocked ? items : items.filter(i => i.hidden || owned.has(i.id))
|
|
837
850
|
|
|
838
851
|
return (
|
|
839
852
|
<>
|
|
@@ -848,6 +861,21 @@ function SlotGrid({
|
|
|
848
861
|
<span style={S.tileName}>None</span>
|
|
849
862
|
</button>
|
|
850
863
|
{shown.map(item => {
|
|
864
|
+
if (item.hidden) {
|
|
865
|
+
return (
|
|
866
|
+
<button
|
|
867
|
+
key={item.id}
|
|
868
|
+
type="button"
|
|
869
|
+
disabled
|
|
870
|
+
aria-label={`${item.label}, archived`}
|
|
871
|
+
style={{ ...S.tile, cursor: 'not-allowed', opacity: 0.45 }}
|
|
872
|
+
>
|
|
873
|
+
<Html html={preview(item.id)} style={{ ...S.tilePv, ...colour }} />
|
|
874
|
+
<span style={S.tileName}>{item.label}</span>
|
|
875
|
+
<span style={S.tileEarn}>Archived</span>
|
|
876
|
+
</button>
|
|
877
|
+
)
|
|
878
|
+
}
|
|
851
879
|
const own = owned.has(item.id)
|
|
852
880
|
const on = equipped === item.id
|
|
853
881
|
const trying = tryOn?.slot === slot && tryOn.id === item.id
|
|
@@ -856,7 +884,7 @@ function SlotGrid({
|
|
|
856
884
|
key={item.id}
|
|
857
885
|
type="button"
|
|
858
886
|
aria-pressed={own ? on : trying}
|
|
859
|
-
aria-label={own ? item.label : `${item.label}, locked. ${item.earn}. Try it on.`}
|
|
887
|
+
aria-label={own ? item.label : `${item.label}, locked. ${item.earn ?? ''}. Try it on.`}
|
|
860
888
|
style={{
|
|
861
889
|
...S.tile,
|
|
862
890
|
...(on ? S.tileOn : {}),
|
|
@@ -879,13 +907,12 @@ function SlotGrid({
|
|
|
879
907
|
)
|
|
880
908
|
})}
|
|
881
909
|
</div>
|
|
882
|
-
|
|
883
|
-
<
|
|
884
|
-
|
|
885
|
-
? `${locked.length}
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
{locked.length > 0 && (
|
|
910
|
+
{locked.length > 0 && (
|
|
911
|
+
<div style={S.foot}>
|
|
912
|
+
<span>
|
|
913
|
+
{locked.length === 1 ? 'One to earn.' : `${locked.length} to earn.`} Pick one to try it
|
|
914
|
+
on.
|
|
915
|
+
</span>
|
|
889
916
|
<label>
|
|
890
917
|
<input
|
|
891
918
|
type="checkbox"
|
|
@@ -894,8 +921,8 @@ function SlotGrid({
|
|
|
894
921
|
/>{' '}
|
|
895
922
|
Show locked
|
|
896
923
|
</label>
|
|
897
|
-
|
|
898
|
-
|
|
924
|
+
</div>
|
|
925
|
+
)}
|
|
899
926
|
</>
|
|
900
927
|
)
|
|
901
928
|
}
|
|
@@ -57,9 +57,17 @@ export interface AvatarDialogProps {
|
|
|
57
57
|
returnFocus?: React.RefObject<HTMLElement | null>
|
|
58
58
|
/** The person's display name, shown in the preview. */
|
|
59
59
|
name?: string | null
|
|
60
|
+
/** Admins also see archived cosmetics. */
|
|
61
|
+
isAdmin?: boolean
|
|
60
62
|
}
|
|
61
63
|
|
|
62
|
-
export function AvatarDialog({
|
|
64
|
+
export function AvatarDialog({
|
|
65
|
+
open,
|
|
66
|
+
onClose,
|
|
67
|
+
returnFocus,
|
|
68
|
+
name = null,
|
|
69
|
+
isAdmin = false
|
|
70
|
+
}: AvatarDialogProps) {
|
|
63
71
|
const titleId = useId()
|
|
64
72
|
const cardRef = useRef<HTMLDivElement>(null)
|
|
65
73
|
const onCloseRef = useRef(onClose)
|
|
@@ -110,7 +118,7 @@ export function AvatarDialog({ open, onClose, returnFocus, name = null }: Avatar
|
|
|
110
118
|
Done
|
|
111
119
|
</button>
|
|
112
120
|
</div>
|
|
113
|
-
<AvatarBuilder name={name} />
|
|
121
|
+
<AvatarBuilder name={name} isAdmin={isAdmin} />
|
|
114
122
|
</div>
|
|
115
123
|
</div>,
|
|
116
124
|
document.body
|