packing-bingo 0.4.0 → 0.6.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.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { CSSProperties } from 'react';
3
- import { PackingBingoOptions, PackingBingoState } from './core.cjs';
4
- export { BingoEvent, BingoItem, DEFAULT_ITEMS, LINES, Messages, PackingBingoInstance, PerfectEvent, bingoLines, createPackingBingo, en, ja } from './core.cjs';
3
+ import { PackingBingoOptions, BingoMode, PackingBingoState } from './core.cjs';
4
+ export { BingoEvent, BingoItem, DEFAULT_ITEMS, FinishEvent, LINES, Messages, PackingBingoInstance, PerfectEvent, bingoLines, createPackingBingo, en, ja, speedBonus } from './core.cjs';
5
5
 
6
6
  interface PackingBingoProps extends Omit<PackingBingoOptions, "controlled" | "defaultChecked"> {
7
7
  /** Controlled state (one boolean per item). Update it from `onChange`. */
@@ -16,6 +16,10 @@ interface PackingBingoHandle {
16
16
  reset(): void;
17
17
  /** Move the items to random squares, as the 🔀 button does. Checks stay with their items. */
18
18
  shuffle(): void;
19
+ /** Switch between the packing card and the infinite mode, as the switch does (with its animation). */
20
+ setMode(mode: BingoMode): void;
21
+ /** End a running infinite game and show its results, as the 🏁 FINISH button does. */
22
+ finish(): void;
19
23
  /** Set the card. A one-item change plays like a tap; bigger jumps apply quietly. */
20
24
  setChecked(checked: readonly boolean[]): void;
21
25
  getState(): PackingBingoState | null;
@@ -26,5 +30,5 @@ interface PackingBingoHandle {
26
30
  */
27
31
  declare const PackingBingo: react.ForwardRefExoticComponent<PackingBingoProps & react.RefAttributes<PackingBingoHandle>>;
28
32
 
29
- export { PackingBingo, PackingBingoOptions, PackingBingoState };
33
+ export { BingoMode, PackingBingo, PackingBingoOptions, PackingBingoState };
30
34
  export type { PackingBingoHandle, PackingBingoProps };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { CSSProperties } from 'react';
3
- import { PackingBingoOptions, PackingBingoState } from './core.js';
4
- export { BingoEvent, BingoItem, DEFAULT_ITEMS, LINES, Messages, PackingBingoInstance, PerfectEvent, bingoLines, createPackingBingo, en, ja } from './core.js';
3
+ import { PackingBingoOptions, BingoMode, PackingBingoState } from './core.js';
4
+ export { BingoEvent, BingoItem, DEFAULT_ITEMS, FinishEvent, LINES, Messages, PackingBingoInstance, PerfectEvent, bingoLines, createPackingBingo, en, ja, speedBonus } from './core.js';
5
5
 
6
6
  interface PackingBingoProps extends Omit<PackingBingoOptions, "controlled" | "defaultChecked"> {
7
7
  /** Controlled state (one boolean per item). Update it from `onChange`. */
@@ -16,6 +16,10 @@ interface PackingBingoHandle {
16
16
  reset(): void;
17
17
  /** Move the items to random squares, as the 🔀 button does. Checks stay with their items. */
18
18
  shuffle(): void;
19
+ /** Switch between the packing card and the infinite mode, as the switch does (with its animation). */
20
+ setMode(mode: BingoMode): void;
21
+ /** End a running infinite game and show its results, as the 🏁 FINISH button does. */
22
+ finish(): void;
19
23
  /** Set the card. A one-item change plays like a tap; bigger jumps apply quietly. */
20
24
  setChecked(checked: readonly boolean[]): void;
21
25
  getState(): PackingBingoState | null;
@@ -26,5 +30,5 @@ interface PackingBingoHandle {
26
30
  */
27
31
  declare const PackingBingo: react.ForwardRefExoticComponent<PackingBingoProps & react.RefAttributes<PackingBingoHandle>>;
28
32
 
29
- export { PackingBingo, PackingBingoOptions, PackingBingoState };
33
+ export { BingoMode, PackingBingo, PackingBingoOptions, PackingBingoState };
30
34
  export type { PackingBingoHandle, PackingBingoProps };
package/dist/index.js CHANGED
@@ -6,18 +6,20 @@ import {
6
6
  createPackingBingo,
7
7
  en,
8
8
  ja,
9
- resolveStorageKey
10
- } from "./chunk-BAA2CFUA.js";
9
+ resolveStorageKey,
10
+ speedBonus
11
+ } from "./chunk-A5JVNVWS.js";
11
12
 
12
13
  // src/react.tsx
13
14
  import { forwardRef, useEffect, useImperativeHandle, useRef } from "react";
14
15
  import { jsx } from "react/jsx-runtime";
15
16
  var PackingBingo = forwardRef(function PackingBingo2(props, ref) {
16
- const { checked, defaultChecked, defaultOrder, className, style, onChange, onBingo, onPerfect, messages, fonts: _fonts, ...config } = props;
17
+ const { checked, defaultChecked, defaultOrder, className, style, onChange, onBingo, onPerfect, onModeChange, onFinish, mode, messages, fonts: _fonts, ...config } = props;
17
18
  const host = useRef(null);
18
19
  const inst = useRef(null);
19
- const callbacks = useRef({ onChange, onBingo, onPerfect });
20
- callbacks.current = { onChange, onBingo, onPerfect };
20
+ const callbacks = useRef({ onChange, onBingo, onPerfect, onModeChange, onFinish });
21
+ callbacks.current = { onChange, onBingo, onPerfect, onModeChange, onFinish };
22
+ const latestMode = useRef(mode);
21
23
  const messagesRef = useRef(messages);
22
24
  messagesRef.current = messages;
23
25
  const controlled = checked !== void 0;
@@ -47,13 +49,20 @@ var PackingBingo = forwardRef(function PackingBingo2(props, ref) {
47
49
  callbacks.current.onChange?.(next);
48
50
  },
49
51
  onBingo: (e) => callbacks.current.onBingo?.(e),
50
- onPerfect: (e) => callbacks.current.onPerfect?.(e)
52
+ onPerfect: (e) => callbacks.current.onPerfect?.(e),
53
+ onFinish: (e) => callbacks.current.onFinish?.(e),
54
+ mode: latestMode.current,
55
+ onModeChange: (m) => {
56
+ latestMode.current = m;
57
+ callbacks.current.onModeChange?.(m);
58
+ }
51
59
  });
52
60
  inst.current = instance;
53
61
  return () => {
54
62
  const state = instance.getState();
55
- if (!controlled) latest.current = state.checked;
56
- latestOrder.current = state.order;
63
+ const packed = state.packing ?? state;
64
+ if (!controlled) latest.current = packed.checked;
65
+ latestOrder.current = packed.order;
57
66
  latestKey.current = storageKey;
58
67
  instance.destroy();
59
68
  if (inst.current === instance) inst.current = null;
@@ -65,11 +74,16 @@ var PackingBingo = forwardRef(function PackingBingo2(props, ref) {
65
74
  useEffect(() => {
66
75
  if (controlled && checked) inst.current?.setChecked(checked, { animate: true });
67
76
  }, [controlled, checked]);
77
+ useEffect(() => {
78
+ if (mode) inst.current?.setMode(mode);
79
+ }, [mode]);
68
80
  useImperativeHandle(
69
81
  ref,
70
82
  () => ({
71
83
  reset: () => inst.current?.reset(),
72
84
  shuffle: () => inst.current?.shuffle(),
85
+ setMode: (m) => inst.current?.setMode(m),
86
+ finish: () => inst.current?.finish(),
73
87
  setChecked: (next) => inst.current?.setChecked(next, { animate: true }),
74
88
  getState: () => inst.current?.getState() ?? null
75
89
  }),
@@ -84,5 +98,6 @@ export {
84
98
  bingoLines,
85
99
  createPackingBingo,
86
100
  en,
87
- ja
101
+ ja,
102
+ speedBonus
88
103
  };
@@ -1,8 +1,6 @@
1
- "use strict";var PackingBingo=(()=>{var We=Object.defineProperty;var Vt=Object.getOwnPropertyDescriptor;var Xt=Object.getOwnPropertyNames;var Yt=Object.prototype.hasOwnProperty;var Jt=(n,a)=>{for(var s in a)We(n,s,{get:a[s],enumerable:!0})},Zt=(n,a,s,m)=>{if(a&&typeof a=="object"||typeof a=="function")for(let c of Xt(a))!Yt.call(n,c)&&c!==s&&We(n,c,{get:()=>a[c],enumerable:!(m=Vt(a,c))||m.enumerable});return n};var Qt=n=>Zt(We({},"__esModule",{value:!0}),n);var pn={};Jt(pn,{DEFAULT_ITEMS:()=>ce,LINES:()=>tn,bingoLines:()=>Ye,createPackingBingo:()=>sn,en:()=>wt,ja:()=>Je});var ce=[{emoji:"\u{1F45B}",label:"\u8CA1\u5E03"},{emoji:"\u{1F4F1}",label:"\u30B9\u30DE\u30DB"},{emoji:"\u{1F50B}",label:"\u30E2\u30D0\u30A4\u30EB\u200B\u5145\u96FB\u5668"},{emoji:"\u{1F4CB}",label:"\u5065\u5EB7\u8ABF\u67FB\u7968"},{emoji:"\u{1FAAA}",label:"\u30DE\u30A4\u30CA\u30AB\u30FC\u30C9\u200B\u307E\u305F\u306F\u4FDD\u967A\u8A3C"},{emoji:"\u{1F4D6}",label:"\u3057\u304A\u308A"},{emoji:"\u{1F637}",label:"\u30DE\u30B9\u30AF"},{emoji:"\u{1F927}",label:"\u30CF\u30F3\u30AB\u30C1"},{emoji:"\u{1F48A}",label:"\u5E38\u5099\u85AC"},{emoji:"\u{1F6CD}\uFE0F",label:"\u30D3\u30CB\u30FC\u30EB\u888B"},{emoji:"\u{1F9E4}",label:"\u8ECD\u624B\uFF08\u5B66\u6821\u652F\u7D66\uFF09"},{emoji:"\u{1F526}",label:"\u30D8\u30C3\u30C9\u30E9\u30A4\u30C8"},{emoji:"\u{1F455}",label:"\u30B8\u30E3\u30FC\u30B8"},{emoji:"\u2614",label:"\u96E8\u5177"},{emoji:"\u{1F6C1}",label:"\u30BF\u30AA\u30EB"},{emoji:"\u{1F9F4}",label:"\u65E5\u713C\u3051\u6B62\u3081"}];var ze=2,Ve=10,Te=n=>{throw new Error(`[packing-bingo] ${n}`)};function Xe(n){if(n.items)return n.items;let a=n.size;return a==null||!Number.isInteger(a)||a<ze?ce:ce.slice(0,a*a-(n.free?1:0))}function xt(n,a){(!Number.isInteger(n)||n<ze||n>Ve)&&Te(`"size" must be a whole number from ${ze} to ${Ve} (got ${n}).`),a&&n%2===0&&Te(`"free" needs an odd size such as 3 or 5, so that the card has a center (got ${n}).`)}function vt(n,a){let s=b=>Array.from({length:n},(l,k)=>b(k)),m=[...s(b=>s(l=>b*n+l)),...s(b=>s(l=>l*n+b)),s(b=>b*(n+1)),s(b=>(b+1)*(n-1))],c=a?(n*n-1)/2:-1,x=b=>a&&b>c?b-1:b;return{center:c,cellLines:m,lines:m.map(b=>b.filter(l=>l!==c).map(x))}}function yt(n){let a=Xe(n),s=!!n.free,m=n.size;if(m==null){let v=a.length,$=u=>{let M=Math.round(Math.sqrt(u));return M*M===u&&M>=ze&&M<=Ve?M:0};if(m=$(v+(s?1:0)),!m){let u=$(v+(s?0:1)),M=s?u?`; ${v} items fill a ${u}\xD7${u} card without "free"`:"":u%2?`, or set "free" for a ${u}\xD7${u} card with a FREE center`:"";Te(s?`With "free", "items" must have one less than an odd square number of entries (8, 24, 48, 80)${M} (got ${v}).`:`"items" must have a square number of entries (4, 9, 16, 25, \u2026, 100)${M} (got ${v}).`)}}xt(m,s);let c=m*m-(s?1:0);if(a.length!==c){let v=`a ${m}\xD7${m} card${s?" with a FREE center":""}`;Te(n.items?`"items" must have exactly ${c} entries for ${v} (got ${a.length}).`:`A ${v.slice(2)} needs ${c} items, but DEFAULT_ITEMS has only ${ce.length}. Pass "items".`)}let{center:x,cellLines:b,lines:l}=vt(m,s),k=a.map((v,$)=>s&&$>=x?$+1:$);return{size:m,free:s,items:a,itemCell:k,center:x,cellLines:b,lines:l}}function Ye(n,a=!1){return xt(n,a),vt(n,a).lines}var Je={title:"\u6301\u3061\u3082\u306E\u30D3\u30F3\u30B4",tag:"",subtitle:"",packed:"\u305D\u308D\u3063\u305F",bingo:"BINGO",score:"SCORE",combo:n=>`${n} COMBO`,comboPop:n=>`${n} COMBO!`,reset:"\u30EA\u30BB\u30C3\u30C8",shuffle:"\u{1F500} \u30B7\u30E3\u30C3\u30D5\u30EB",soundOn:"\u{1F50A} \u97F3\u3042\u308A",soundOff:"\u{1F507} \u97F3\u306A\u3057",stamp:"OK",free:"FREE",reachBadge:"\u30EA\u30FC\u30C1",reachPop:"\u30EA\u30FC\u30C1!",bannerSingle:"BINGO!",bannerDouble:"\u30C0\u30D6\u30EB\u30D3\u30F3\u30B4!",bannerTriple:"\u30C8\u30EA\u30D7\u30EB\u30D3\u30F3\u30B4!",bannerNth:n=>`${n} \u30E9\u30A4\u30F3\u76EE\uFF01`,bannerMulti:n=>`\u4E00\u6C17\u306B ${n} \u30E9\u30A4\u30F3\uFF01`,statusStart:()=>"",statusLines:(n,a)=>`\u30D3\u30F3\u30B4 ${n} \u30E9\u30A4\u30F3\uFF01 \u306E\u3053\u308A ${a} \u3053`,statusReach:()=>"",statusDone:"\u{1F389} \u30D1\u30FC\u30D5\u30A7\u30AF\u30C8\uFF01\u5FD8\u308C\u7269\u30BC\u30ED\u3067\u51FA\u767A\u3067\u304D\u307E\u3059",perfectTag:"\u{1F3C6} PERFECT",perfectStamp:`\u6E96\u5099
2
- \u5B8C\u4E86`,perfectTitle:"\u30D1\u30FC\u30D5\u30A7\u30AF\u30C8\uFF01",perfectBody:n=>`${n}\u3053 \u305C\u3093\u3076\u305D\u308D\u3063\u305F\uFF01
3
- \u5FD8\u308C\u7269\u30BC\u30ED\u3067\u3001\u3044\u3063\u3066\u3089\u3063\u3057\u3083\u3044\uFF01`,perfectBonus:n=>`PERFECT BONUS +${n}`,statScore:"SCORE",statCombo:"MAX COMBO",statLines:"BINGO",close:"\u3068\u3058\u308B",demoLabel:"\u30C7\u30E2\uFF1A",demoBingo:"\u25B6 \u30D3\u30F3\u30B4\u3092\u898B\u308B",demoPerfect:"\u25B6 \u30B3\u30F3\u30DC \u2192 \u30D1\u30FC\u30D5\u30A7\u30AF\u30C8",demoRestore:"\u6700\u521D\u306B\u623B\u3059"},wt={title:"Packing Bingo",tag:"",subtitle:"",packed:"PACKED",bingo:"BINGO",score:"SCORE",combo:n=>`${n} COMBO`,comboPop:n=>`${n} COMBO!`,reset:"Reset",shuffle:"\u{1F500} Shuffle",soundOn:"\u{1F50A} Sound on",soundOff:"\u{1F507} Muted",stamp:"OK",free:"FREE",reachBadge:"REACH",reachPop:"Reach!",bannerSingle:"BINGO!",bannerDouble:"DOUBLE BINGO!",bannerTriple:"TRIPLE BINGO!",bannerNth:n=>`Line ${n}!`,bannerMulti:n=>`${n} lines at once!`,statusStart:()=>"",statusLines:(n,a)=>`${n} bingo line${n===1?"":"s"}! ${a} to go`,statusReach:()=>"",statusDone:"\u{1F389} Perfect! Nothing left behind.",perfectTag:"\u{1F3C6} PERFECT",perfectStamp:`ALL
4
- SET`,perfectTitle:"Perfect!",perfectBody:n=>`All ${n} packed!
5
- Have a great trip!`,perfectBonus:n=>`PERFECT BONUS +${n}`,statScore:"SCORE",statCombo:"MAX COMBO",statLines:"BINGO",close:"Close",demoLabel:"Demo:",demoBingo:"\u25B6 Show a bingo",demoPerfect:"\u25B6 Combo \u2192 perfect",demoRestore:"Restore"};var Et=[0,2,4,7,9,12,14,16,19,21,24,26,28,31,33,36],D=n=>523.25*Math.pow(2,n/12);function Lt(n){let a=null,s=null;function m(){if(n()||typeof window>"u")return null;let l=navigator.userActivation;if(!a&&l&&!l.hasBeenActive)return null;if(!a){let k=window.AudioContext??window.webkitAudioContext;if(!k)return null;a=new k;let v=a.createDynamicsCompressor();s=a.createGain(),s.gain.value=.6,s.connect(v).connect(a.destination)}return a.state==="suspended"&&a.resume(),a}function c(l,k=0,v=.15,$="triangle",u=.2,M=0){let E=m();if(!E||!s)return;let T=E.currentTime+k,q=E.createOscillator(),P=E.createGain();q.type=$,q.frequency.setValueAtTime(l,T),M&&q.frequency.exponentialRampToValueAtTime(M,T+v),P.gain.setValueAtTime(1e-4,T),P.gain.exponentialRampToValueAtTime(u,T+.01),P.gain.exponentialRampToValueAtTime(1e-4,T+v),q.connect(P).connect(s),q.start(T),q.stop(T+v+.05)}function x(l=0,k=.3,v=.25,$=1200){let u=m();if(!u||!s)return;let M=u.currentTime+l,E=Math.ceil(u.sampleRate*k),T=u.createBuffer(1,E,u.sampleRate),q=T.getChannelData(0);for(let g=0;g<E;g++)q[g]=(Math.random()*2-1)*Math.pow(1-g/E,2.5);let P=u.createBufferSource(),ee=u.createBiquadFilter(),ve=u.createGain();P.buffer=T,ee.type="bandpass",ee.frequency.value=$,ee.Q.value=.7,ve.gain.value=v,P.connect(ee).connect(ve).connect(s),P.start(M)}let b=l=>D(Et[Math.min(Math.max(l,0),Et.length-1)]);return{pop(l){let k=b(l);c(k,0,.16,"triangle",.22),c(k*2,0,.08,"sine",.06),c(150,0,.09,"sine",.25,60)},off:()=>c(392,0,.1,"sine",.1,262),reach(){c(988,0,.08,"square",.05),c(1319,.09,.14,"square",.05)},bingo(l){[0,4,7,12,16,19].forEach((k,v)=>c(D(k),v*.06,.22,"square",.06)),[12,16,19].forEach(k=>c(D(k),.38,.6,"triangle",.12)),l>1&&[24,28,31].forEach(k=>c(D(k),.55,.6,"triangle",.08)),x(0,.25,.12,3e3)},perfect(){[0,4,7,12,16,19,24].forEach((l,k)=>c(D(l-12),k*.07,.25,"square",.06)),[0,4,7,12].forEach(l=>c(D(l),.55,1.2,"triangle",.12)),[12,16,19].forEach(l=>c(D(l),.55,1.2,"sawtooth",.03)),c(D(-12),.55,1.2,"sine",.2)},boom(){x(0,.5,.3,500),c(90,0,.3,"sine",.25,40)},tick:()=>c(1760,0,.03,"square",.03),note:(l,k=0)=>c(b(l),k,.12,"square",.05),shuffle(){for(let l=0;l<7;l++)x(l*.042,.05,.16,1600+l*260);c(D(7),.34,.12,"triangle",.14),c(D(12),.42,.2,"triangle",.14)},close(){a&&a.close().catch(()=>{}),a=null,s=null}}}function St(n){return n.controlled?null:n.storageKey!==void 0?n.storageKey||null:n.demo?null:en(Xe(n))}function en(n){let a=n.map(m=>`${m.emoji}\0${m.label}`).join(""),s=2166136261;for(let m=0;m<a.length;m++)s^=a.charCodeAt(m),s=Math.imul(s,16777619);return`packing-bingo:${(s>>>0).toString(36)}`}var Mt=`
1
+ "use strict";var PackingBingo=(()=>{var Pt=Object.defineProperty;var aa=Object.getOwnPropertyDescriptor;var ra=Object.getOwnPropertyNames;var ia=Object.prototype.hasOwnProperty;var oa=(r,n)=>{for(var f in n)Pt(r,f,{get:n[f],enumerable:!0})},sa=(r,n,f,u)=>{if(n&&typeof n=="object"||typeof n=="function")for(let y of ra(n))!ia.call(r,y)&&y!==f&&Pt(r,y,{get:()=>n[y],enumerable:!(u=aa(n,y))||u.enumerable});return r};var pa=r=>sa(Pt({},"__esModule",{value:!0}),r);var va={};oa(va,{DEFAULT_ITEMS:()=>qe,LINES:()=>ba,bingoLines:()=>It,createPackingBingo:()=>ya,en:()=>Cn,formatTime:()=>Ze,ja:()=>S,speedBonus:()=>Nn});var qe=[{emoji:"\u{1F45B}",label:"\u8CA1\u5E03"},{emoji:"\u{1F4F1}",label:"\u30B9\u30DE\u30DB"},{emoji:"\u{1F50B}",label:"\u30E2\u30D0\u30A4\u30EB\u200B\u5145\u96FB\u5668"},{emoji:"\u{1F4CB}",label:"\u5065\u5EB7\u8ABF\u67FB\u7968"},{emoji:"\u{1FAAA}",label:"\u30DE\u30A4\u30CA\u30AB\u30FC\u30C9\u200B\u307E\u305F\u306F\u4FDD\u967A\u8A3C"},{emoji:"\u{1F4D6}",label:"\u3057\u304A\u308A"},{emoji:"\u{1F637}",label:"\u30DE\u30B9\u30AF"},{emoji:"\u{1F927}",label:"\u30CF\u30F3\u30AB\u30C1"},{emoji:"\u{1F48A}",label:"\u5E38\u5099\u85AC"},{emoji:"\u{1F6CD}\uFE0F",label:"\u30D3\u30CB\u30FC\u30EB\u888B"},{emoji:"\u{1F9E4}",label:"\u8ECD\u624B\uFF08\u5B66\u6821\u652F\u7D66\uFF09"},{emoji:"\u{1F526}",label:"\u30D8\u30C3\u30C9\u30E9\u30A4\u30C8"},{emoji:"\u{1F455}",label:"\u30B8\u30E3\u30FC\u30B8"},{emoji:"\u2614",label:"\u96E8\u5177"},{emoji:"\u{1F6C1}",label:"\u30BF\u30AA\u30EB"},{emoji:"\u{1F9F4}",label:"\u65E5\u713C\u3051\u6B62\u3081"}];var pt=2,Ot=10,lt=r=>{throw new Error(`[packing-bingo] ${r}`)};function Rt(r){if(r.items)return r.items;let n=r.size;return n==null||!Number.isInteger(n)||n<pt?qe:qe.slice(0,n*n-(r.free?1:0))}function Tn(r,n){(!Number.isInteger(r)||r<pt||r>Ot)&&lt(`"size" must be a whole number from ${pt} to ${Ot} (got ${r}).`),n&&r%2===0&&lt(`"free" needs an odd size such as 3 or 5, so that the card has a center (got ${r}).`)}function Mn(r,n){let f=h=>Array.from({length:r},(p,T)=>h(T)),u=[...f(h=>f(p=>h*r+p)),...f(h=>f(p=>p*r+h)),f(h=>h*(r+1)),f(h=>(h+1)*(r-1))],y=n?(r*r-1)/2:-1,x=h=>n&&h>y?h-1:h;return{center:y,cellLines:u,lines:u.map(h=>h.filter(p=>p!==y).map(x))}}function Bn(r){let n=Rt(r),f=!!r.free,u=r.size;if(u==null){let M=n.length,b=c=>{let k=Math.round(Math.sqrt(c));return k*k===c&&k>=pt&&k<=Ot?k:0};if(u=b(M+(f?1:0)),!u){let c=b(M+(f?0:1)),k=f?c?`; ${M} items fill a ${c}\xD7${c} card without "free"`:"":c%2?`, or set "free" for a ${c}\xD7${c} card with a FREE center`:"";lt(f?`With "free", "items" must have one less than an odd square number of entries (8, 24, 48, 80)${k} (got ${M}).`:`"items" must have a square number of entries (4, 9, 16, 25, \u2026, 100)${k} (got ${M}).`)}}Tn(u,f);let y=u*u-(f?1:0);if(n.length!==y){let M=`a ${u}\xD7${u} card${f?" with a FREE center":""}`;lt(r.items?`"items" must have exactly ${y} entries for ${M} (got ${n.length}).`:`A ${M.slice(2)} needs ${y} items, but DEFAULT_ITEMS has only ${qe.length}. Pass "items".`)}let{center:x,cellLines:h,lines:p}=Mn(u,f),T=n.map((M,b)=>f&&b>=x?b+1:b);return{size:u,free:f,items:n,itemCell:T,center:x,cellLines:h,lines:p}}function It(r,n=!1){return Tn(r,n),Mn(r,n).lines}var S={title:"\u6301\u3061\u3082\u306E\u30D3\u30F3\u30B4",tag:"",subtitle:"",packed:"\u305D\u308D\u3063\u305F",bingo:"BINGO",score:"SCORE",combo:r=>`${r} COMBO`,comboPop:r=>`${r} COMBO!`,reset:"\u30EA\u30BB\u30C3\u30C8",shuffle:"\u{1F500} \u30B7\u30E3\u30C3\u30D5\u30EB",soundOn:"\u{1F50A} \u97F3\u3042\u308A",soundOff:"\u{1F507} \u97F3\u306A\u3057",readyTitle:"Are you ready?",readyPrompt:"",soundHint:"\u7AEF\u672B\u306E\u97F3\u91CF\u3092MAX\u306B",vibrationHint:"\u304A\u3084\u3059\u307F\u30E2\u30FC\u30C9\u3092\u30AA\u30D5",readyTap:"\u30BF\u30C3\u30D7\u3067\u30B9\u30BF\u30FC\u30C8",readyGo:"START!",time:"\u30BF\u30A4\u30E0",statTime:"\u30AF\u30EA\u30A2\u30BF\u30A4\u30E0",modeLabel:"\u30E2\u30FC\u30C9",modeNormal:"\u901A\u5E38",modeInfinite:"\u221E \u7121\u9650",normalTitle:"NORMAL",normalSub:"\u901A\u5E38\u30E2\u30FC\u30C9",infiniteTitle:"INFINITE",infiniteSub:"\u7121\u9650\u30D3\u30F3\u30B4",infiniteRule:"\u305D\u308D\u3063\u305F\u5217\u306F\u6D88\u3048\u3066\u3001\u307E\u305F\u57CB\u3081\u3089\u308C\u308B\u3002\u4F55\u5EA6\u3067\u3082\u30D3\u30F3\u30B4\uFF01",finish:"\u{1F3C1} FINISH",finishTitle:"\u30D5\u30A3\u30CB\u30C3\u30B7\u30E5\uFF01",finishStamp:"\u221E",finishTime:"\u30D7\u30EC\u30A4\u30BF\u30A4\u30E0",again:"\u3082\u3046\u4E00\u5EA6",stamp:"OK",free:"FREE",reachBadge:"\u30EA\u30FC\u30C1",reachPop:"\u30EA\u30FC\u30C1!",bannerSingle:"BINGO!",bannerDouble:"\u30C0\u30D6\u30EB\u30D3\u30F3\u30B4!",bannerTriple:"\u30C8\u30EA\u30D7\u30EB\u30D3\u30F3\u30B4!",bannerNth:r=>`${r} \u30E9\u30A4\u30F3\u76EE\uFF01`,bannerMulti:r=>`\u4E00\u6C17\u306B ${r} \u30E9\u30A4\u30F3\uFF01`,statusStart:()=>"",statusLines:()=>"",statusReach:()=>"",statusDone:"",perfectTag:"\u{1F3C6} PERFECT",perfectStamp:`\u6E96\u5099
2
+ \u5B8C\u4E86`,perfectTitle:"\u30D1\u30FC\u30D5\u30A7\u30AF\u30C8\uFF01",perfectBody:"",perfectBonus:r=>`PERFECT BONUS +${r}`,speedBonus:r=>`SPEED BONUS +${r.toLocaleString()}`,statScore:"SCORE",statCombo:"MAX COMBO",statLines:"BINGO",close:"\u3068\u3058\u308B",demoLabel:"\u30C7\u30E2\uFF1A",demoBingo:"\u25B6 \u30D3\u30F3\u30B4\u3092\u898B\u308B",demoPerfect:"\u25B6 \u30B3\u30F3\u30DC \u2192 \u30D1\u30FC\u30D5\u30A7\u30AF\u30C8",demoRestore:"\u6700\u521D\u306B\u623B\u3059"},Cn={title:"Packing Bingo",tag:"",subtitle:"",packed:"PACKED",bingo:"BINGO",score:"SCORE",combo:r=>`${r} COMBO`,comboPop:r=>`${r} COMBO!`,reset:"Reset",shuffle:"\u{1F500} Shuffle",soundOn:"\u{1F50A} Sound on",soundOff:"\u{1F507} Muted",readyTitle:"Are you ready?",readyPrompt:"",soundHint:"Turn your volume to MAX",vibrationHint:"Turn off Do Not Disturb",readyTap:"Tap to start",readyGo:"GO!",time:"Time",statTime:"Time",modeLabel:"Mode",modeNormal:"Normal",modeInfinite:"\u221E Infinite",normalTitle:"NORMAL",normalSub:"Normal mode",infiniteTitle:"INFINITE",infiniteSub:"Infinite bingo",infiniteRule:"Completed lines clear, so you can fill them again. Bingo forever!",finish:"\u{1F3C1} FINISH",finishTitle:"Finish!",finishStamp:"\u221E",finishTime:"Time played",again:"Play again",stamp:"OK",free:"FREE",reachBadge:"REACH",reachPop:"Reach!",bannerSingle:"BINGO!",bannerDouble:"DOUBLE BINGO!",bannerTriple:"TRIPLE BINGO!",bannerNth:r=>`Line ${r}!`,bannerMulti:r=>`${r} lines at once!`,statusStart:()=>"",statusLines:()=>"",statusReach:()=>"",statusDone:"",perfectTag:"\u{1F3C6} PERFECT",perfectStamp:`ALL
3
+ SET`,perfectTitle:"Perfect!",perfectBody:"",perfectBonus:r=>`PERFECT BONUS +${r}`,speedBonus:r=>`SPEED BONUS +${r.toLocaleString()}`,statScore:"SCORE",statCombo:"MAX COMBO",statLines:"BINGO",close:"Close",demoLabel:"Demo:",demoBingo:"\u25B6 Show a bingo",demoPerfect:"\u25B6 Combo \u2192 perfect",demoRestore:"Restore"};var qt=[0,2,4,7,9,12,14,16,19,21,24,26,28,31,33,36],O=r=>523.25*Math.pow(2,r/12);function zn(r){let n=null,f=null,u=new Map;function y(b,c,k,L){u.set(b,{gain:c,start:k}),b.onended=()=>{u.delete(b),b.disconnect(),L.forEach($=>$.disconnect())}}function x(){let b=n?.currentTime??0;u.forEach(({gain:c,start:k},L)=>{try{if(k>b)c.gain.cancelScheduledValues(b),c.gain.setValueAtTime(0,b),L.stop(b);else{if(typeof c.gain.cancelAndHoldAtTime=="function")c.gain.cancelAndHoldAtTime(b);else{let $=c.gain.value;c.gain.cancelScheduledValues(b),c.gain.setValueAtTime($,b)}c.gain.linearRampToValueAtTime(0,b+.01),L.stop(b+.01)}}catch{}}),u.clear()}function h(){if(r()||typeof window>"u"||document.hidden)return null;let b=navigator.userActivation;if(!n&&b&&!b.hasBeenActive)return null;if(!n){let c=window.AudioContext??window.webkitAudioContext;if(!c)return null;n=new c;let k=n.createDynamicsCompressor();f=n.createGain(),f.gain.value=.6,f.connect(k).connect(n.destination)}return n.state==="suspended"&&n.resume(),n}function p(b,c=0,k=.15,L="triangle",$=.2,se=0){let W=h();if(!W||!f)return;let V=W.currentTime+c,_=W.createOscillator(),m=W.createGain();_.type=L,_.frequency.setValueAtTime(b,V),se&&_.frequency.exponentialRampToValueAtTime(se,V+k),m.gain.setValueAtTime(1e-4,V),m.gain.exponentialRampToValueAtTime($,V+.01),m.gain.exponentialRampToValueAtTime(1e-4,V+k),_.connect(m).connect(f),y(_,m,V,[m]),_.start(V),_.stop(V+k+.05)}function T(b=0,c=.3,k=.25,L=1200){let $=h();if(!$||!f)return;let se=$.currentTime+b,W=Math.ceil($.sampleRate*c),V=$.createBuffer(1,W,$.sampleRate),_=V.getChannelData(0);for(let pe=0;pe<W;pe++)_[pe]=(Math.random()*2-1)*Math.pow(1-pe/W,2.5);let m=$.createBufferSource(),re=$.createBiquadFilter(),G=$.createGain();m.buffer=V,re.type="bandpass",re.frequency.value=L,re.Q.value=.7,G.gain.value=k,m.connect(re).connect(G).connect(f),y(m,G,se,[re,G]),m.start(se)}let M=b=>O(qt[Math.min(Math.max(b,0),qt.length-1)]);return{pop(b){let c=M(b),k=Math.min(3,Math.floor((b+1)/3));p(c,0,.16,"triangle",.22),p(c*2,0,.08,"sine",.06),p(170+k*15,0,.11,"sine",.28,48),T(0,.035,.1+k*.025,1800),k&&p(c*1.5,.035,.11,"triangle",.04+k*.015)},off:()=>p(392,0,.1,"sine",.1,262),reach(){p(988,0,.08,"square",.05),p(1319,.09,.14,"square",.05)},bingo(b){[0,4,7,12,16,19].forEach((c,k)=>p(O(c),k*.06,.22,"square",.06)),[12,16,19].forEach(c=>p(O(c),.38,.6,"triangle",.12)),b>1&&[24,28,31].forEach(c=>p(O(c),.55,.6,"triangle",.08)),T(0,.25,.12,3e3)},perfect(){[0,4,7,12,16,19,24].forEach((b,c)=>p(O(b-12),c*.07,.25,"square",.06)),[0,4,7,12].forEach(b=>p(O(b),.55,1.2,"triangle",.12)),[12,16,19].forEach(b=>p(O(b),.55,1.2,"sawtooth",.03)),p(O(-12),.55,1.2,"sine",.2)},boom(){T(0,.5,.3,500),p(90,0,.3,"sine",.25,40)},tick:()=>p(1760,0,.03,"square",.03),note:(b,c=0)=>p(M(b),c,.12,"square",.05),shuffle(){for(let b=0;b<7;b++)T(b*.042,.05,.16,1600+b*260);p(O(7),.34,.12,"triangle",.14),p(O(12),.42,.2,"triangle",.14)},count(b){b?(p(O(12),0,.5,"square",.07),p(O(24),0,.5,"triangle",.14),T(0,.2,.12,3e3)):(p(O(5),0,.14,"square",.07),p(O(17),0,.14,"triangle",.12))},mode(b){b?(p(196,0,.42,"sine",.12,784),[0,2,4,7,9,12,14,16,19,21,24].forEach((c,k)=>p(O(c-12),k*.032,.16,"triangle",.07)),[12,16,19,24].forEach(c=>p(O(c),.38,1.1,"sine",.07)),p(O(31),.38,.9,"triangle",.03),T(0,.5,.07,6500),T(.36,.7,.05,9e3)):(p(O(7),0,.1,"square",.05),p(O(0),.1,.28,"triangle",.14),p(160,.1,.2,"sine",.26,55),T(.1,.12,.14,1400))},clear(b){let c=Math.max(1,Math.min(8,b));for(let k=0;k<c;k++)p(M(qt.length-1-k*2),k*.035,.18,"sine",.07);T(0,.3,.08,7e3)},stop:x,close(){x(),n&&n.close().catch(()=>{}),n=null,f=null}}}var ct=null;function An(r){let n={},f=0,u=()=>{if(f++,ct===n){ct=null;try{navigator.vibrate?.(0)}catch{}}},y=x=>{if(!r||document.hidden||typeof navigator.vibrate!="function"||navigator.userActivation&&!navigator.userActivation.hasBeenActive)return!1;try{if(navigator.vibrate(x))return ct=n,!0}catch{}return!1};return{play(x,h=1,p=1,T=360){let M=++f,b=Math.min(3,Math.floor(h/3)),c=Math.max(80,T-40),k=x==="off"?35:x==="perfect"?[160,45,100]:x==="bingo"?p>=3?[c,40,500,50,650,50,850]:p===2?[c,40,500,50,650]:[c,40,500]:x==="reach"?[140,40,240]:x==="shuffle"?[90,35,90,35,220]:x==="count"?60:x==="go"?260:x==="infinite"?[25,30,35,30,45,30,220]:x==="normal"?[50,70,160]:x==="finish"?[120,40,120,40,320]:b?[100+b*20,15,80+b*20]:90;if(y(k))return L=>{f===M&&ct===n&&y([...L])}},stop:u}}var Nt=[260,45,160],Dt=[{at:1820,beat:[200]},{at:2170,beat:[100,35,160]},{at:2520,beat:[260]},{at:3e3,beat:[110,40,110]},{at:3430,beat:[320]},{at:3950,beat:[140,40,200]},{at:4540,beat:[460]}];function $n(r){return r.controlled?null:r.storageKey!==void 0?r.storageKey||null:r.demo?null:la(Rt(r))}function la(r){let n=r.map(u=>`${u.emoji}\0${u.label}`).join(""),f=2166136261;for(let u=0;u<n.length;u++)f^=n.charCodeAt(u),f=Math.imul(f,16777619);return`packing-bingo:${(f>>>0).toString(36)}`}var Pn=`
6
4
  .pkb{--pk-sun:var(--pkb-sun,#FFD54F);--pk-ink:var(--pkb-ink,#2A1F14);--pk-paper:var(--pkb-paper,#FFFDF6);--pk-red:var(--pkb-red,#E8473B);--pk-mint:var(--pkb-mint,#BDEBD2);--pk-display:"Dela Gothic One",var(--pkb-font-fallback,sans-serif);--pk-body:"M PLUS Rounded 1c","Hiragino Maru Gothic ProN",var(--pkb-font-fallback,sans-serif);--pk-n:4;--pk-s:1;--pk-d:1;container-type:inline-size;isolation:isolate;width:100%}
7
5
  .pkb,.pkb *{box-sizing:border-box;margin:0;padding:0}
8
6
  .pkb-board{position:relative;overflow:hidden;max-width:720px;margin:0 auto;padding:22px 26px 20px;border-radius:24px;background-color:var(--pk-sun);background-image:radial-gradient(rgba(42,31,20,.12) 1.3px,transparent 1.6px);background-size:16px 16px;border:2.5px solid var(--pk-ink);color:var(--pk-ink);font-family:var(--pk-body);line-height:1.4;text-align:left}
@@ -11,13 +9,17 @@ Have a great trip!`,perfectBonus:n=>`PERFECT BONUS +${n}`,statScore:"SCORE",stat
11
9
  .pkb-board.pkb-punch{animation:pkb-punch .4s cubic-bezier(.3,1.6,.5,1)}
12
10
  @keyframes pkb-punch{30%{transform:scale(1.018)}}
13
11
  .pkb-head{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px 16px;margin-bottom:18px}
14
- .pkb-tags{display:flex;gap:8px;align-items:center}
12
+ .pkb-tags{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
15
13
  .pkb-kicker{display:inline-block;background:var(--pk-ink);color:var(--pk-sun);font-weight:800;font-size:11px;letter-spacing:.14em;padding:4px 10px;border-radius:999px}
16
14
  .pkb-kicker:empty{display:none}
17
15
  .pkb-kicker.pkb-gold{color:#fff;background:linear-gradient(90deg,#E8473B,#FF9F1C,#1FA971,#2F6FED,#E8473B);background-size:200% 100%;animation:pkb-rb 2s linear infinite}
18
16
  @keyframes pkb-rb{to{background-position:-200% 0}}
19
17
  .pkb button{font-family:var(--pk-body)}
20
18
  .pkb-snd{appearance:none;border:2px solid var(--pk-ink);background:var(--pk-paper);border-radius:999px;padding:2px 9px;font-weight:800;font-size:11px;line-height:1.4;color:var(--pk-ink);cursor:pointer}
19
+ .pkb-watch{display:inline-block;min-width:5.4em;padding:3px 10px 2px;border-radius:999px;background:var(--pk-ink);color:var(--pk-paper);font-family:var(--pk-display);font-size:13px;line-height:1.3;text-align:center;font-variant-numeric:tabular-nums;letter-spacing:.03em}
20
+ .pkb-watch::before{content:"\u23F1 ";font-family:var(--pk-body)}
21
+ .pkb-watch.pkb-run{color:var(--pk-sun)}
22
+ .pkb-watch.pkb-done{background:var(--pk-red);color:#fff}
21
23
  .pkb-title{font-family:var(--pk-display);font-weight:400;font-size:34px;line-height:1.15;margin-top:8px;letter-spacing:.02em;color:inherit}
22
24
  .pkb-sub{font-weight:800;font-size:13px;margin-top:4px;word-break:auto-phrase}
23
25
  .pkb-side{display:flex;flex-direction:column;gap:8px;flex:none}
@@ -35,12 +37,12 @@ Have a great trip!`,perfectBonus:n=>`PERFECT BONUS +${n}`,statScore:"SCORE",stat
35
37
  .pkb-combo b{font-family:var(--pk-display);font-weight:400;font-size:13px;color:var(--pk-red);white-space:nowrap}
36
38
  .pkb-bar{flex:1;height:9px;border:2px solid var(--pk-ink);border-radius:999px;background:var(--pk-paper);overflow:hidden}
37
39
  .pkb-bar i{display:block;height:100%;background:var(--pk-red);transform-origin:left}
38
- .pkb-combo.pkb-on .pkb-bar i{animation:pkb-drain 2.5s linear forwards}
40
+ .pkb-combo.pkb-on .pkb-bar i.pkb-draining{animation:pkb-drain 2.5s linear forwards}
39
41
  @keyframes pkb-drain{from{transform:scaleX(1)}to{transform:scaleX(0)}}
40
42
  .pkb-gw{position:relative}
41
43
  .pkb-grid{display:grid;grid-template-columns:repeat(var(--pk-n),minmax(0,1fr));gap:calc(12px*var(--pk-d))}
42
44
  .pkb-tile{position:relative;min-width:0;place-self:stretch;aspect-ratio:1/.82;background:var(--pk-paper);border:2.5px solid var(--pk-ink);border-radius:calc(16px*var(--pk-d));box-shadow:4px 4px 0 var(--pk-ink);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:calc(6px*var(--pk-d));cursor:pointer;user-select:none;-webkit-tap-highlight-color:transparent;transition:transform .1s,box-shadow .1s,background-color .25s}
43
- .pkb-tile:active:not(.pkb-free){transform:translate(3px,3px);box-shadow:1px 1px 0 var(--pk-ink)}
45
+ .pkb-tile:active:not(.pkb-free):not(.pkb-lock){transform:translate(3px,3px);box-shadow:1px 1px 0 var(--pk-ink)}
44
46
  .pkb-tile input{position:absolute;opacity:0;pointer-events:none;width:1px;height:1px}
45
47
  .pkb-tile:has(input:focus-visible){outline:3px solid var(--pk-ink);outline-offset:3px}
46
48
  .pkb-emo{font-size:max(14px,calc(32px*var(--pk-s)));line-height:1;transition:opacity .2s}
@@ -48,6 +50,7 @@ Have a great trip!`,perfectBonus:n=>`PERFECT BONUS +${n}`,statScore:"SCORE",stat
48
50
  .pkb-stamp{position:absolute;left:50%;top:50%;width:64%;aspect-ratio:1;border-radius:50%;border:3px solid var(--pk-red);box-shadow:inset 0 0 0 2px var(--pk-paper),inset 0 0 0 4px var(--pk-red);color:var(--pk-red);display:grid;place-items:center;font-family:var(--pk-display);font-size:max(9px,calc(20px*var(--pk-s)));letter-spacing:.04em;opacity:0;transform:translate(-50%,-50%) rotate(-16deg) scale(1.7);transition:transform .25s cubic-bezier(.3,1.5,.5,1),opacity .15s;pointer-events:none}
49
51
  .pkb-tile.pkb-on .pkb-stamp{opacity:.9;transform:translate(-50%,-50%) rotate(-16deg) scale(1)}
50
52
  .pkb-tile.pkb-on .pkb-emo,.pkb-tile.pkb-on .pkb-lbl{opacity:.35}
53
+ .pkb-tile.pkb-lock{cursor:default}
51
54
  .pkb-tile.pkb-free{cursor:default;container-type:inline-size}
52
55
  .pkb-tile.pkb-free .pkb-stamp{width:72%;opacity:1;transition:none;font-size:17cqi;letter-spacing:.02em;line-height:1;text-align:center;background:var(--pk-red);color:var(--pk-paper);border-color:var(--pk-red);box-shadow:inset 0 0 0 2px var(--pk-red),inset 0 0 0 4px var(--pk-paper)}
53
56
  .pkb-tile.pkb-line{background-color:var(--pk-mint)}
@@ -57,12 +60,14 @@ Have a great trip!`,perfectBonus:n=>`PERFECT BONUS +${n}`,statScore:"SCORE",stat
57
60
  @keyframes pkb-aura{50%{box-shadow:4px 4px 0 var(--pk-ink),0 0 0 7px rgba(232,71,59,.35)}}
58
61
  .pkb-tile.pkb-reach::after{content:attr(data-reach);position:absolute;top:-11px;right:-8px;z-index:3;background:var(--pk-red);color:#fff;font-size:10.5px;font-weight:800;letter-spacing:.06em;padding:3px 8px;border-radius:999px;border:2px solid var(--pk-ink);transform:rotate(6deg);animation:pkb-bob 1.1s ease-in-out infinite}
59
62
  @keyframes pkb-bob{50%{transform:rotate(6deg) translateY(-4px)}}
60
- .pkb-tile.pkb-squash{animation:pkb-squash .34s cubic-bezier(.3,1.6,.5,1)}
61
- @keyframes pkb-squash{0%{transform:scale(.88)}55%{transform:scale(1.05)}}
63
+ .pkb-tile.pkb-squash{z-index:1;animation:pkb-squash .38s cubic-bezier(.16,1,.3,1)}
64
+ @keyframes pkb-squash{0%{transform:translate(3px,4px) scale(calc(.9 - var(--pkb-impact,0)*.018));box-shadow:0 0 0 var(--pk-ink)}38%{transform:translateY(calc(-2px - var(--pkb-impact,0)*1px)) scale(calc(1.045 + var(--pkb-impact,0)*.012))}70%{transform:translateY(1px) scale(.985)}100%{transform:none}}
65
+ .pkb-tile.pkb-on .pkb-stamp.pkb-hit{animation:pkb-stamp-hit .32s cubic-bezier(.16,1,.3,1) both}
66
+ @keyframes pkb-stamp-hit{0%{opacity:0;transform:translate(-50%,-50%) rotate(-26deg) scale(2.1)}28%{opacity:1;transform:translate(-50%,-50%) rotate(-12deg) scale(.88)}52%{transform:translate(-50%,-50%) rotate(-18deg) scale(1.08)}100%{opacity:.9;transform:translate(-50%,-50%) rotate(-16deg) scale(1)}}
62
67
  .pkb-tile.pkb-hop{animation:pkb-hop .55s cubic-bezier(.3,1.6,.5,1) var(--pkb-d,0ms) both}
63
68
  @keyframes pkb-hop{35%{transform:translateY(-14px) scale(1.07)}}
64
69
  .pkb-ring{position:absolute;left:50%;top:50%;width:70%;aspect-ratio:1;border:4px solid var(--pk-red);border-radius:50%;pointer-events:none;z-index:4;animation:pkb-ring .5s ease-out forwards}
65
- @keyframes pkb-ring{from{transform:translate(-50%,-50%) scale(.3);opacity:.9}to{transform:translate(-50%,-50%) scale(1.9);opacity:0}}
70
+ @keyframes pkb-ring{from{transform:translate(-50%,-50%) scale(.3);opacity:.9}to{transform:translate(-50%,-50%) scale(calc(1.9 + var(--pkb-impact,0)*.18));opacity:0}}
66
71
  .pkb-lines{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible;z-index:2;transition:opacity .4s}
67
72
  .pkb-board.pkb-all .pkb-lines{opacity:0}
68
73
  .pkb-lines line{fill:none;stroke-linecap:round;stroke-dasharray:1;stroke-dashoffset:0}
@@ -73,10 +78,11 @@ Have a great trip!`,perfectBonus:n=>`PERFECT BONUS +${n}`,statScore:"SCORE",stat
73
78
  .pkb-foot{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px 10px;margin-top:18px;font-weight:800;font-size:13px;word-break:auto-phrase}
74
79
  .pkb-foot>span{flex:1 1 14em}
75
80
  .pkb-foot>span:empty{flex-basis:0}
76
- .pkb-acts{display:flex;gap:8px;flex:none;margin-left:auto}
81
+ .pkb-acts{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px;flex:0 1 auto;max-width:100%;margin-left:auto}
77
82
  .pkb-reset,.pkb-shuf{appearance:none;flex:none;border:2px solid var(--pk-ink);background:transparent;border-radius:999px;padding:5px 12px;font-weight:800;font-size:12px;line-height:1.4;color:var(--pk-ink);cursor:pointer}
78
83
  .pkb-shuf{background:var(--pk-paper);box-shadow:2px 2px 0 var(--pk-ink)}
79
- .pkb-shuf:active{transform:translate(2px,2px);box-shadow:none}
84
+ .pkb-shuf:active:not(:disabled){transform:translate(2px,2px);box-shadow:none}
85
+ .pkb-shuf:disabled{cursor:default;opacity:.4}
80
86
  .pkb-flash{position:absolute;inset:0;z-index:7;background:#fff;opacity:0;pointer-events:none}
81
87
  .pkb-flash.pkb-go{animation:pkb-flash .4s ease-out}
82
88
  @keyframes pkb-flash{0%{opacity:.8}100%{opacity:0}}
@@ -93,15 +99,43 @@ Have a great trip!`,perfectBonus:n=>`PERFECT BONUS +${n}`,statScore:"SCORE",stat
93
99
  .pkb-float.pkb-big{font-size:clamp(14px,5.6cqi,34px);color:#FFE066}
94
100
  .pkb-float.pkb-rch{font-size:20px;color:var(--pk-red);-webkit-text-stroke:4px var(--pk-paper)}
95
101
  @keyframes pkb-rise{0%{opacity:0;transform:translate(-50%,-20%) scale(.4)}18%{opacity:1;transform:translate(-50%,-60%) scale(1.2)}30%{transform:translate(-50%,-70%) scale(1)}75%{opacity:1}100%{opacity:0;transform:translate(-50%,-190%) scale(1)}}
102
+ .pkb-ready{appearance:none;position:absolute;inset:0;z-index:12;display:grid;place-items:center;padding:20px;border:0;border-radius:inherit;background:rgba(42,31,20,.5);color:var(--pk-ink);font:inherit;text-align:center;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color .35s}
103
+ .pkb-ready[hidden]{display:none}
104
+ .pkb-ready:focus-visible{outline:3px solid var(--pk-ink);outline-offset:-6px}
105
+ .pkb-ready.pkb-gone{pointer-events:none;background-color:transparent}
106
+ .pkb-board.pkb-waiting .pkb-snd{position:relative;z-index:13}
107
+ .pkb-ready-in,.pkb-count{grid-area:1/1}
108
+ .pkb-ready-in{display:flex;flex-direction:column;align-items:center;width:min(400px,100%);padding:24px 22px 22px;border:2.5px solid var(--pk-ink);border-radius:22px;background:var(--pk-paper)}
109
+ .pkb-ready.pkb-counting .pkb-ready-in{visibility:hidden}
110
+ .pkb-ready-t{font-family:var(--pk-display);font-weight:400;font-size:clamp(26px,7.5cqi,36px);line-height:1.15;color:var(--pk-red)}
111
+ .pkb-ready-q{margin-top:6px;font-weight:800;font-size:18px;line-height:1.4}
112
+ .pkb-ready-l{display:flex;flex-direction:column;gap:4px;width:100%;margin-top:14px;padding:12px 14px;border-radius:14px;background:rgba(42,31,20,.07);font-weight:800;font-size:16px;line-height:1.6;text-align:left;overflow-wrap:anywhere;word-break:auto-phrase}
113
+ .pkb-ready-l>span::before{content:"\u30FB"}
114
+ .pkb-ready-go{margin-top:18px;padding:10px 30px;border:2.5px solid var(--pk-ink);border-radius:999px;background:var(--pk-sun);font-weight:800;font-size:16px;line-height:1.4;box-shadow:3px 3px 0 var(--pk-ink);animation:pkb-beat 1.2s ease-in-out infinite}
115
+ @keyframes pkb-beat{50%{transform:scale(1.06)}}
116
+ .pkb-count{font-family:var(--pk-display);font-weight:400;line-height:1.1;paint-order:stroke fill;font-size:clamp(90px,34cqi,200px);color:var(--pk-sun);-webkit-text-stroke:5px var(--pk-ink);text-shadow:7px 7px 0 var(--pk-ink);opacity:0;pointer-events:none}
117
+ .pkb-count.pkb-go{font-size:clamp(48px,17cqi,120px);color:var(--pk-red);white-space:nowrap}
118
+ .pkb-count.pkb-tick{animation:pkb-cnt 1s cubic-bezier(.2,1.4,.4,1) forwards}
119
+ .pkb-count.pkb-go.pkb-tick{animation:pkb-cnt-go .75s cubic-bezier(.2,1.4,.4,1) forwards}
120
+ @keyframes pkb-cnt{0%{opacity:0;transform:scale(2.2)}18%{opacity:1;transform:scale(.92)}30%{transform:scale(1)}75%{opacity:1}100%{opacity:0;transform:scale(.8)}}
121
+ @keyframes pkb-cnt-go{0%{opacity:0;transform:scale(.4) rotate(-8deg)}25%{opacity:1;transform:scale(1.12) rotate(-5deg)}40%{transform:scale(1) rotate(-5deg)}70%{opacity:1}100%{opacity:0;transform:scale(1.5) rotate(-5deg)}}
122
+ .pkb-ptime{display:inline-flex;align-items:baseline;gap:8px;margin:-4px 0 14px;padding:5px 16px 4px;border-radius:999px;background:var(--pk-ink);color:var(--pk-sun)}
123
+ .pkb-ptime[hidden]{display:none}
124
+ .pkb-ptime small{font-size:11px;font-weight:800;letter-spacing:.08em;color:#fff}
125
+ .pkb-ptime b{font-family:var(--pk-display);font-weight:400;font-size:22px;line-height:1.2;font-variant-numeric:tabular-nums}
96
126
  .pkb-perfect{position:absolute;inset:0;z-index:8;display:grid;place-items:center;padding:20px;background:rgba(42,31,20,.5);opacity:0;visibility:hidden;transition:opacity .3s,visibility .3s}
97
- .pkb-perfect.pkb-show{opacity:1;visibility:visible}
127
+ /* Visible at once when opening (focus can't land on a hidden dialog); hidden only after the fade when closing. */
128
+ .pkb-perfect.pkb-show{opacity:1;visibility:visible;transition:opacity .3s,visibility 0s}
98
129
  .pkb-card{width:min(400px,100%);background:var(--pk-paper);border:2.5px solid var(--pk-ink);border-radius:22px;box-shadow:6px 6px 0 var(--pk-ink);padding:26px 22px 20px;text-align:center;transform:scale(.6) translateY(30px);transition:transform .45s cubic-bezier(.3,1.5,.5,1)}
99
130
  .pkb-perfect.pkb-show .pkb-card{transform:none}
100
131
  .pkb-medal{width:124px;height:124px;margin:0 auto 12px;border-radius:50%;border:5px solid var(--pk-red);box-shadow:inset 0 0 0 4px var(--pk-paper),inset 0 0 0 7px var(--pk-red);color:var(--pk-red);display:grid;place-content:center;font-family:var(--pk-display);font-size:26px;line-height:1.15;white-space:pre-line;opacity:0;transform:rotate(-14deg) scale(2.6)}
101
132
  .pkb-perfect.pkb-show .pkb-medal{animation:pkb-slam .38s cubic-bezier(.5,0,.75,0) .35s forwards}
133
+ .pkb-perfect.pkb-settled,.pkb-perfect.pkb-settled .pkb-card{transition:none}
134
+ .pkb-perfect.pkb-settled .pkb-medal{animation:none;opacity:1;transform:rotate(-14deg) scale(1)}
102
135
  @keyframes pkb-slam{to{opacity:1;transform:rotate(-14deg) scale(1)}}
103
136
  .pkb-ptitle{font-family:var(--pk-display);font-weight:400;font-size:30px;line-height:1.3;color:inherit}
104
137
  .pkb-pbody{font-weight:800;font-size:13.5px;line-height:1.6;margin:6px 0 14px;white-space:pre-line;word-break:auto-phrase}
138
+ .pkb-pbody:empty{margin:0 0 14px}
105
139
  .pkb-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-bottom:16px}
106
140
  .pkb-stats>div{border:2px solid var(--pk-ink);border-radius:12px;padding:6px 4px 5px;background:#fff}
107
141
  .pkb-stats small{display:block;font-size:9.5px;font-weight:800;letter-spacing:.1em}
@@ -111,26 +145,89 @@ Have a great trip!`,perfectBonus:n=>`PERFECT BONUS +${n}`,statScore:"SCORE",stat
111
145
  .pkb-fx{position:absolute;inset:0;width:100%;height:100%;z-index:10;pointer-events:none}
112
146
  .pkb-demo{max-width:720px;margin:12px auto 4px;display:flex;flex-wrap:wrap;align-items:center;gap:8px;font-family:var(--pk-body);font-size:12px;color:#666}
113
147
  .pkb-demo button{appearance:none;border:1px solid #ccc;background:#f3f3f3;color:#222;border-radius:999px;padding:5px 12px;font-size:12px;cursor:pointer}
114
- @container (max-width:560px){.pkb-board{padding:18px 14px 16px}.pkb-head{flex-direction:column;align-items:stretch;gap:12px}.pkb-score{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}.pkb-pill,.pkb-pill.pkb-sc{min-width:0;padding:5px 4px 4px}.pkb-pill b{font-size:19px}.pkb-title{font-size:26px}.pkb-grid{gap:max(3px,calc(8px*var(--pk-d)))}.pkb-tile{border-radius:calc(12px*var(--pk-d));box-shadow:3px 3px 0 var(--pk-ink);gap:calc(3px*var(--pk-d));aspect-ratio:1/1}.pkb-emo{font-size:max(13px,calc(24px*var(--pk-s)))}.pkb-lbl{font-size:max(8.5px,calc(10.5px*var(--pk-s)));padding:0 calc(2px*var(--pk-d))}.pkb-stamp{font-size:max(9px,calc(14px*var(--pk-s)))}.pkb-tile.pkb-reach::after{font-size:9px;padding:2px 5px;top:-9px;right:-5px}.pkb-lines .pkb-u{stroke-width:calc(10px*var(--pk-d))}.pkb-lines .pkb-o{stroke-width:calc(5px*var(--pk-d))}.pkb-banner::before{width:380px;height:380px;margin:-190px 0 0 -190px}.pkb-banner span{font-size:12px}.pkb-medal{width:96px;height:96px;font-size:20px}.pkb-card{padding:20px 14px 16px}.pkb-ptitle{font-size:24px}.pkb-stats b{font-size:17px}.pkb-float.pkb-pt{font-size:17px}.pkb-float.pkb-cmb{font-size:13px}}
115
- @container (max-width:400px){.pkb-board{padding:16px 10px 14px}.pkb-grid{gap:max(3px,calc(6px*var(--pk-d)))}.pkb-lbl{font-size:max(8.5px,calc(10px*var(--pk-s)));padding:0 calc(1px*var(--pk-d))}.pkb-emo{font-size:max(12px,calc(22px*var(--pk-s)))}.pkb-stamp{font-size:max(9px,calc(13px*var(--pk-s)))}.pkb-foot{margin-top:14px;font-size:12px}.pkb-perfect{padding:12px}.pkb-stats{gap:6px}.pkb-stats>div{padding:6px 2px 5px}.pkb-stats small{letter-spacing:.02em}}
148
+ .pkb-mode{position:relative;isolation:isolate;display:inline-grid;grid-auto-flow:column;grid-auto-columns:1fr;padding:2px;border-radius:999px;background:var(--pk-ink);transition:box-shadow .4s}
149
+ .pkb-mode::after{content:"";position:absolute;inset:0;z-index:2;border-radius:inherit;pointer-events:none;background:linear-gradient(110deg,transparent 30%,rgba(255,255,255,.75) 45%,transparent 60%) no-repeat;background-size:250% 100%;background-position:200% 0;opacity:0}
150
+ .pkb-mode button{appearance:none;position:relative;z-index:1;border:0;background:none;border-radius:999px;padding:3px 11px 2px;font-weight:800;font-size:11px;line-height:1.4;letter-spacing:.04em;white-space:nowrap;color:var(--pk-paper);opacity:.72;cursor:pointer;transition:color .3s,opacity .3s;-webkit-tap-highlight-color:transparent}
151
+ .pkb-mode button[aria-checked="true"]{opacity:1;color:var(--pk-ink);cursor:default}
152
+ .pkb-mode button:focus-visible{outline:2px solid var(--pk-paper);outline-offset:-4px}
153
+ .pkb-mode-th{position:absolute;top:2px;bottom:2px;left:2px;width:calc(50% - 2px);border-radius:999px;background:var(--pk-sun);transition:transform .55s cubic-bezier(.3,1.45,.45,1)}
154
+ .pkb.pkb-inf .pkb-mode{box-shadow:0 0 14px 1px rgba(155,93,229,.6)}
155
+ .pkb.pkb-inf .pkb-mode::after{opacity:1;animation:pkb-glint 3.2s ease-in-out infinite}
156
+ .pkb.pkb-inf .pkb-mode-th{transform:translateX(100%);background:linear-gradient(90deg,#FF9F1C,#E8473B,#9B5DE5,#2F6FED,#1FA971,#FF9F1C) 0 0/200% 100%;animation:pkb-rb 2.4s linear infinite}
157
+ .pkb.pkb-inf .pkb-mode button[data-m="infinite"]{color:#fff;text-shadow:0 1px 1px rgba(42,31,20,.55)}
158
+ .pkb-board.pkb-waiting .pkb-mode,.pkb-board.pkb-switching .pkb-mode{z-index:15}
159
+ .pkb-board.pkb-switching .pkb-fx{z-index:16}
160
+ .pkb.pkb-inf .pkb-board{border-color:transparent;background:radial-gradient(rgba(42,31,20,.12) 1.3px,transparent 1.6px) 0 0/16px 16px padding-box,linear-gradient(var(--pk-sun),var(--pk-sun)) padding-box,linear-gradient(120deg,#FF9F1C,#E8473B 22%,#9B5DE5 45%,#2F6FED 68%,#1FA971 88%,#FF9F1C) border-box;box-shadow:0 0 0 2px var(--pk-ink),0 10px 34px -10px rgba(155,93,229,.7)}
161
+ .pkb.pkb-inf .pkb-demo [data-r="dP"],.pkb.pkb-inf .pkb-demo [data-r="dR"]{display:none}
162
+ .pkb-ready-b,.pkb-ready-r{display:none}
163
+ .pkb.pkb-inf .pkb-ready-in{border-color:transparent;background:linear-gradient(var(--pk-paper),var(--pk-paper)) padding-box,linear-gradient(120deg,#FF9F1C,#E8473B 22%,#9B5DE5 45%,#2F6FED 68%,#1FA971 88%,#FF9F1C) border-box;box-shadow:0 0 0 2px var(--pk-ink),0 0 32px rgba(155,93,229,.5)}
164
+ .pkb.pkb-inf .pkb-ready-b{display:inline-block;margin-bottom:10px;padding:4px 14px 3px;border-radius:999px;background:linear-gradient(90deg,#FF9F1C,#E8473B,#9B5DE5,#2F6FED,#1FA971,#FF9F1C) 0 0/200% 100%;color:#fff;font-weight:800;font-size:13px;line-height:1.4;letter-spacing:.08em;text-shadow:0 1px 1px rgba(42,31,20,.5);box-shadow:0 0 14px rgba(155,93,229,.55);animation:pkb-rb 2.4s linear infinite}
165
+ .pkb.pkb-inf .pkb-ready-r{display:block;margin-top:8px;font-weight:800;font-size:15px;line-height:1.5;word-break:auto-phrase}
166
+ .pkb-tile.pkb-clr{animation:pkb-clr .62s var(--pkb-cd,0ms) both}
167
+ @keyframes pkb-clr{0%{transform:perspective(600px) rotateY(0);animation-timing-function:cubic-bezier(.55,0,.9,.45)}42%{transform:perspective(600px) rotateY(90deg) scale(.9)}42.01%{transform:perspective(600px) rotateY(-90deg) scale(.9);animation-timing-function:cubic-bezier(.2,1.45,.4,1)}100%{transform:perspective(600px) rotateY(0)}}
168
+ .pkb-mfx{position:absolute;inset:0;z-index:14;display:grid;place-items:center;overflow:hidden;border-radius:inherit;pointer-events:none;visibility:hidden;opacity:0;text-align:center}
169
+ .pkb-mfx.pkb-show{visibility:visible;animation:pkb-mfx 1.7s ease-out forwards}
170
+ @keyframes pkb-mfx{0%{opacity:0}9%{opacity:1}72%{opacity:1}100%{opacity:0}}
171
+ .pkb-mfx-inf{background:radial-gradient(120% 95% at 50% 42%,#33205c 0%,#170f2e 52%,#08060f 100%)}
172
+ .pkb-mfx-n{background:var(--pk-sun) radial-gradient(rgba(42,31,20,.16) 1.3px,transparent 1.6px) 0 0/16px 16px}
173
+ .pkb-mfx::after{content:"";position:absolute;top:-30%;bottom:-30%;left:-50%;width:50%;background:linear-gradient(90deg,transparent,rgba(255,255,255,.55),transparent);transform:skewX(-18deg);opacity:0}
174
+ .pkb-mfx.pkb-show::after{animation:pkb-beam 1s cubic-bezier(.4,0,.2,1) .22s both}
175
+ @keyframes pkb-beam{0%{opacity:1;transform:skewX(-18deg) translateX(0)}100%{opacity:1;transform:skewX(-18deg) translateX(400%)}}
176
+ .pkb-mfx-glow{position:absolute;left:50%;top:46%;width:min(150cqi,1000px);aspect-ratio:1;translate:-50% -50%;border-radius:50%;background:conic-gradient(#FF9F1C,#E8473B,#9B5DE5,#2F6FED,#1FA971,#FF9F1C);-webkit-mask:radial-gradient(circle,transparent 14%,#000 30%,rgba(0,0,0,.4) 48%,transparent 68%);mask:radial-gradient(circle,transparent 14%,#000 30%,rgba(0,0,0,.4) 48%,transparent 68%);filter:blur(28px);opacity:0}
177
+ .pkb-mfx.pkb-show .pkb-mfx-glow{animation:pkb-spin 3s linear infinite,pkb-glow 1.7s ease-out both}
178
+ @keyframes pkb-glow{0%{opacity:0;scale:.35}30%{opacity:.8;scale:1}100%{opacity:.5;scale:1.12}}
179
+ .pkb-mfx i{position:absolute;left:var(--x);top:var(--y);width:calc(20px*var(--s));aspect-ratio:1;background:var(--c);clip-path:polygon(50% 0,62% 38%,100% 50%,62% 62%,50% 100%,38% 62%,0 50%,38% 38%);opacity:0}
180
+ .pkb-mfx.pkb-show i{animation:pkb-twk .85s ease-in-out var(--t) both}
181
+ @keyframes pkb-twk{0%{opacity:0;scale:0;rotate:0deg}45%{opacity:1;scale:1;rotate:70deg}100%{opacity:0;scale:.2;rotate:160deg}}
182
+ .pkb-mfx-in{position:relative;display:flex;flex-direction:column;align-items:center;padding:0 16px}
183
+ .pkb-mfx-sym{display:block;font-family:var(--pk-display);font-weight:400;line-height:1}
184
+ .pkb-mfx-inf .pkb-mfx-sym{font-size:clamp(110px,36cqi,230px);line-height:.9;padding:0 .06em;background:linear-gradient(90deg,#FFE066,#FF9F1C,#E8473B,#9B5DE5,#2F6FED,#1FA971,#FFE066) 0 0/200% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;filter:drop-shadow(0 0 22px rgba(155,93,229,.9)) drop-shadow(0 0 3px rgba(255,255,255,.8))}
185
+ .pkb-mfx.pkb-show.pkb-mfx-inf .pkb-mfx-sym{animation:pkb-sym 1.7s cubic-bezier(.2,1.25,.35,1) both,pkb-rb 1.7s linear both}
186
+ @keyframes pkb-sym{0%{opacity:0;transform:scale(.25) rotate(-30deg)}26%{opacity:1;transform:scale(1.1) rotate(4deg)}38%{transform:scale(1) rotate(0)}100%{opacity:1;transform:scale(1.06)}}
187
+ .pkb-mfx-n .pkb-mfx-sym{display:grid;place-items:center;width:clamp(110px,30cqi,170px);aspect-ratio:1;border-radius:50%;border:5px solid var(--pk-red);box-shadow:inset 0 0 0 4px var(--pk-sun),inset 0 0 0 7px var(--pk-red);color:var(--pk-red);font-size:clamp(34px,10cqi,56px);letter-spacing:.04em;transform:rotate(-14deg)}
188
+ .pkb-mfx.pkb-show.pkb-mfx-n .pkb-mfx-sym{animation:pkb-mslam .42s cubic-bezier(.5,0,.75,0) .08s both}
189
+ @keyframes pkb-mslam{from{opacity:0;transform:rotate(-14deg) scale(2.6)}to{opacity:1;transform:rotate(-14deg) scale(1)}}
190
+ .pkb-mfx-t{display:block;margin-top:6px;font-family:var(--pk-display);font-weight:400;font-size:clamp(24px,8.5cqi,52px);line-height:1.1;letter-spacing:.2em;margin-right:-.2em;white-space:nowrap}
191
+ .pkb-mfx-inf .pkb-mfx-t{color:#fff;text-shadow:0 0 18px rgba(155,93,229,.95),0 0 4px rgba(255,255,255,.9)}
192
+ .pkb-mfx-n .pkb-mfx-t{margin-top:16px;color:var(--pk-ink)}
193
+ .pkb-mfx.pkb-show .pkb-mfx-t{animation:pkb-track 1.7s cubic-bezier(.16,1,.3,1) .12s both}
194
+ @keyframes pkb-track{0%{opacity:0;letter-spacing:.9em;margin-right:-.9em;filter:blur(8px)}40%{opacity:1;letter-spacing:.2em;margin-right:-.2em;filter:blur(0)}100%{opacity:1;letter-spacing:.24em;margin-right:-.24em}}
195
+ .pkb-mfx-s{display:inline-block;margin-top:12px;padding:5px 16px 4px;border-radius:999px;font-weight:800;font-size:14px;line-height:1.4;letter-spacing:.06em}
196
+ .pkb-mfx-inf .pkb-mfx-s{color:#fff;background:rgba(255,255,255,.12);border:1.5px solid rgba(255,255,255,.4)}
197
+ .pkb-mfx-n .pkb-mfx-s{background:var(--pk-ink);color:var(--pk-sun)}
198
+ .pkb-mfx.pkb-show .pkb-mfx-s{animation:pkb-up .6s cubic-bezier(.2,1.3,.4,1) .4s both}
199
+ @keyframes pkb-up{from{opacity:0;transform:translateY(12px)}}
200
+ .pkb-finbtn{display:none;appearance:none;flex:none;border:2px solid var(--pk-ink);border-radius:999px;padding:5px 14px;font-weight:800;font-size:12px;line-height:1.4;letter-spacing:.04em;color:#fff;text-shadow:0 1px 1px rgba(42,31,20,.55);background:linear-gradient(90deg,#FF9F1C,#E8473B,#9B5DE5,#2F6FED,#1FA971,#FF9F1C) 0 0/200% 100%;box-shadow:2px 2px 0 var(--pk-ink),0 0 12px rgba(155,93,229,.45);cursor:pointer;animation:pkb-rb 2.4s linear infinite}
201
+ .pkb.pkb-inf .pkb-finbtn{display:inline-block}
202
+ .pkb-finbtn:active:not(:disabled){transform:translate(2px,2px);box-shadow:none}
203
+ .pkb-finbtn:disabled{cursor:default;opacity:.4;animation:none;box-shadow:2px 2px 0 var(--pk-ink)}
204
+ .pkb-board.pkb-over .pkb-grid{opacity:.55;filter:saturate(.5);transition:opacity .4s,filter .4s}
205
+ .pkb-pbtns{display:flex;flex-wrap:wrap;justify-content:center;gap:10px}
206
+ .pkb-perfect.pkb-fin .pkb-card{border-color:transparent;background:linear-gradient(var(--pk-paper),var(--pk-paper)) padding-box,linear-gradient(120deg,#FF9F1C,#E8473B 22%,#9B5DE5 45%,#2F6FED 68%,#1FA971 88%,#FF9F1C) border-box;box-shadow:0 0 0 2px var(--pk-ink),6px 6px 0 2px var(--pk-ink),0 0 40px rgba(155,93,229,.5)}
207
+ .pkb-perfect.pkb-fin .pkb-medal{border-color:transparent;background:linear-gradient(var(--pk-paper),var(--pk-paper)) padding-box,conic-gradient(#FF9F1C,#E8473B,#9B5DE5,#2F6FED,#1FA971,#FF9F1C) border-box;box-shadow:0 0 18px rgba(155,93,229,.55);color:#7B3FD0;font-size:clamp(44px,14cqi,64px);line-height:1;text-shadow:0 0 12px rgba(155,93,229,.45)}
208
+ .pkb-perfect.pkb-fin .pkb-again{background:linear-gradient(90deg,#FF9F1C,#E8473B,#9B5DE5,#2F6FED,#1FA971,#FF9F1C) 0 0/200% 100%;color:#fff;text-shadow:0 1px 1px rgba(42,31,20,.55);animation:pkb-rb 2.4s linear infinite}
209
+ .pkb-perfect.pkb-fin .pkb-close:not(.pkb-again){background:var(--pk-paper)}
210
+ @container (max-width:560px){.pkb-board{padding:18px 14px 16px}.pkb-head{flex-direction:column;align-items:stretch;gap:12px}.pkb-score{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}.pkb-pill,.pkb-pill.pkb-sc{min-width:0;padding:5px 4px 4px}.pkb-pill b{font-size:19px}.pkb-title{font-size:26px}.pkb-grid{gap:max(3px,calc(8px*var(--pk-d)))}.pkb-tile{border-radius:calc(12px*var(--pk-d));box-shadow:3px 3px 0 var(--pk-ink);gap:calc(3px*var(--pk-d));aspect-ratio:1/1}.pkb-emo{font-size:max(13px,calc(24px*var(--pk-s)))}.pkb-lbl{font-size:max(8.5px,calc(10.5px*var(--pk-s)));padding:0 calc(2px*var(--pk-d))}.pkb-stamp{font-size:max(9px,calc(14px*var(--pk-s)))}.pkb-tile.pkb-reach::after{font-size:9px;padding:2px 5px;top:-9px;right:-5px}.pkb-lines .pkb-u{stroke-width:calc(10px*var(--pk-d))}.pkb-lines .pkb-o{stroke-width:calc(5px*var(--pk-d))}.pkb-banner::before{width:380px;height:380px;margin:-190px 0 0 -190px}.pkb-banner span{font-size:12px}.pkb-medal{width:96px;height:96px;font-size:20px}.pkb-card{padding:20px 14px 16px}.pkb-ptitle{font-size:24px}.pkb-stats b{font-size:17px}.pkb-float.pkb-pt{font-size:17px}.pkb-float.pkb-cmb{font-size:13px}.pkb-ready-in{padding:20px 16px 18px}.pkb-ready-l{font-size:15px;padding:10px 12px}.pkb-ready-go{font-size:15px}.pkb-ptime b{font-size:19px}}
211
+ @container (max-width:400px){.pkb-board{padding:16px 10px 14px}.pkb-mode button{padding:3px 8px 2px}.pkb-grid{gap:max(3px,calc(6px*var(--pk-d)))}.pkb-lbl{font-size:max(8.5px,calc(10px*var(--pk-s)));padding:0 calc(1px*var(--pk-d))}.pkb-emo{font-size:max(12px,calc(22px*var(--pk-s)))}.pkb-stamp{font-size:max(9px,calc(13px*var(--pk-s)))}.pkb-foot{margin-top:14px;font-size:12px}.pkb-perfect,.pkb-ready{padding:12px}.pkb-stats{gap:6px}.pkb-stats>div{padding:6px 2px 5px}.pkb-stats small{letter-spacing:.02em}}
116
212
  @container (max-width:320px){.pkb-board{padding-inline:8px}.pkb-grid{gap:max(3px,calc(5px*var(--pk-d)))}.pkb-lbl{font-size:max(8.5px,calc(9.5px*var(--pk-s)));padding:0}}
117
- @media (prefers-reduced-motion:reduce){.pkb-board.pkb-shake,.pkb-board.pkb-punch,.pkb-flash.pkb-go,.pkb-tile.pkb-hop,.pkb-tile.pkb-squash,.pkb-tile.pkb-reach,.pkb-tile.pkb-line::before,.pkb-pill.pkb-hot,.pkb-bump,.pkb-tile.pkb-reach::after,.pkb-banner::before,.pkb-lines .pkb-draw line,.pkb-kicker.pkb-gold{animation:none}.pkb-banner.pkb-show{animation:pkb-fade 1.8s forwards}.pkb-float{animation:pkb-fade 1s both}.pkb-perfect.pkb-show .pkb-medal{animation:none;opacity:1;transform:rotate(-14deg)}.pkb-card{transition:none}}
213
+ @media (prefers-reduced-motion:reduce){.pkb-board.pkb-shake,.pkb-board.pkb-punch,.pkb-flash.pkb-go,.pkb-tile.pkb-hop,.pkb-tile.pkb-squash,.pkb-tile.pkb-on .pkb-stamp.pkb-hit,.pkb-tile.pkb-reach,.pkb-tile.pkb-line::before,.pkb-pill.pkb-hot,.pkb-bump,.pkb-tile.pkb-reach::after,.pkb-banner::before,.pkb-lines .pkb-draw line,.pkb-kicker.pkb-gold,.pkb-ready-go,.pkb.pkb-inf .pkb-mode-th,.pkb.pkb-inf .pkb-mode::after,.pkb.pkb-inf .pkb-ready-b,.pkb-tile.pkb-clr,.pkb-finbtn,.pkb-perfect.pkb-fin .pkb-again,.pkb-mfx.pkb-show.pkb-mfx-inf .pkb-mfx-sym,.pkb-mfx.pkb-show.pkb-mfx-n .pkb-mfx-sym,.pkb-mfx.pkb-show .pkb-mfx-t,.pkb-mfx.pkb-show .pkb-mfx-s,.pkb-mfx.pkb-show .pkb-mfx-glow,.pkb-mfx.pkb-show::after{animation:none}.pkb-count.pkb-tick,.pkb-count.pkb-go.pkb-tick{animation:pkb-fade 1s forwards}.pkb-mfx.pkb-show{animation:pkb-fade 1.4s forwards}.pkb-mode-th{transition:none}.pkb-ready{transition:none}.pkb-banner.pkb-show{animation:pkb-fade 1.8s forwards}.pkb-float{animation:pkb-fade 1s both}.pkb-perfect.pkb-show .pkb-medal{animation:none;opacity:1;transform:rotate(-14deg)}.pkb-card,.pkb-tile,.pkb-stamp{transition:none}}
118
214
  @keyframes pkb-fade{0%,100%{opacity:0}15%,80%{opacity:1}}
119
- `;var tn=Ye(4),Bt=["#E8473B","#2F6FED","#1FA971","#FFFDF6","#2A1F14","#FF9F1C"],$t=["#FF9F1C","#1FA971","#2F6FED","#9B5DE5","#E8473B"],nn=2500,Ct="packing-bingo-muted",an="packing-bingo-order:",h=n=>n.replace(/[&<>"']/g,a=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[a]);function Ze(n){try{return localStorage.getItem(n)}catch{return null}}function Qe(n,a){try{localStorage.setItem(n,a)}catch{}}var Tt=(n,a)=>`${+((Math.floor(n/a)+n%a)*.36/Math.max(1,a-1)).toFixed(3)}s`,Oe=n=>n.slice().sort((a,s)=>a-s).join(","),zt=560;function rn(){if(document.getElementById("pkb-styles"))return;let n=document.createElement("style");n.id="pkb-styles",n.textContent=Mt,document.head.appendChild(n)}function on(n,a,{demo:s,shuffle:m,vibrate:c}){let x=n.size,b=c?'<input type="checkbox" switch role="checkbox">':'<input type="checkbox">',l=Array.from({length:x*x},($,u)=>{let M=`--pkb-gd:${Tt(u,x)}`;if(u===n.center)return`<div class="pkb-tile pkb-free pkb-on" style="${M}"><span class="pkb-stamp">${h(a.free)}</span></div>`;let E=n.items[n.itemCell.indexOf(u)];return`<label class="pkb-tile" data-reach="${h(a.reachBadge)}" style="${M}">${b}<span class="pkb-emo" aria-hidden="true">${h(E.emoji)}</span><span class="pkb-lbl">${h(E.label).replace(/・/g,"\u30FB<wbr>")}</span><span class="pkb-stamp" aria-hidden="true">${h(a.stamp)}</span></label>`}).join(""),k=`--pk-n:${x};--pk-s:${+Math.min(1.35,4/x).toFixed(3)};--pk-d:${+Math.min(1,4/x).toFixed(3)}`,v=s?`<div class="pkb-demo"><span>${h(a.demoLabel)}</span><button type="button" data-r="dB">${h(a.demoBingo)}</button><button type="button" data-r="dP">${h(a.demoPerfect)}</button><button type="button" data-r="dR">${h(a.demoRestore)}</button></div>`:"";return`<div class="pkb" style="${k}"><div class="pkb-board">
215
+ `;var ba=It(4),da=["#E8473B","#2F6FED","#1FA971","#FFFDF6","#2A1F14","#FF9F1C"],Rn=["#FF9F1C","#1FA971","#2F6FED","#9B5DE5","#E8473B"],fa=2500,In="packing-bingo-muted",ma="packing-bingo-order:",g=r=>r.replace(/[&<>"']/g,n=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[n]);function Ht(r){try{return localStorage.getItem(r)}catch{return null}}function bt(r,n){try{localStorage.setItem(r,n)}catch{}}var qn=(r,n)=>`${+((Math.floor(r/n)+r%n)*.36/Math.max(1,n-1)).toFixed(3)}s`,Je=r=>r.slice().sort((n,f)=>n-f).join(","),ka=1e3,ua=750;function Ze(r,n=1){let f=10**n,u=Math.floor(Math.max(0,r)/(1e3/f)),y=n?"."+String(u%f).padStart(n,"0"):"",x=Math.floor(u/f),h=x%60,p=Math.floor(x/60)%60,T=Math.floor(x/3600),M=b=>String(b).padStart(2,"0");return(T?`${T}:${M(p)}`:String(p))+`:${M(h)}${y}`}function Nn(r,n){return Math.round(r*1e6/Math.max(n,1))}var jt=560,ga=1e3,Be=["#FFFFFF","#FFE066","#FF9F1C","#E8473B","#9B5DE5","#2F6FED","#1FA971"];function ha(){if(document.getElementById("pkb-styles"))return;let r=document.createElement("style");r.id="pkb-styles",r.textContent=Pn,document.head.appendChild(r)}var dt=(r,n)=>r??n??"";function xa(r,n,{demo:f,shuffle:u,vibrate:y,ready:x,modes:h}){let p=r.size,T=y?'<input type="checkbox" switch role="checkbox">':'<input type="checkbox">',M=Array.from({length:p*p},(_,m)=>{let re=`--pkb-gd:${qn(m,p)}`;if(m===r.center)return`<div class="pkb-tile pkb-free pkb-on" style="${re}"><span class="pkb-stamp">${g(n.free)}</span></div>`;let G=r.items[r.itemCell.indexOf(m)];return`<label class="pkb-tile" data-reach="${g(n.reachBadge)}" style="${re}">${T}<span class="pkb-emo" aria-hidden="true">${g(G.emoji)}</span><span class="pkb-lbl">${g(G.label).replace(/・/g,"\u30FB<wbr>")}</span><span class="pkb-stamp" aria-hidden="true">${g(n.stamp)}</span></label>`}).join(""),b=`--pk-n:${p};--pk-s:${+Math.min(1.35,4/p).toFixed(3)};--pk-d:${+Math.min(1,4/p).toFixed(3)}`,c=f?`<div class="pkb-demo"><span>${g(n.demoLabel)}</span><button type="button" data-r="dB">${g(n.demoBingo)}</button><button type="button" data-r="dP">${g(n.demoPerfect)}</button><button type="button" data-r="dR">${g(n.demoRestore)}</button></div>`:"",k=[dt(n.soundHint,S.soundHint),y?dt(n.vibrationHint,S.vibrationHint):""].filter(_=>_.trim()),L=dt(n.readyPrompt,S.readyPrompt),$=dt(n.infiniteRule,S.infiniteRule),se=x?`<button type="button" class="pkb-ready" data-r="ready"><span class="pkb-ready-in"><span class="pkb-ready-b">\u221E ${g(n.infiniteSub?.trim()||S.infiniteSub)}</span><b class="pkb-ready-t">${g(n.readyTitle?.trim()||S.readyTitle)}</b>`+(L.trim()?`<span class="pkb-ready-q">${g(L)}</span>`:"")+($.trim()?`<span class="pkb-ready-r">${g($)}</span>`:"")+(k.length?`<span class="pkb-ready-l">${k.map(_=>`<span>${g(_)}</span>`).join("")}</span>`:"")+`<span class="pkb-ready-go">${g(n.readyTap?.trim()||S.readyTap)}</span></span><b class="pkb-count" data-r="count" aria-live="assertive"></b></button>`:"",W=n.time?.trim()||S.time,V=h?`<span class="pkb-mode" data-r="mode" role="radiogroup" aria-label="${g(n.modeLabel?.trim()||S.modeLabel)}"><i class="pkb-mode-th" data-r="modeTh"></i><button type="button" role="radio" data-m="normal">${g(n.modeNormal?.trim()||S.modeNormal)}</button><button type="button" role="radio" data-m="infinite">${g(n.modeInfinite?.trim()||S.modeInfinite)}</button></span>`:"";return`<div class="pkb" style="${b}"><div class="pkb-board">
120
216
  <div class="pkb-head"><div>
121
- <div class="pkb-tags"><span class="pkb-kicker" data-r="kick">${h(a.tag)}</span><button type="button" class="pkb-snd" data-r="snd"></button></div>
122
- <h2 class="pkb-title">${h(a.title)}</h2>${a.subtitle?`<p class="pkb-sub">${h(a.subtitle)}</p>`:""}</div>
217
+ <div class="pkb-tags"><span class="pkb-kicker" data-r="kick">${g(n.tag)}</span>${V}<button type="button" class="pkb-snd" data-r="snd"></button><span class="pkb-watch" data-r="watch" role="timer" aria-label="${g(W)}">${Ze(0)}</span></div>
218
+ <h2 class="pkb-title">${g(n.title)}</h2>${n.subtitle?`<p class="pkb-sub">${g(n.subtitle)}</p>`:""}</div>
123
219
  <div class="pkb-side"><div class="pkb-score">
124
- <div class="pkb-pill"><small>${h(a.packed)}</small><b data-r="cnt"></b></div>
125
- <div class="pkb-pill" data-r="bp"><small>${h(a.bingo)}</small><b data-r="bng"></b></div>
126
- <div class="pkb-pill pkb-sc" data-r="sp"><small>${h(a.score)}</small><b data-r="sc">0</b></div></div>
220
+ <div class="pkb-pill"><small>${g(n.packed)}</small><b data-r="cnt"></b></div>
221
+ <div class="pkb-pill" data-r="bp"><small>${g(n.bingo)}</small><b data-r="bng"></b></div>
222
+ <div class="pkb-pill pkb-sc" data-r="sp"><small>${g(n.score)}</small><b data-r="sc">0</b></div></div>
127
223
  <div class="pkb-combo" data-r="combo"><b data-r="cmbN"></b><span class="pkb-bar"><i data-r="cbar"></i></span></div></div></div>
128
- <div class="pkb-gw"><div class="pkb-grid">${l}</div><svg class="pkb-lines" aria-hidden="true"></svg>
224
+ <div class="pkb-gw"><div class="pkb-grid">${M}</div><svg class="pkb-lines" aria-hidden="true"></svg>
129
225
  <div class="pkb-banner" data-r="banner" aria-hidden="true"><b data-r="bT"></b><span data-r="bS"></span></div></div>
130
- <div class="pkb-foot"><span data-r="msg" aria-live="polite"></span><div class="pkb-acts">${m?`<button type="button" class="pkb-shuf" data-r="shuf">${h(a.shuffle)}</button>`:""}<button type="button" class="pkb-reset" data-r="reset">${h(a.reset)}</button></div></div>
226
+ <div class="pkb-foot"><span data-r="msg" aria-live="polite"></span><div class="pkb-acts"><button type="button" class="pkb-finbtn" data-r="fin" disabled>${g(n.finish?.trim()||S.finish)}</button>${u?`<button type="button" class="pkb-shuf" data-r="shuf">${g(n.shuffle)}</button>`:""}<button type="button" class="pkb-reset" data-r="reset">${g(n.reset)}</button></div></div>
131
227
  <div class="pkb-flash" data-r="flash"></div>
132
- <div class="pkb-perfect" data-r="perfect"><div class="pkb-card" role="dialog" aria-label="${h(a.perfectTitle)}">
133
- <div class="pkb-medal">${h(a.perfectStamp)}</div><h3 class="pkb-ptitle">${h(a.perfectTitle)}</h3><p class="pkb-pbody" data-r="pbody">${h(Ot(a,n.items.length))}</p>
134
- <div class="pkb-stats"><div><small>${h(a.statScore)}</small><b data-r="sScore">0</b></div><div><small>${h(a.statCombo)}</small><b data-r="sCombo">\xD70</b></div><div><small>${h(a.statLines)}</small><b data-r="sBingo">0</b></div></div>
135
- <button type="button" class="pkb-close" data-r="close">${h(a.close)}</button></div></div>
136
- <canvas class="pkb-fx"></canvas></div>${v}</div>`}var Ot=(n,a)=>typeof n.perfectBody=="function"?n.perfectBody(a):n.perfectBody;function sn(n,a={}){let s=yt(a),{items:m,cellLines:c}=s,x=s.size,b=m.length,l=e=>Array.from({length:b},(t,r)=>!!e?.[r]),k=()=>Array.from({length:b},(e,t)=>t),v=e=>e.every((t,r)=>t===r),$=e=>Array.isArray(e)&&e.length===b&&e.every(t=>Number.isInteger(t)&&t>=0&&t<b)&&new Set(e).size===b,u=k(),M=k(),E=s.lines,T=[...c[0],...c[2*x].slice(1,-1)],q=s.itemCell.flatMap((e,t)=>T.includes(e)?[t]:[]),P=()=>{let e=l(void 0);return q.forEach(t=>e[u[t]]=!0),e},ee=e=>Math.floor(e/x)+e%x,ve=Math.min(1,4/x),g={...Je,...a.messages};a.title!=null&&(g.title=a.title),a.tag!=null&&(g.tag=a.tag),a.subtitle!=null&&(g.subtitle=a.subtitle);let At=!!a.controlled,te=St(a),ye=te&&an+te,Ae=!!a.demo,et=a.vibrate!==!1,I=typeof matchMedia=="function"&&matchMedia("(prefers-reduced-motion: reduce)").matches,C=!1,ne=new Set,N=(e,t)=>{let r=window.setTimeout(()=>{ne.delete(r),C||e()},t);ne.add(r)},Ft=e=>new Promise(t=>window.setTimeout(t,e)),be=0;rn(),n.innerHTML=on(s,g,{demo:Ae,shuffle:a.shuffle!==!1,vibrate:et});let f=e=>{let t=n.querySelector(`[data-r="${e}"]`);if(!t)throw new Error(`[packing-bingo] internal: missing element "${e}"`);return t},_=n.querySelector(".pkb-board"),we=n.querySelector(".pkb-gw"),de=n.querySelector(".pkb-grid"),Ee=n.querySelector(".pkb-lines"),fe=n.querySelector(".pkb-fx"),L=fe.getContext("2d"),K=Array.from(de.children),H=s.itemCell.map(e=>K[e]),Pt=s.center>=0?K[s.center]:null,Le=H.map(e=>e.querySelector("input")),tt=f("kick"),Fe=f("snd"),U=f("perfect"),w=l(void 0),B=[],me=new Set,Pe=new Set,Se=!1,nt=0,O=0,ue=0,z=0,ae=0,at=0,Ie=!1,re=new Set,J=new Set,rt=Ze(Ct),Z=rt!=null?rt==="1":a.sound===!1,A=Lt(()=>Z),ot=()=>{Fe.textContent=Z?g.soundOff:g.soundOn,Fe.setAttribute("aria-pressed",String(!Z))};Fe.addEventListener("click",()=>{Z=!Z,Qe(Ct,Z?"1":"0"),ot(),Z||A.pop(4)}),ot();let W=[],Q=0,ke=1,V=0,X=0,it=()=>{let e=_.getBoundingClientRect();ke=Math.min(2,window.devicePixelRatio||1),V=e.width,X=e.height,fe.width=Math.round(V*ke),fe.height=Math.round(X*ke)},Re=(e,t,r,o,p,i,d,S)=>({x:e,y:t,vx:r,vy:o,g:p,life:d,shape:S,w:(5+Math.random()*6)*i,h:(3+Math.random()*5)*i,r:Math.random()*6,vr:(Math.random()-.5)*.35,c:Bt[Math.random()*Bt.length|0]}),qe=()=>{!Q&&L&&(Q=requestAnimationFrame(st))};function oe(e,t,r,o={}){if(!I){for(let p=0;p<r;p++){let i=(o.angle??-Math.PI/2)+(Math.random()-.5)*(o.spread??Math.PI*2),d=(o.speed??10)*(.35+Math.random()*.85),S=Math.random()<(o.star??.15)?"star":Math.random()<.3?"round":"rect";W.push(Re(e,t,Math.cos(i)*d,Math.sin(i)*d,o.g??.28,o.size??1,(o.life??110)+Math.random()*40,S))}qe()}}function It(e){if(I)return;let t=performance.now()+e,r=()=>{for(let o=0;o<4;o++)W.push(Re(Math.random()*V,-12,(Math.random()-.5)*2,2+Math.random()*3,.045,1,420,Math.random()<.2?"star":"rect"));qe(),performance.now()<t&&N(r,45)};r()}function Rt(e){if(I)return;let t=performance.now()+e,r=()=>{let o=Re(Math.random()*V,-30,(Math.random()-.5)*1.5,1.5+Math.random()*2,.05,1,500,"emoji");o.e=m[Math.random()*m.length|0].emoji,o.w=22+Math.random()*12,o.vr=(Math.random()-.5)*.06,W.push(o),qe(),performance.now()<t&&N(r,110)};r()}function qt(e,t){oe(e,t,80,{speed:7.5,g:.06,life:85,star:.4}),A.boom()}function Nt(e,t){e.beginPath();for(let r=0;r<10;r++){let o=r*Math.PI/5-Math.PI/2,p=r%2?t*.45:t;e.lineTo(Math.cos(o)*p,Math.sin(o)*p)}e.closePath(),e.fill()}function st(){if(Q=0,!(C||!L)){L.setTransform(ke,0,0,ke,0,0),L.clearRect(0,0,V,X),W=W.filter(e=>e.life>0&&e.y<X+40);for(let e of W)e.vx*=.985,e.vy=e.vy*.985+e.g,e.x+=e.vx,e.y+=e.vy,e.r+=e.vr,e.life--,L.save(),L.globalAlpha=Math.min(1,e.life/25),L.translate(e.x,e.y),L.rotate(e.r),L.fillStyle=e.c,e.shape==="round"?(L.beginPath(),L.arc(0,0,e.h/1.6,0,7),L.fill()):e.shape==="star"?Nt(L,e.w*.8):e.shape==="emoji"?(L.font=`${e.w}px "Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji",sans-serif`,L.textAlign="center",L.textBaseline="middle",L.fillText(e.e??"",0,0)):(L.scale(1,Math.cos(e.r*2.3)),L.fillRect(-e.w/2,-e.h/2,e.w,e.h)),L.restore();W.length&&(Q=requestAnimationFrame(st))}}let Me=e=>{let t=_.getBoundingClientRect(),r=e.getBoundingClientRect();return{x:r.left-t.left+r.width/2,y:r.top-t.top+r.height/2}},R=(e,t)=>{e.classList.remove(t),e.offsetWidth,e.classList.add(t)},pt=(e,t)=>{I||(e.classList.remove("pkb-squash"),e.style.setProperty("--pkb-d",t+"ms"),R(e,"pkb-hop"))};de.addEventListener("animationend",e=>{let t=e.target;t.classList.contains("pkb-tile")&&(e.animationName==="pkb-hop"||e.animationName==="pkb-squash")&&t.classList.remove(e.animationName)});let jt=e=>{let t=document.createElement("span");t.className="pkb-ring",e.appendChild(t),t.addEventListener("animationend",()=>t.remove())},ge=e=>{if(!et)return;let t=navigator.userActivation;if(!(t&&!t.hasBeenActive))try{navigator.vibrate?.(e)}catch{}},Be=(e,t,r,o,p=0,i)=>{let d=document.createElement("div");d.className="pkb-float pkb-"+o,d.textContent=e,d.style.left=t+"px",d.style.top=r+"px",p&&(d.style.animationDelay=p+"ms"),i&&(d.style.color=i),_.appendChild(d),d.addEventListener("animationend",()=>d.remove())},lt=(e,t,r)=>Math.max(0,Math.min(1,(e-t)/r)),ct=e=>1-Math.pow(1-e,3),$e=0;function Ne(){cancelAnimationFrame($e);let e=ue,t=O,r=performance.now(),o=p=>{if(C)return;let i=lt(p,r,450);ue=Math.round(e+(t-e)*ct(i)),f("sc").textContent=ue.toLocaleString(),i<1&&($e=requestAnimationFrame(o))};o(r),I||R(f("sp"),"pkb-bump")}let bt=(e,t,r,o="pt")=>{Be(`+${e}`,t,r,o),Ne()};function je(e,t,r,o,p,i=!1){let d=performance.now(),S=be,F=0,G=j=>{if(C||S!==be)return;let le=lt(j,d,o);e.textContent=p(Math.round(t+(r-t)*ct(le))),i&&le<1&&j-F>55&&(A.tick(),F=j),le<1?requestAnimationFrame(G):I||R(e,"pkb-bump")};G(d)}let dt=e=>({x:e.offsetLeft+e.offsetWidth/2,y:e.offsetTop+e.offsetHeight/2}),he=0;function De(e=[]){if(he){Ee.innerHTML="";return}Ee.setAttribute("viewBox",`0 0 ${we.clientWidth} ${we.clientHeight}`),Ee.innerHTML=B.map(t=>{let r=dt(K[c[t][0]]),o=dt(K[c[t][x-1]]),p=o.x-r.x,i=o.y-r.y,d=Math.hypot(p,i)||1,S=26*ve,F=p/d*S,G=i/d*S,j=`x1="${r.x-F}" y1="${r.y-G}" x2="${o.x+F}" y2="${o.y+G}" pathLength="1"`;return`<g${e.includes(t)?' class="pkb-draw"':""}><line class="pkb-u" ${j}/><line class="pkb-o" ${j}/></g>`}).join("")}function Dt(e,t){let r=Me(H[e]);if(!t){z=0,f("combo").classList.remove("pkb-on"),A.off(),ge(8);return}let o=performance.now();z=o-at<nn?z+1:1,at=o,ae=Math.max(ae,z),A.pop(z-1),I||(R(H[e],"pkb-squash"),jt(H[e])),oe(r.x,r.y,18,{speed:6,g:.2,life:30,size:.6,star:.5}),re.has(e)||(re.add(e),O+=10*z,bt(10*z,r.x,r.y-12)),z>=2&&(Be(g.comboPop(z),r.x,r.y+22,"cmb",90,$t[(z-2)%$t.length]),f("cmbN").textContent=g.combo(z),R(f("combo"),"pkb-on")),ge(18)}f("cbar").addEventListener("animationend",()=>{f("combo").classList.remove("pkb-on"),z=0});function Ht(e){e.forEach(t=>{let r=Me(H[t]);Be(g.reachPop,r.x,r.y-34,"rch",150)}),N(()=>A.reach(),150)}function Gt(e,t){let r=e.length,o=[...new Set(e.flatMap(i=>c[i]))].map(i=>K[i]),p=Math.min(70,300/o.length);o.forEach((i,d)=>N(()=>{pt(i,0);let S=Me(i);oe(S.x,S.y,14,{speed:5,g:.15,life:30,size:.7,star:.8}),A.note(d+3)},d*p)),N(()=>{f("bT").textContent=r>=3?g.bannerTriple:r===2?g.bannerDouble:g.bannerSingle,f("bS").textContent=r>1?g.bannerMulti(r):g.bannerNth(B.length),R(f("banner"),"pkb-show"),I||(R(f("flash"),"pkb-go"),R(_,"pkb-punch"));let i=Me(we);oe(i.x,i.y,r>1?180:110,{speed:r>1?16:13,star:.3}),A.bingo(r),ge(r>1?[40,60,40,60,90]:[40,60,40]),t&&N(()=>bt(t,i.x,i.y+105,"big"),350)},o.length*p+60)}function _t(e){let t=Ie?0:1e3;Ie=!0,O+=t,K.forEach((o,p)=>pt(o,ee(p)*180/Math.max(1,x-1))),A.perfect(),I||R(f("flash"),"pkb-go"),f("pbody").textContent=Ot(g,b),f("sScore").textContent="0",f("sCombo").textContent="\xD70",f("sBingo").textContent="0",N(()=>{R(U,"pkb-show"),f("close").focus({preventScroll:!0}),N(()=>{I||R(_,"pkb-shake"),A.boom(),oe(0,X,90,{angle:-Math.PI/3,spread:.8,speed:22,g:.32,star:.3}),oe(V,X,90,{angle:-Math.PI*2/3,spread:.8,speed:22,g:.32,star:.3}),It(3500),ge([60,80,60,80,200]),t&&Be(g.perfectBonus(t),V/2,X*.16,"big"),je(f("sScore"),0,O,1300,o=>o.toLocaleString(),!0),je(f("sCombo"),0,ae,700,o=>"\xD7"+o),je(f("sBingo"),0,B.length,700,String),Ne()},720),[1300,1650,2e3,2350,2700].forEach(o=>N(()=>qt(V*(.15+Math.random()*.7),X*(.12+Math.random()*.3)),o)),N(()=>Rt(3e3),1500)},520);let r={score:O,maxCombo:ae};e.push(()=>a.onPerfect?.(r))}function He(){be++,ne.forEach(e=>clearTimeout(e)),ne.clear(),cancelAnimationFrame($e),ue=O,f("sc").textContent=O.toLocaleString()}function Kt(){W=[],cancelAnimationFrame(Q),Q=0,L?.clearRect(0,0,fe.width,fe.height),_.querySelectorAll(".pkb-float, .pkb-ring").forEach(e=>e.remove()),f("banner").classList.remove("pkb-show"),f("flash").classList.remove("pkb-go"),f("combo").classList.remove("pkb-on"),U.classList.remove("pkb-show")}let Ge=()=>E.flatMap((e,t)=>e.every(r=>w[r])?[t]:[]);function Ce(e,t){let r=[],o=w,p=o.filter(Boolean).length;B=Ge();let i=B.filter(y=>!me.has(y));[...me].some(y=>!B.includes(y))&&(He(),p<b&&U.classList.remove("pkb-show"));let d=new Set(B.flatMap(y=>c[y])),S=new Set;for(let y of E){let Y=y.filter(Wt=>!o[Wt]);Y.length===1&&S.add(Y[0])}H.forEach((y,Y)=>{y.classList.toggle("pkb-on",o[Y]),y.classList.toggle("pkb-line",d.has(s.itemCell[M[Y]])),y.classList.toggle("pkb-reach",S.has(Y))}),Pt?.classList.toggle("pkb-line",d.has(s.center)),_.classList.toggle("pkb-all",p===b),tt.classList.toggle("pkb-gold",p===b),tt.textContent=p===b?g.perfectTag:g.tag,f("cnt").textContent=`${p}/${b}`,f("bng").textContent=String(B.length);let F=f("bp");B.length>nt&&(F.classList.remove("pkb-hot"),F.offsetWidth),F.classList.toggle("pkb-hot",B.length>0),nt=B.length,De(i),e!==null&&Dt(e,o[e]);let G=i.map(y=>Oe(E[y])).filter(y=>!J.has(y));G.forEach(y=>J.add(y));let j=100*G.length*G.length;if(O+=j,t)j&&Ne();else if(p===b&&!Se)_t(r);else if(i.length){Gt(i,j);let y={newLines:i,totalLines:B.length,score:O};r.push(()=>a.onBingo?.(y))}else if(e!==null&&o[e]){let y=[...S].filter(Y=>!Pe.has(Y));y.length&&Ht(y)}me=new Set(B),Pe=S,Se=p===b;let le=[...S].map(y=>m[y].label);return f("msg").textContent=p===b?g.statusDone:le.length?g.statusReach(le):B.length?g.statusLines(B.length,b-p):g.statusStart(b-p),r}let ft=e=>{for(let t of e){if(C)return;t()}},mt=()=>{te&&Qe(te,JSON.stringify(w))};function ut(e,t,r){w=e,Le.forEach((p,i)=>p.checked=w[i]);let o=Ce(t,r);return mt(),o}function _e(e){He(),Kt(),w=e,Le.forEach((r,o)=>r.checked=w[o]),re.clear(),J.clear(),w.forEach((r,o)=>r&&re.add(o));let t=Ge();t.forEach(r=>J.add(Oe(E[r]))),me=new Set(t),Pe=new Set,Se=w.every(Boolean),Ie=Se,O=ue=re.size*10+J.size*100,z=0,ae=0,f("sc").textContent=O.toLocaleString(),Ce(null,!0),mt()}function ie(e,t,r={}){if(At){Le.forEach((p,i)=>p.checked=w[i]),a.onChange?.(e.slice());return}let o=[];r.reset?_e(e):o=ut(e,t,!!r.quiet),a.onChange?.(w.slice()),ft(o)}function kt(e){u=e,u.forEach((r,o)=>{M[r]=o,K[s.itemCell[o]]=H[r]}),E=s.lines.map(r=>r.map(o=>u[o]));let t=document.activeElement;K.forEach((r,o)=>{r.style.setProperty("--pkb-gd",Tt(o,x)),de.appendChild(r)}),t instanceof HTMLElement&&de.contains(t)&&document.activeElement!==t&&t.focus({preventScroll:!0})}let Ut=()=>{ye&&Qe(ye,JSON.stringify(u))},xe=[];function gt(e){w.every(Boolean)||He();let t=I?null:H.map(o=>o.getBoundingClientRect());xe.forEach(o=>o.cancel()),xe=[],kt(e),E.forEach(o=>{o.every(p=>re.has(p))&&J.add(Oe(o))});let r=Ge();r.forEach(o=>J.add(Oe(E[o]))),me=new Set(r),Ce(null,!0),Ut(),!(!t||typeof Element.prototype.animate!="function")&&(H.forEach((o,p)=>{let i=t[p],d=o.getBoundingClientRect(),S=i.left-d.left,F=i.top-d.top;Math.abs(S)+Math.abs(F)<1||xe.push(o.animate([{transform:`translate(${S}px,${F}px)`},{transform:"none"}],{duration:zt-140,delay:Math.random()*140,easing:"cubic-bezier(.3,1.25,.5,1)",fill:"backwards"}))}),clearTimeout(he),he=window.setTimeout(()=>{he=0,xe=[],C||De(B)},zt),Ee.innerHTML="")}function ht(){let e=u.slice();do for(let t=b-1;t>0;t--){let r=Math.floor(Math.random()*(t+1));[e[t],e[r]]=[e[r],e[t]]}while(e.every((t,r)=>t===u[r]));gt(e),A.shuffle(),ge([10,40,10,40,10,40,24])}let Ke=()=>{v(u)||gt(k())};if(de.addEventListener("change",e=>{let t=Le.indexOf(e.target);if(t<0)return;let r=w.slice();r[t]=!r[t],ie(r,t)}),n.querySelector('[data-r="shuf"]')?.addEventListener("click",ht),f("reset").addEventListener("click",()=>{Ke(),ie(l(void 0),null,{reset:!0})}),f("close").addEventListener("click",()=>U.classList.remove("pkb-show")),U.addEventListener("click",e=>{e.target===U&&U.classList.remove("pkb-show")}),Ae){let e=!1,t=()=>{w.every(Boolean)?ie(l(void 0),null,{reset:!0}):U.classList.remove("pkb-show")},r=async o=>{if(!e){e=!0;try{t();let p=be;for(let i of o){if(await Ft(i.delay),C||p!==be)return;let d=w.slice();d[i.i]=!0,ie(d,i.i,{quiet:i.quiet})}}finally{e=!1}}};f("dB").addEventListener("click",()=>{let o=()=>E.map(i=>i.filter(d=>!w[d])).filter(i=>i.length).sort((i,d)=>i.length-d.length)[0]??[],p=w.every(Boolean)?[...E[0]]:o();r(p.map(i=>({i,delay:320})))}),f("dP").addEventListener("click",()=>{let o=m.map((i,d)=>d),p=w.every(Boolean)?o:o.filter(i=>!w[i]);r(p.map((i,d)=>d<p.length-1?{i,delay:170,quiet:!0}:{i,delay:450}))}),f("dR").addEventListener("click",()=>{e||(Ke(),ie(P(),null,{reset:!0}))})}let se=null;if(ye)try{let e=JSON.parse(Ze(ye)??"null");$(e)&&(se=e)}catch{}!se&&$(a.defaultOrder)&&(se=a.defaultOrder.slice()),se&&!v(se)&&kt(se);let pe=null;if(te)try{let e=JSON.parse(Ze(te)??"null");Array.isArray(e)&&(pe=l(e))}catch{}!pe&&a.defaultChecked&&(pe=l(a.defaultChecked)),!pe&&Ae&&(pe=P()),it(),_e(pe??l(void 0));let Ue=typeof ResizeObserver=="function"?new ResizeObserver(()=>{it(),De()}):null;return Ue?.observe(_),Ue?.observe(we),{setChecked(e,t={}){if(C)return;let r=l(e),o=r.flatMap((p,i)=>p!==w[i]?[i]:[]);if(o.length){if(!t.animate||o.length!==1){_e(r);return}ft(ut(r,o[0],!1))}},reset(){C||(Ke(),ie(l(void 0),null,{reset:!0}))},shuffle(){C||ht()},refresh(){C||Ce(null,!0)},getState(){return{checked:w.slice(),lines:B.slice(),score:O,maxCombo:ae,complete:w.every(Boolean),size:x,free:s.free,order:u.slice()}},destroy(){C||(C=!0,ne.forEach(e=>clearTimeout(e)),ne.clear(),clearTimeout(he),xe.forEach(e=>e.cancel()),cancelAnimationFrame(Q),cancelAnimationFrame($e),Ue?.disconnect(),A.close(),n.innerHTML="")}}}return Qt(pn);})();
228
+ <div class="pkb-perfect" data-r="perfect"><div class="pkb-card" data-r="pcard" role="dialog" aria-label="${g(n.perfectTitle)}">
229
+ <div class="pkb-medal" data-r="medal">${g(n.perfectStamp)}</div><h3 class="pkb-ptitle" data-r="ptitle">${g(n.perfectTitle)}</h3><p class="pkb-pbody" data-r="pbody">${g(Dn(n,r.items.length))}</p>
230
+ <p class="pkb-ptime" data-r="ptime" hidden><small data-r="pTl">${g(n.statTime?.trim()||S.statTime)}</small><b data-r="pT"></b></p>
231
+ <div class="pkb-stats"><div><small>${g(n.statScore)}</small><b data-r="sScore">0</b></div><div><small>${g(n.statCombo)}</small><b data-r="sCombo">\xD70</b></div><div><small>${g(n.statLines)}</small><b data-r="sBingo">0</b></div></div>
232
+ <div class="pkb-pbtns"><button type="button" class="pkb-close pkb-again" data-r="again" hidden>${g(n.again?.trim()||S.again)}</button><button type="button" class="pkb-close" data-r="close">${g(n.close)}</button></div></div></div>
233
+ <canvas class="pkb-fx"></canvas>${se}<div class="pkb-mfx" data-r="mfx" aria-hidden="true"></div></div>${c}</div>`}var Dn=(r,n)=>typeof r.perfectBody=="function"?r.perfectBody(n):r.perfectBody;function ya(r,n={}){let f=Bn(n),{items:u,cellLines:y}=f,x=f.size,h=u.length,p=e=>Array.from({length:h},(t,a)=>!!e?.[a]),T=()=>Array.from({length:h},(e,t)=>t),M=e=>e.every((t,a)=>t===a),b=e=>Array.isArray(e)&&e.length===h&&e.every(t=>Number.isInteger(t)&&t>=0&&t<h)&&new Set(e).size===h,c=T(),k=T(),L=f.lines,$=[...y[0],...y[2*x].slice(1,-1)],se=f.itemCell.flatMap((e,t)=>$.includes(e)?[t]:[]),W=()=>{let e=p(void 0);return se.forEach(t=>e[c[t]]=!0),e},V=e=>Math.floor(e/x)+e%x,_=Math.min(1,4/x),m={...S,...n.messages};n.title!=null&&(m.title=n.title),n.tag!=null&&(m.tag=n.tag),n.subtitle!=null&&(m.subtitle=n.subtitle);let re=!!n.controlled,G=$n(n),pe=G&&ma+G,ft=!!n.demo,_t=n.vibrate!==!1,Gt=n.uncheck===!0,R=typeof matchMedia=="function"&&matchMedia("(prefers-reduced-motion: reduce)").matches,ke=An(_t),le=n.mode==="infinite"?"infinite":"normal",E=()=>le==="infinite",ce=null,ye=0,ie=new Set,oe=0,Kt=0,q=!1,Ce=new Set,J=(e,t)=>{let a=window.setTimeout(()=>{Ce.delete(a),q||e()},t);Ce.add(a)},Hn=e=>new Promise(t=>window.setTimeout(t,e)),Ne=0;ha(),r.innerHTML=xa(f,m,{demo:ft,shuffle:n.shuffle!==!1,vibrate:_t,ready:n.ready!==!1,modes:n.modeSwitch!==!1});let l=e=>{let t=r.querySelector(`[data-r="${e}"]`);if(!t)throw new Error(`[packing-bingo] internal: missing element "${e}"`);return t},jn=r.querySelector(".pkb"),N=r.querySelector(".pkb-board"),De=r.querySelector(".pkb-gw"),Q=r.querySelector(".pkb-grid"),Qe=r.querySelector(".pkb-lines"),He=r.querySelector(".pkb-fx"),B=He.getContext("2d"),be=Array.from(Q.children),ee=f.itemCell.map(e=>be[e]),_n=f.center>=0?be[f.center]:null,de=ee.map(e=>e.querySelector("input")),mt=ee.map(e=>e.querySelector(".pkb-stamp")),Ut=l("kick"),kt=l("snd"),K=l("perfect"),ue=l("mfx"),v=p(void 0),X=[],ze=new Set,et=new Set,je=!1,tt=!1,ut=!1,Vt,Yt=0,Y=0,_e=0,D=0,fe=0,Xt=0,nt=!1,ve=new Set,me=new Set,Wt=Ht(In),ge=Wt!=null?Wt==="1":n.sound===!1,P=zn(()=>ge),Jt=()=>{kt.textContent=ge?m.soundOff:m.soundOn,kt.setAttribute("aria-pressed",String(!ge))};kt.addEventListener("click",()=>{ge=!ge,bt(In,ge?"1":"0"),ge&&P.stop(),Jt(),ge||P.pop(4)}),Jt();let he=[],we=0,Ge=1,te=0,ne=0,Zt=()=>{let e=N.getBoundingClientRect();Ge=Math.min(2,window.devicePixelRatio||1),te=e.width,ne=e.height,He.width=Math.round(te*Ge),He.height=Math.round(ne*Ge)},gt=(e,t,a,i,d,o,s,F,A=da)=>({x:e,y:t,vx:a,vy:i,g:d,life:s,shape:F,w:(5+Math.random()*6)*o,h:(3+Math.random()*5)*o,r:Math.random()*6,vr:(Math.random()-.5)*.35,c:A[Math.random()*A.length|0]}),ht=()=>{!we&&B&&(we=requestAnimationFrame(tn))};function ae(e,t,a,i={}){if(!R){for(let d=0;d<a;d++){let o=(i.angle??-Math.PI/2)+(Math.random()-.5)*(i.spread??Math.PI*2),s=(i.speed??10)*(.35+Math.random()*.85),F=Math.random()<(i.star??.15)?"star":Math.random()<.3?"round":"rect";he.push(gt(e,t,Math.cos(o)*s,Math.sin(o)*s,i.g??.28,i.size??1,(i.life??110)+Math.random()*40,F,i.colors))}ht()}}function Qt(e){if(R)return;let t=performance.now()+e,a=()=>{for(let i=0;i<4;i++)he.push(gt(Math.random()*te,-12,(Math.random()-.5)*2,2+Math.random()*3,.045,1,420,Math.random()<.2?"star":"rect"));ht(),performance.now()<t&&J(a,45)};a()}function Gn(e){if(R)return;let t=performance.now()+e,a=()=>{let i=gt(Math.random()*te,-30,(Math.random()-.5)*1.5,1.5+Math.random()*2,.05,1,500,"emoji");i.e=u[Math.random()*u.length|0].emoji,i.w=22+Math.random()*12,i.vr=(Math.random()-.5)*.06,he.push(i),ht(),performance.now()<t&&J(a,110)};a()}function en(e,t){ae(e,t,80,{speed:7.5,g:.06,life:85,star:.4}),P.boom()}function Kn(e,t){e.beginPath();for(let a=0;a<10;a++){let i=a*Math.PI/5-Math.PI/2,d=a%2?t*.45:t;e.lineTo(Math.cos(i)*d,Math.sin(i)*d)}e.closePath(),e.fill()}function tn(){if(we=0,!(q||!B)){B.setTransform(Ge,0,0,Ge,0,0),B.clearRect(0,0,te,ne),he=he.filter(e=>e.life>0&&e.y<ne+40);for(let e of he)e.vx*=.985,e.vy=e.vy*.985+e.g,e.x+=e.vx,e.y+=e.vy,e.r+=e.vr,e.life--,B.save(),B.globalAlpha=Math.min(1,e.life/25),B.translate(e.x,e.y),B.rotate(e.r),B.fillStyle=e.c,e.shape==="round"?(B.beginPath(),B.arc(0,0,e.h/1.6,0,7),B.fill()):e.shape==="star"?Kn(B,e.w*.8):e.shape==="emoji"?(B.font=`${e.w}px "Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji",sans-serif`,B.textAlign="center",B.textBaseline="middle",B.fillText(e.e??"",0,0)):(B.scale(1,Math.cos(e.r*2.3)),B.fillRect(-e.w/2,-e.h/2,e.w,e.h)),B.restore();he.length&&(we=requestAnimationFrame(tn))}}let Ee=e=>{let t=N.getBoundingClientRect(),a=e.getBoundingClientRect();return{x:a.left-t.left+a.width/2,y:a.top-t.top+a.height/2}},C=(e,t)=>{e.classList.remove(t),e.offsetWidth,e.classList.add(t)},nn=(e,t)=>{R||(e.classList.remove("pkb-squash"),e.style.setProperty("--pkb-d",t+"ms"),C(e,"pkb-hop"))};Q.addEventListener("animationend",e=>{let t=e.target;e.animationName==="pkb-stamp-hit"&&t.classList.remove("pkb-hit"),t.classList.contains("pkb-tile")&&(e.animationName==="pkb-hop"||e.animationName==="pkb-squash")&&t.classList.remove(e.animationName),t.classList.contains("pkb-tile")&&e.animationName==="pkb-clr"&&t.classList.remove("pkb-clr")});let Un=e=>{let t=document.createElement("span");t.className="pkb-ring",e.appendChild(t),t.addEventListener("animationend",()=>t.remove())},Ke=(e,t,a,i,d=0,o)=>{let s=document.createElement("div");s.className="pkb-float pkb-"+i,s.textContent=e,s.style.left=t+"px",s.style.top=a+"px",d&&(s.style.animationDelay=d+"ms"),o&&(s.style.color=o),N.appendChild(s),s.addEventListener("animationend",()=>s.remove())},an=(e,t,a)=>Math.max(0,Math.min(1,(e-t)/a)),rn=e=>1-Math.pow(1-e,3),at=0;function xt(){cancelAnimationFrame(at);let e=_e,t=Y,a=performance.now(),i=d=>{if(q)return;let o=an(d,a,450);_e=Math.round(e+(t-e)*rn(o)),l("sc").textContent=_e.toLocaleString(),o<1&&(at=requestAnimationFrame(i))};i(a),R||C(l("sp"),"pkb-bump")}let on=(e,t,a,i="pt")=>{Ke(`+${e}`,t,a,i),xt()};function Ae(e,t,a,i,d,o=!1){let s=performance.now(),F=Ne,A=0,I=j=>{if(q||F!==Ne)return;let Me=an(j,s,i);e.textContent=d(Math.round(t+(a-t)*rn(Me))),o&&Me<1&&j-A>55&&(P.tick(),A=j),Me<1?requestAnimationFrame(I):R||C(e,"pkb-bump")};I(s)}let sn=e=>({x:e.offsetLeft+e.offsetWidth/2,y:e.offsetTop+e.offsetHeight/2}),Fe=0;function yt(e=[]){if(Fe){Qe.innerHTML="";return}Qe.setAttribute("viewBox",`0 0 ${De.clientWidth} ${De.clientHeight}`),Qe.innerHTML=X.map(t=>{let a=sn(be[y[t][0]]),i=sn(be[y[t][x-1]]),d=i.x-a.x,o=i.y-a.y,s=Math.hypot(d,o)||1,F=26*_,A=d/s*F,I=o/s*F,j=`x1="${a.x-A}" y1="${a.y-I}" x2="${i.x+A}" y2="${i.y+I}" pathLength="1"`;return`<g${e.includes(t)?' class="pkb-draw"':""}><line class="pkb-u" ${j}/><line class="pkb-o" ${j}/></g>`}).join("")}let H=r.querySelector('[data-r="ready"]'),$e=l("watch"),z="idle",rt=0,Ue=0,Z=null,it=new Set,pn=(e,t)=>{let a=window.setTimeout(()=>{it.delete(a),q||e()},t);it.add(a)},ot=()=>{it.forEach(e=>clearTimeout(e)),it.clear(),clearInterval(Ue)},ln=()=>z==="play"?performance.now()-rt:Z??0,Ve=()=>{$e.textContent=Ze(ln())};function vt(){z="play",rt=performance.now(),Z=null,clearInterval(Ue),Ue=window.setInterval(Ve,100),$e.classList.remove("pkb-done"),$e.classList.add("pkb-run"),Ve(),wt()}let cn=l("fin"),bn=r.querySelector('[data-r="shuf"]'),wt=()=>{cn.disabled=!(E()&&z==="play"),bn&&(bn.disabled=E()&&z==="done")};function dn(){z==="play"?(Z=performance.now()-rt,$e.classList.replace("pkb-run","pkb-done")):z!=="done"&&(ot(),Et(!1)),z="done",clearInterval(Ue),Ve()}function Et(e){if(Q.removeAttribute("inert"),!H||H.hidden)return;let t=document.activeElement===H;H.classList.add("pkb-gone"),N.classList.remove("pkb-waiting"),H.tabIndex=-1,t&&Q.querySelector("input")?.focus({preventScroll:!0}),e?pn(()=>H.hidden=!0,ua):H.hidden=!0}function Pe(){ot(),Z=null,$e.classList.remove("pkb-run","pkb-done"),z=H?"ready":"idle",Ve(),wt(),N.classList.remove("pkb-over"),Q.removeAttribute("inert"),H&&(H.hidden=!1,H.removeAttribute("tabindex"),H.classList.remove("pkb-gone","pkb-counting"),N.classList.add("pkb-waiting"),l("count").textContent="",Q.setAttribute("inert",""))}let Se=!1,Ft=()=>{!re||!v.some(Boolean)?Pe():Se=!0};function Vn(){z==="play"||z==="done"||(ot(),Et(!1),vt())}function Yn(){if(z!=="ready")return;z="count",H.classList.add("pkb-counting");let e=l("count"),t=["3","2","1",m.readyGo?.trim()||S.readyGo];t.forEach((a,i)=>{let d=i===t.length-1,o=()=>{e.textContent=a,e.classList.toggle("pkb-go",d),C(e,"pkb-tick"),P.count(d),ke.play(d?"go":"count"),d&&(vt(),Et(!0))};i?pn(o,i*ka):o()})}H?.addEventListener("click",Yn);function Xn(e,t,a,i){let d=Ee(ee[e]);if(!t){mt[e].classList.remove("pkb-hit"),D=0,l("combo").classList.remove("pkb-on"),P.off(),ke.play("off");return}let o=performance.now();D=o-Xt<fa?D+1:1,Xt=o,fe=Math.max(fe,D);let s=new Set(i.flatMap(j=>y[j])).size,F=Math.min(70*s,300)+60,A=ke.play(a,D,i.length,F);Vt=a==="perfect"?A:void 0;let I=Math.min(3,Math.floor(D/3));P.pop(D-1),R||(ee[e].style.setProperty("--pkb-impact",String(I)),C(ee[e],"pkb-squash"),C(mt[e],"pkb-hit"),Un(ee[e])),ae(d.x,d.y,18+I*6,{speed:6+I,g:.2,life:30,size:.6,star:.5}),ve.has(e)||(ve.add(e),Y+=10*D,on(10*D,d.x,d.y-12)),D>=2&&(Ke(m.comboPop(D),d.x,d.y+22,"cmb",90,Rn[(D-2)%Rn.length]),l("cmbN").textContent=m.combo(D),l("combo").classList.add("pkb-on"),C(l("cbar"),"pkb-draining"),R||C(l("cmbN"),"pkb-bump"))}l("cbar").addEventListener("animationend",()=>{l("combo").classList.remove("pkb-on"),D=0});function Wn(e){e.forEach(t=>{let a=Ee(ee[t]);Ke(m.reachPop,a.x,a.y-34,"rch",150)}),J(()=>P.reach(),150)}function Jn(e,t,a){let i=e.length,d=[...new Set(e.flatMap(s=>y[s]))].map(s=>be[s]),o=Math.min(70,300/d.length);d.forEach((s,F)=>J(()=>{nn(s,0);let A=Ee(s);ae(A.x,A.y,14,{speed:5,g:.15,life:30,size:.7,star:.8}),P.note(F+3)},F*o)),J(()=>{l("bT").textContent=i>=3?m.bannerTriple:i===2?m.bannerDouble:m.bannerSingle,l("bS").textContent=i>1?m.bannerMulti(i):m.bannerNth(a),C(l("banner"),"pkb-show"),R||(C(l("flash"),"pkb-go"),C(N,"pkb-punch"));let s=Ee(De);ae(s.x,s.y,i>1?180:110,{speed:i>1?16:13,star:.3}),P.bingo(i),t&&J(()=>on(t,s.x,s.y+105,"big"),350)},d.length*o+60)}function Zn(e){let t=Vt;tt=!0,K.classList.remove("pkb-settled");let a=nt?0:1e3,i=nt||Z==null?0:Nn(h,Z);nt=!0,Y+=a+i,be.forEach((o,s)=>nn(o,V(s)*180/Math.max(1,x-1))),P.perfect(),R||C(l("flash"),"pkb-go"),mn(!1),l("pbody").textContent=Dn(m,h),l("ptime").hidden=Z==null,l("pT").textContent=Ze(Z??0,2),l("sScore").textContent="0",l("sCombo").textContent="\xD70",l("sBingo").textContent="0",J(()=>{tt=!1,C(K,"pkb-show"),l("close").focus({preventScroll:!0}),J(()=>{R||C(N,"pkb-shake"),P.boom(),t?.(Nt),ae(0,ne,90,{angle:-Math.PI/3,spread:.8,speed:22,g:.32,star:.3}),ae(te,ne,90,{angle:-Math.PI*2/3,spread:.8,speed:22,g:.32,star:.3}),Qt(3500),a&&Ke(m.perfectBonus(a),te/2,ne*.16,"big");let o=Math.min(34,Math.max(14,te*.056))*1.3+6;i&&Ke((m.speedBonus??S.speedBonus)(i),te/2,Math.max(o/2+4,ne*.16-o),"big"),Ae(l("sScore"),0,Y,1300,s=>s.toLocaleString(),!0),Ae(l("sCombo"),0,fe,700,s=>"\xD7"+s),Ae(l("sBingo"),0,kn(),700,String),xt()},720),J(()=>Gn(3e3),1500)},520),Dt.forEach(({at:o,beat:s})=>J(()=>{en(te*(.15+Math.random()*.7),ne*(.12+Math.random()*.3)),t?.(s)},o));let d={score:Y,maxCombo:fe,time:Z==null?null:Math.round(Z),speedBonus:i};e.push(()=>n.onPerfect?.(d))}function fn(e){if(clearTimeout(oe),oe=0,!ie.size)return;let t=[...ie].filter(i=>v[i]);ie.clear(),v=v.slice(),t.forEach(i=>{v[i]=!1,de[i].checked=!1,ve.delete(i)}),me.clear();let a=st();a.forEach(i=>me.add(Je(L[i]))),ze=new Set(a),Xe(null,!0),!(!e||!t.length)&&(P.clear(t.length),t.forEach((i,d)=>{let o=ee[i];R||(o.style.setProperty("--pkb-cd",Math.min(d*28,280)+"ms"),o.classList.remove("pkb-squash","pkb-hop"),C(o,"pkb-clr"));let s=Ee(o);ae(s.x,s.y,9,{speed:4.5,g:.06,life:45,size:.75,star:1,colors:Be.slice(1)})}))}function Qn(e){let t=performance.now()+e;oe&&t<=Kt||(clearTimeout(oe),Kt=t,oe=window.setTimeout(()=>{oe=0,q||fn(!0)},e))}let ea=()=>{clearTimeout(oe),oe=0,ie.clear()};function mn(e){let t=e?m.finishTitle?.trim()||S.finishTitle:m.perfectTitle;K.classList.toggle("pkb-fin",e),l("pcard").setAttribute("aria-label",t),l("medal").textContent=e?m.finishStamp?.trim()||S.finishStamp:m.perfectStamp,l("ptitle").textContent=t,l("pTl").textContent=e?m.finishTime?.trim()||S.finishTime:m.statTime?.trim()||S.statTime,l("again").hidden=!e}let kn=()=>E()?ye:X.length,un=()=>l(K.classList.contains("pkb-fin")?"again":"close");function Ye(){ie.size&&fn(!1),Ne++,tt=!1,Ce.forEach(e=>clearTimeout(e)),Ce.clear(),ke.stop(),P.stop(),cancelAnimationFrame(at),_e=Y,l("sc").textContent=Y.toLocaleString()}function St(e=!1){he=[],cancelAnimationFrame(we),we=0,B?.clearRect(0,0,He.width,He.height),N.querySelectorAll(".pkb-float, .pkb-ring").forEach(t=>t.remove()),l("banner").classList.remove("pkb-show"),l("flash").classList.remove("pkb-go"),l("combo").classList.remove("pkb-on"),l("cbar").classList.remove("pkb-draining"),be.forEach(t=>t.classList.remove("pkb-squash","pkb-hop","pkb-clr")),mt.forEach(t=>t.classList.remove("pkb-hit")),N.classList.remove("pkb-punch","pkb-shake","pkb-switching"),ue.classList.remove("pkb-show"),e||K.classList.remove("pkb-show","pkb-settled")}let st=()=>L.flatMap((e,t)=>e.every(a=>v[a])?[t]:[]);function Xe(e,t){let a=[],i=v,d=i.filter(Boolean).length,o=E(),s=d===h&&!o;X=st();let F=X.filter(w=>!ze.has(w));if([...ze].some(w=>!X.includes(w))&&(Ye(),d<h&&K.classList.remove("pkb-show")),o&&(t||(ye+=F.length),X.length)){let w=ie.size;X.forEach(U=>L[U].forEach(xe=>ie.add(xe))),(ie.size>w||!oe)&&Qn(!t&&F.length?ga:jt+200)}let A=new Set(X.flatMap(w=>y[w])),I=new Set;for(let w of L){let U=w.filter(xe=>!i[xe]);U.length===1&&I.add(U[0])}ee.forEach((w,U)=>{w.classList.toggle("pkb-on",i[U]);let xe=i[U]&&(!Gt||ie.has(U));w.classList.toggle("pkb-lock",xe),xe?de[U].setAttribute("aria-readonly","true"):de[U].removeAttribute("aria-readonly"),w.classList.toggle("pkb-line",A.has(f.itemCell[k[U]])),w.classList.toggle("pkb-reach",I.has(U))}),_n?.classList.toggle("pkb-line",A.has(f.center)),N.classList.toggle("pkb-all",s),Ut.classList.toggle("pkb-gold",s),Ut.textContent=s?m.perfectTag:m.tag,l("cnt").textContent=`${d}/${h}`;let j=o?ye:X.length;l("bng").textContent=String(j);let Me=l("bp");if(j>Yt&&(Me.classList.remove("pkb-hot"),Me.offsetWidth),Me.classList.toggle("pkb-hot",j>0),Yt=j,yt(F),e!==null){let w=[...I].some(xe=>!et.has(xe)),U=!t&&s&&!je?"perfect":!t&&F.length?"bingo":!t&&w?"reach":"tap";Xn(e,i[e],U,F)}let At=F.map(w=>Je(L[w])).filter(w=>!me.has(w));At.forEach(w=>me.add(w));let $t=100*At.length*At.length;if(Y+=$t,t)$t&&xt();else if(s&&!je)Zn(a);else if(F.length){Jn(F,$t,j);let w={newLines:F,totalLines:j,score:Y,mode:le};a.push(()=>n.onBingo?.(w))}else if(e!==null&&i[e]){let w=[...I].filter(U=>!et.has(U));w.length&&Wn(w)}ze=new Set(X),et=I,je=s;let Ln=[...I].map(w=>u[w].label);return l("msg").textContent=s?m.statusDone:Ln.length?m.statusReach(Ln):X.length?m.statusLines(X.length,h-d):m.statusStart(h-d),a}let gn=e=>{for(let t of e){if(q)return;t()}},hn=()=>{G&&!E()&&bt(G,JSON.stringify(v))};function xn(e,t,a){z==="idle"&&t!==null&&e[t]&&vt(),!E()&&e.every(Boolean)&&dn(),v=e,de.forEach((d,o)=>d.checked=v[o]);let i=Xe(t,a);return hn(),i}function We(e){ea(),ye=0,Ye(),St(),!E()&&e.every(Boolean)?dn():(z==="play"||z==="done")&&!e.some(Boolean)&&Pe(),v=e,de.forEach((a,i)=>a.checked=v[i]),ve.clear(),me.clear(),v.forEach((a,i)=>a&&ve.add(i));let t=st();t.forEach(a=>me.add(Je(L[a]))),ze=new Set(t),et=new Set,je=!E()&&v.every(Boolean),nt=je,Y=_e=ve.size*10+me.size*100,D=0,fe=0,l("sc").textContent=Y.toLocaleString(),Xe(null,!0),hn()}function Oe(e,t,a={}){let i=E();if(re&&!i){Se=!!a.reset&&Se,de.forEach((o,s)=>o.checked=v[s]),n.onChange?.(e.slice());return}let d=[];a.reset?We(e):d=xn(e,t,!!a.quiet),i||n.onChange?.(v.slice()),gn(d)}function Lt(e){c=e,c.forEach((a,i)=>{k[a]=i,be[f.itemCell[i]]=ee[a]}),L=f.lines.map(a=>a.map(i=>c[i]));let t=document.activeElement;be.forEach((a,i)=>{a.style.setProperty("--pkb-gd",qn(i,x)),Q.appendChild(a)}),t instanceof HTMLElement&&Q.contains(t)&&document.activeElement!==t&&t.focus({preventScroll:!0})}let ta=()=>{!pe||E()||bt(pe,JSON.stringify(c))},Le=[];function yn(e){(E()||!v.every(Boolean))&&Ye();let t=R?null:ee.map(i=>i.getBoundingClientRect());Le.forEach(i=>i.cancel()),Le=[],Lt(e),L.forEach(i=>{i.every(d=>ve.has(d))&&me.add(Je(i))});let a=st();a.forEach(i=>me.add(Je(L[i]))),ze=new Set(a),Xe(null,!0),ta(),!(!t||typeof Element.prototype.animate!="function")&&(ee.forEach((i,d)=>{let o=t[d],s=i.getBoundingClientRect(),F=o.left-s.left,A=o.top-s.top;Math.abs(F)+Math.abs(A)<1||Le.push(i.animate([{transform:`translate(${F}px,${A}px)`},{transform:"none"}],{duration:jt-140,delay:Math.random()*140,easing:"cubic-bezier(.3,1.25,.5,1)",fill:"backwards"}))}),clearTimeout(Fe),Fe=window.setTimeout(()=>{Fe=0,Le=[],q||yt(X)},jt),Qe.innerHTML="")}function vn(){if(E()&&z==="done")return;let e=c.slice();do for(let t=h-1;t>0;t--){let a=Math.floor(Math.random()*(t+1));[e[t],e[a]]=[e[a],e[t]]}while(e.every((t,a)=>t===c[a]));yn(e),P.shuffle(),ke.play("shuffle")}let Tt=()=>{M(c)||yn(T())},wn=e=>v[e]&&(!Gt||ie.has(e));Q.addEventListener("click",e=>{let t=de.indexOf(e.target);t>=0&&wn(t)&&e.preventDefault()}),Q.addEventListener("change",e=>{let t=de.indexOf(e.target);if(t<0)return;if(wn(t)){de[t].checked=!0;return}let a=v.slice();a[t]=!a[t],Oe(a,t)}),r.querySelector('[data-r="shuf"]')?.addEventListener("click",vn);let Mt=()=>{We(p(void 0)),Pe()};l("reset").addEventListener("click",()=>{if(E())return Mt();Tt(),Ft(),Oe(p(void 0),null,{reset:!0})}),l("close").addEventListener("click",()=>K.classList.remove("pkb-show")),l("again").addEventListener("click",()=>{E()&&(Mt(),(H&&!H.hidden?H:Q.querySelector("input"))?.focus({preventScroll:!0}))});function En(){if(q||!E()||z!=="play")return;Ye(),St(),Z=performance.now()-rt,z="done",clearInterval(Ue),$e.classList.replace("pkb-run","pkb-done"),Ve(),wt(),D=0,Q.setAttribute("inert",""),N.classList.add("pkb-over"),mn(!0),l("pbody").textContent="",l("ptime").hidden=!1,l("pT").textContent=Ze(Z,2),l("sScore").textContent="0",l("sCombo").textContent="\xD70",l("sBingo").textContent="0",K.classList.remove("pkb-settled"),C(K,"pkb-show"),un().focus({preventScroll:!0}),P.perfect();let e=ke.play("finish");R||C(l("flash"),"pkb-go"),J(()=>{R||C(N,"pkb-shake"),P.boom(),e?.(Nt),ae(0,ne,80,{angle:-Math.PI/3,spread:.8,speed:21,g:.32,star:.5,colors:Be}),ae(te,ne,80,{angle:-Math.PI*2/3,spread:.8,speed:21,g:.32,star:.5,colors:Be}),Qt(2500),Ae(l("sScore"),0,Y,1300,a=>a.toLocaleString(),!0),Ae(l("sCombo"),0,fe,700,a=>"\xD7"+a),Ae(l("sBingo"),0,ye,700,String)},720),[1250,1700,2200].forEach((a,i)=>J(()=>{en(te*(.15+Math.random()*.7),ne*(.12+Math.random()*.3)),e?.(Dt[i*2].beat)},a));let t={score:Y,maxCombo:fe,lines:ye,time:Math.round(Z)};n.onFinish?.(t)}if(cn.addEventListener("click",En),K.addEventListener("click",e=>{e.target===K&&K.classList.remove("pkb-show")}),ft){let e=!1,t=()=>{!E()&&v.every(Boolean)?Oe(p(void 0),null,{reset:!0}):K.classList.remove("pkb-show")},a=async i=>{if(!e){e=!0;try{t(),Vn();let d=Ne;for(let o of i){if(await Hn(o.delay),q||d!==Ne)return;let s=v.slice();s[o.i]=!0,Oe(s,o.i,{quiet:o.quiet})}}finally{e=!1}}};l("dB").addEventListener("click",()=>{if(E()&&z==="done")return;let i=()=>L.map(o=>o.filter(s=>!v[s])).filter(o=>o.length).sort((o,s)=>o.length-s.length)[0]??[],d=!E()&&v.every(Boolean)?[...L[0]]:i();a(d.map(o=>({i:o,delay:320})))}),l("dP").addEventListener("click",()=>{if(E())return;let i=u.map((o,s)=>s),d=v.every(Boolean)?i:i.filter(o=>!v[o]);a(d.map((o,s)=>s<d.length-1?{i:o,delay:170,quiet:!0}:{i:o,delay:450}))}),l("dR").addEventListener("click",()=>{e||E()||(Tt(),Ft(),Oe(W(),null,{reset:!0}))})}let Re=r.querySelector('[data-r="mode"]'),Bt=Re?Array.from(Re.querySelectorAll("button[data-m]")):[],Fn=()=>{jn.classList.toggle("pkb-inf",E()),Bt.forEach(e=>{let t=e.dataset.m===le;e.setAttribute("aria-checked",String(t)),e.tabIndex=t?0:-1})};function na(){let e=E(),t=e?m.infiniteTitle?.trim()||S.infiniteTitle:m.normalTitle?.trim()||S.normalTitle,a=e?m.infiniteSub?.trim()||S.infiniteSub:m.normalSub?.trim()||S.normalSub,i=e&&!R?Array.from({length:18},(o,s)=>{let F=(5+Math.random()*90).toFixed(1),A=(6+Math.random()*88).toFixed(1),I=(.45+Math.random()*.95).toFixed(2),j=Math.round(100+Math.random()*950);return`<i style="--x:${F}%;--y:${A}%;--s:${I};--t:${j}ms;--c:${Be[s%Be.length]}"></i>`}).join(""):"";ue.className="pkb-mfx "+(e?"pkb-mfx-inf":"pkb-mfx-n"),ue.innerHTML=(e?'<span class="pkb-mfx-glow"></span>':"")+i+`<span class="pkb-mfx-in"><b class="pkb-mfx-sym">${e?"\u221E":g(m.stamp)}</b><b class="pkb-mfx-t">${g(t)}</b><span class="pkb-mfx-s">${g(a)}</span></span>`,C(ue,"pkb-show"),N.classList.add("pkb-switching"),Re&&!R&&C(Re,"pkb-bump"),P.mode(e),ke.play(e?"infinite":"normal");let d=Bt.find(o=>o.dataset.m===le);if(d){let o=Ee(d);ae(o.x,o.y,e?46:24,{speed:e?7:5,g:.1,life:55,size:.8,star:e?.9:.3,colors:e?Be:void 0})}J(()=>{let o=Ee(De);e?ae(o.x,o.y,90,{speed:12,g:.07,life:90,star:.75,colors:Be}):(R||C(N,"pkb-punch"),ae(o.x,o.y,70,{speed:11,star:.2}))},e?260:430)}ue.addEventListener("animationend",e=>{e.target===ue&&(ue.classList.remove("pkb-show"),N.classList.remove("pkb-switching"),ue.innerHTML="")});function Ct(e){if(q||e===le||e!=="normal"&&e!=="infinite")return;let t=ce;e==="infinite"?ce={checked:v.slice(),order:c.slice()}:ce=null,le=e,Se=!1,t&&t.order.some((a,i)=>a!==c[i])&&(Le.forEach(a=>a.cancel()),Le=[],clearTimeout(Fe),Fe=0,Lt(t.order)),Fn(),Pe(),We(t?t.checked:p(void 0)),na(),n.onModeChange?.(le)}Re?.addEventListener("click",e=>{let t=e.target.closest("button[data-m]");t&&Ct(t.dataset.m)}),Re?.addEventListener("keydown",e=>{["ArrowLeft","ArrowRight","ArrowUp","ArrowDown"].includes(e.key)&&(e.preventDefault(),Ct(E()?"normal":"infinite"),Bt.find(t=>t.dataset.m===le)?.focus())});let Ie=null;if(pe)try{let e=JSON.parse(Ht(pe)??"null");b(e)&&(Ie=e)}catch{}!Ie&&b(n.defaultOrder)&&(Ie=n.defaultOrder.slice()),Ie&&!M(Ie)&&Lt(Ie);let Te=null;if(G)try{let e=JSON.parse(Ht(G)??"null");Array.isArray(e)&&(Te=p(e))}catch{}!Te&&n.defaultChecked&&(Te=p(n.defaultChecked)),!Te&&ft&&(Te=W()),Zt(),E()&&(ce={checked:Te??p(void 0),order:c.slice()}),Fn(),We(E()?p(void 0):Te??p(void 0)),z!=="done"&&Pe();let zt=typeof ResizeObserver=="function"?new ResizeObserver(()=>{Zt(),yt()}):null;zt?.observe(N),zt?.observe(De);let Sn=()=>{if(!document.hidden){ut&&K.classList.contains("pkb-show")&&un().focus({preventScroll:!0}),ut=!1;return}let e=tt||K.classList.contains("pkb-show");ut=e,Ye(),St(e),e&&(l("sScore").textContent=Y.toLocaleString(),l("sCombo").textContent="\xD7"+fe,l("sBingo").textContent=String(kn()),K.classList.add("pkb-show","pkb-settled")),D=0};return document.addEventListener("visibilitychange",Sn),{setChecked(e,t={}){if(q)return;let a=p(e);if(ce){ce.checked=a,Se=!1,G&&bt(G,JSON.stringify(a));return}Se&&!a.some(Boolean)&&Pe(),Se=!1;let i=a.flatMap((d,o)=>d!==v[o]?[o]:[]);if(i.length){if(!t.animate||i.length!==1){We(a);return}gn(xn(a,i[0],!1))}},reset(){if(!q){if(E())return Mt();Tt(),Ft(),Oe(p(void 0),null,{reset:!0})}},shuffle(){q||vn()},setMode(e){Ct(e)},finish(){En()},refresh(){q||Xe(null,!0)},getState(){return{checked:v.slice(),lines:X.slice(),score:Y,maxCombo:fe,complete:!E()&&v.every(Boolean),mode:le,cleared:ye,finished:E()&&z==="done",packing:ce&&{checked:ce.checked.slice(),order:ce.order.slice()},size:x,free:f.free,order:c.slice(),time:Math.round(ln())}},destroy(){q||(q=!0,ot(),Ce.forEach(e=>clearTimeout(e)),Ce.clear(),clearTimeout(Fe),clearTimeout(oe),Le.forEach(e=>e.cancel()),cancelAnimationFrame(we),cancelAnimationFrame(at),zt?.disconnect(),document.removeEventListener("visibilitychange",Sn),ke.stop(),P.close(),r.innerHTML="")}}}return pa(va);})();